From dd60caa3f51c5117c0193f8f3272e1c7f5230eb7 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 15 Jun 2021 21:50:13 -0700 Subject: . --- html/101screen.subx.html | 75 +- html/103grapheme.subx.html | 367 +- html/104test.subx.html | 27 +- html/108write.subx.html | 4 +- html/315stack-debug.subx.html | 12 +- html/317abort.subx.html | 10 +- html/400.mu.html | 217 +- html/403unicode.mu.html | 49 +- html/408float.mu.html | 5 +- html/411string.mu.html | 50 +- html/412render-float-decimal.mu.html | 206 +- html/500fake-screen.mu.html | 1137 +- html/501draw-text.mu.html | 334 +- html/502test.mu.html | 7 +- html/503manhattan-line.mu.html | 6 +- html/504test-screen.mu.html | 656 +- html/505colors.mu.html | 117 +- html/506math.mu.html | 20 +- html/507line.mu.html | 32 +- html/508circle.mu.html | 19 +- html/509bezier.mu.html | 32 +- html/boot.subx.html | 1248 +- html/colors.mu.html | 73 +- html/ex10.mu.html | 16 +- html/ex11.mu.html | 156 +- html/ex2.mu.html | 11 +- html/ex3.mu.html | 9 +- html/ex4.mu.html | 2 +- html/ex5.mu.html | 3 +- html/ex6.mu.html | 6 +- html/ex7.mu.html | 11 +- html/ex8.mu.html | 3 +- html/ex9.mu.html | 21 +- html/hest-life.mu.html | 2015 +- html/life.mu.html | 70 +- html/linux/mu.subx.html | 67676 +++++++++++++++++---------------- html/mandelbrot-fixed.mu.html | 146 +- html/mandelbrot-silhouette.mu.html | 217 + html/mandelbrot.mu.html | 46 +- html/mu-init.subx.html | 21 +- html/rpn.mu.html | 95 +- html/shell/cell.mu.html | 14 +- html/shell/environment.mu.html | 1459 +- html/shell/evaluate.mu.html | 3397 +- html/shell/gap-buffer.mu.html | 2116 +- html/shell/global.mu.html | 1112 +- html/shell/grapheme-stack.mu.html | 52 +- html/shell/macroexpand.mu.html | 68 +- html/shell/main.mu.html | 14 +- html/shell/parse.mu.html | 42 +- html/shell/primitives.mu.html | 3412 +- html/shell/print.mu.html | 6 +- html/shell/read.mu.html | 2 +- html/shell/sandbox.mu.html | 1969 +- html/shell/tokenize.mu.html | 2113 +- html/shell/trace.mu.html | 426 +- 56 files changed, 46598 insertions(+), 44831 deletions(-) create mode 100644 html/mandelbrot-silhouette.mu.html diff --git a/html/101screen.subx.html b/html/101screen.subx.html index 27e5514b..3de3f02a 100644 --- a/html/101screen.subx.html +++ b/html/101screen.subx.html @@ -66,37 +66,50 @@ if ('onhashchange' in window) { 9 # . prologue 10 55/push-ebp 11 89/<- %ebp 4/r32/esp -12 # . save registers -13 50/push-eax -14 51/push-ecx -15 # bounds checks -16 8b/-> *(ebp+8) 0/r32/eax -17 3d/compare-eax-and 0/imm32 -18 7c/jump-if-< $pixel-on-real-screen:end/disp8 -19 3d/compare-eax-and 0x400/imm32/screen-width=1024 -20 7d/jump-if->= $pixel-on-real-screen:end/disp8 -21 8b/-> *(ebp+0xc) 0/r32/eax -22 3d/compare-eax-and 0/imm32 -23 7c/jump-if-< $pixel-on-real-screen:end/disp8 -24 3d/compare-eax-and 0x300/imm32/screen-height=768 -25 7d/jump-if->= $pixel-on-real-screen:end/disp8 -26 # eax = y*1024 + x -27 8b/-> *(ebp+0xc) 0/r32/eax -28 c1/shift 4/subop/left %eax 0xa/imm8 -29 03/add-> *(ebp+8) 0/r32/eax -30 # eax += location of frame buffer -31 03/add-> *Video-memory-addr 0/r32/eax -32 # *eax = color -33 8b/-> *(ebp+0x10) 1/r32/ecx -34 88/byte<- *eax 1/r32/CL -35 $pixel-on-real-screen:end: -36 # . restore registers -37 59/pop-to-ecx -38 58/pop-to-eax -39 # . epilogue -40 89/<- %esp 5/r32/ebp -41 5d/pop-to-ebp -42 c3/return +12 # +13 (pixel-on-screen-buffer *Video-memory-addr *(ebp+8) *(ebp+0xc) *(ebp+0x10) 0x400 0x300) +14 $pixel-on-real-screen:end: +15 # . epilogue +16 89/<- %esp 5/r32/ebp +17 5d/pop-to-ebp +18 c3/return +19 +20 # 'buffer' here is not a valid Mu type: a naked address without a length. +21 pixel-on-screen-buffer: # buffer: (addr byte), x: int, y: int, color: int, width: int, height: int +22 # . prologue +23 55/push-ebp +24 89/<- %ebp 4/r32/esp +25 # . save registers +26 50/push-eax +27 51/push-ecx +28 # bounds checks +29 8b/-> *(ebp+0xc) 0/r32/eax # foo +30 3d/compare-eax-and 0/imm32 +31 7c/jump-if-< $pixel-on-screen-buffer:end/disp8 +32 3b/compare 0/r32/eax *(ebp+0x18) +33 7d/jump-if->= $pixel-on-screen-buffer:end/disp8 +34 8b/-> *(ebp+0x10) 0/r32/eax +35 3d/compare-eax-and 0/imm32 +36 7c/jump-if-< $pixel-on-screen-buffer:end/disp8 +37 3b/compare 0/r32/eax *(ebp+0x1c) +38 7d/jump-if->= $pixel-on-screen-buffer:end/disp8 +39 # eax = y*width + x +40 8b/-> *(ebp+0x10) 0/r32/eax +41 0f af/multiply-> *(ebp+0x18) 0/r32/eax +42 03/add-> *(ebp+0xc) 0/r32/eax +43 # eax += location of frame buffer +44 03/add-> *(ebp+8) 0/r32/eax +45 # *eax = color +46 8b/-> *(ebp+0x14) 1/r32/ecx +47 88/byte<- *eax 1/r32/CL +48 $pixel-on-screen-buffer:end: +49 # . restore registers +50 59/pop-to-ecx +51 58/pop-to-eax +52 # . epilogue +53 89/<- %esp 5/r32/ebp +54 5d/pop-to-ebp +55 c3/return diff --git a/html/103grapheme.subx.html b/html/103grapheme.subx.html index 42c4f598..549c5064 100644 --- a/html/103grapheme.subx.html +++ b/html/103grapheme.subx.html @@ -75,159 +75,220 @@ if ('onhashchange' in window) { 18 # . prologue 19 55/push-ebp 20 89/<- %ebp 4/r32/esp - 21 # . save registers - 22 50/push-eax - 23 51/push-ecx - 24 52/push-edx - 25 53/push-ebx - 26 56/push-esi - 27 # var letter-bitmap/esi = font[g] - 28 8b/-> *(ebp+8) 6/r32/esi - 29 c1 4/subop/shift-left %esi 4/imm8 - 30 81 0/subop/add %esi Font/imm32 - 31 # if (letter-bitmap >= 0x9400) return # characters beyond ASCII currently not supported - 32 81 7/subop/compare %esi 0x9400/imm32 - 33 7d/jump-if->= $draw-grapheme-on-real-screen:end/disp8 - 34 # var ycurr/edx: int = y*16 - 35 8b/-> *(ebp+0x10) 2/r32/edx - 36 c1 4/subop/shift-left %edx 4/imm8 - 37 # var ymax/ebx: int = ycurr + 16 - 38 8b/-> *(ebp+0x10) 3/r32/ebx - 39 c1 4/subop/shift-left %ebx 4/imm8 - 40 81 0/subop/add %ebx 0x10/imm32 - 41 { - 42 # if (ycurr >= ymax) break - 43 39/compare %edx 3/r32/ebx - 44 7d/jump-if->= break/disp8 - 45 # var xcurr/eax: int = x*8 + 7 - 46 8b/-> *(ebp+0xc) 0/r32/eax # font-width - 1 - 47 c1 4/subop/shift-left %eax 3/imm8 - 48 05/add-to-eax 7/imm32 - 49 # var xmin/ecx: int = x*8 - 50 8b/-> *(ebp+0xc) 1/r32/ecx - 51 c1 4/subop/shift-left %ecx 3/imm8 - 52 # var row-bitmap/ebx: int = *letter-bitmap - 53 53/push-ebx - 54 8b/-> *esi 3/r32/ebx - 55 { - 56 # if (xcurr < xmin) break - 57 39/compare %eax 1/r32/ecx - 58 7c/jump-if-< break/disp8 - 59 # shift LSB from row-bitmap into carry flag (CF) - 60 c1 5/subop/shift-right-logical %ebx 1/imm8 - 61 # if LSB, draw a pixel in the given color - 62 { - 63 73/jump-if-not-CF break/disp8 - 64 (pixel-on-real-screen %eax %edx *(ebp+0x14)) - 65 eb/jump $draw-grapheme-on-real-screen:continue/disp8 - 66 } - 67 # otherwise use the background color - 68 (pixel-on-real-screen %eax %edx *(ebp+0x18)) - 69 $draw-grapheme-on-real-screen:continue: - 70 # --x - 71 48/decrement-eax - 72 # - 73 eb/jump loop/disp8 - 74 } - 75 # reclaim row-bitmap - 76 5b/pop-to-ebx - 77 # ++y - 78 42/increment-edx - 79 # next bitmap row - 80 46/increment-esi - 81 # - 82 eb/jump loop/disp8 - 83 } - 84 $draw-grapheme-on-real-screen:end: - 85 # . restore registers - 86 5e/pop-to-esi - 87 5b/pop-to-ebx - 88 5a/pop-to-edx - 89 59/pop-to-ecx - 90 58/pop-to-eax - 91 # . epilogue - 92 89/<- %esp 5/r32/ebp - 93 5d/pop-to-ebp - 94 c3/return - 95 - 96 cursor-position-on-real-screen: # -> _/eax: int, _/ecx: int - 97 # . prologue - 98 55/push-ebp - 99 89/<- %ebp 4/r32/esp -100 # TODO: support fake screen; we currently assume 'screen' is always 0 (real) -101 8b/-> *Real-screen-cursor-x 0/r32/eax -102 8b/-> *Real-screen-cursor-y 1/r32/ecx -103 $cursor-position-on-real-screen:end: -104 # . epilogue -105 89/<- %esp 5/r32/ebp -106 5d/pop-to-ebp -107 c3/return -108 -109 set-cursor-position-on-real-screen: # x: int, y: int -110 # . prologue -111 55/push-ebp -112 89/<- %ebp 4/r32/esp -113 # . save registers -114 50/push-eax -115 # -116 8b/-> *(ebp+8) 0/r32/eax -117 89/<- *Real-screen-cursor-x 0/r32/eax -118 8b/-> *(ebp+0xc) 0/r32/eax -119 89/<- *Real-screen-cursor-y 0/r32/eax -120 $set-cursor-position-on-real-screen:end: -121 # . restore registers -122 58/pop-to-eax -123 # . epilogue -124 89/<- %esp 5/r32/ebp -125 5d/pop-to-ebp -126 c3/return -127 -128 # Not a real `show-cursor` primitive: -129 # - does not clear previous location cursor was shown at. -130 # - does not preserve what was at the cursor. Caller is responsible for -131 # tracking what was on the screen at this position before and passing it -132 # in again. -133 # - does not stop showing the cursor at this location when the cursor moves -134 draw-cursor-on-real-screen: # g: grapheme -135 # . prologue -136 55/push-ebp -137 89/<- %ebp 4/r32/esp -138 # . save registers -139 50/push-eax -140 51/push-ecx -141 # -142 (cursor-position-on-real-screen) # => eax, ecx -143 (draw-grapheme-on-real-screen *(ebp+8) %eax %ecx 0 7) -144 $draw-cursor-on-real-screen:end: -145 # . restore registers -146 59/pop-to-ecx -147 58/pop-to-eax -148 # . epilogue -149 89/<- %esp 5/r32/ebp -150 5d/pop-to-ebp -151 c3/return -152 -153 == data -154 -155 # The cursor is where certain Mu functions (usually of the form -156 # 'draw*cursor*') print to by default. -157 # -158 # We don't bother displaying the cursor when drawing. It only becomes visible -159 # on draw-cursor, which is quite rickety (see above) -160 # -161 # It's up to applications to manage cursor display: -162 # - clean up where it used to be -163 # - display the cursor before waiting for a key -164 # - ensure its location appropriately suggests the effect keystrokes will have -165 # - ensure its contents (and colors) appropriately reflect the state of the -166 # screen -167 # -168 # There's no blinking, etc. We aren't using any hardware-supported text mode -169 # here. -170 Real-screen-cursor-x: -171 0/imm32 -172 Real-screen-cursor-y: -173 0/imm32 + 21 # + 22 (draw-grapheme-on-screen-buffer *Video-memory-addr *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) 0x80 0x30) + 23 $draw-grapheme-on-real-screen:end: + 24 # . epilogue + 25 89/<- %esp 5/r32/ebp + 26 5d/pop-to-ebp + 27 c3/return + 28 + 29 draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int + 30 # . prologue + 31 55/push-ebp + 32 89/<- %ebp 4/r32/esp + 33 # . save registers + 34 50/push-eax + 35 51/push-ecx + 36 52/push-edx + 37 # if screen-width*screen-height > len(screen-data) abort + 38 { + 39 # ecx = len(screen-data) + 40 8b/-> *(ebp+8) 1/r32/ecx + 41 8b/-> *ecx 1/r32/ecx + 42 # eax = screen-width*screen-height + 43 ba/copy-to-edx 0/imm32 + 44 8b/-> *(ebp+0x20) 0/r32/eax + 45 f7 4/subop/multiply-into-eax *(ebp+0x24) + 46 81 7/subop/compare %edx 0/imm32 + 47 0f 85/jump-if-!= $draw-grapheme-on-screen-array:overflow/disp32 + 48 # if (eax > ecx) abort + 49 39/compare %eax 1/r32/ecx + 50 0f 8f/jump-if-> $draw-grapheme-on-screen-array:abort/disp32 + 51 } + 52 # eax = screen-data+4 (skip length) + 53 8b/-> *(ebp+8) 0/r32/eax + 54 05/add-to-eax 4/imm32 + 55 # + 56 (draw-grapheme-on-screen-buffer %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) + 57 $draw-grapheme-on-screen-array:end: + 58 # . restore registers + 59 5a/pop-to-edx + 60 59/pop-to-ecx + 61 58/pop-to-eax + 62 # . epilogue + 63 89/<- %esp 5/r32/ebp + 64 5d/pop-to-ebp + 65 c3/return + 66 + 67 $draw-grapheme-on-screen-array:overflow: + 68 (abort "draw-grapheme-on-screen-array: screen dimensions too large") + 69 + 70 $draw-grapheme-on-screen-array:abort: + 71 (abort "draw-grapheme-on-screen-array: coordinates are off the screen. Are the screen dimensions correct?") + 72 + 73 # 'buffer' here is not a valid Mu type: a naked address without a length. + 74 draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int + 75 # . prologue + 76 55/push-ebp + 77 89/<- %ebp 4/r32/esp + 78 # . save registers + 79 50/push-eax + 80 51/push-ecx + 81 52/push-edx + 82 53/push-ebx + 83 56/push-esi + 84 # switch screen-width and screen-height from grapheme to pixel units + 85 c1 4/subop/shift-left *(ebp+20) 3/imm8/log2-font-width + 86 c1 4/subop/shift-left *(ebp+24) 4/imm8/log2-font-height + 87 # esi = g + 88 8b/-> *(ebp+0xc) 6/r32/esi + 89 # if (g >= 128) return # characters beyond ASCII currently not supported + 90 81 7/subop/compare %esi 0x80/imm32 + 91 0f 8d/jump-if->= $draw-grapheme-on-screen-buffer:end/disp32 + 92 # var letter-bitmap/esi = font[g] + 93 c1 4/subop/shift-left %esi 4/imm8 + 94 81 0/subop/add %esi Font/imm32 + 95 # var ycurr/edx: int = y*16 + 96 8b/-> *(ebp+0x14) 2/r32/edx + 97 c1 4/subop/shift-left %edx 4/imm8 + 98 # var ymax/ebx: int = ycurr + 16 + 99 8b/-> *(ebp+0x14) 3/r32/ebx +100 c1 4/subop/shift-left %ebx 4/imm8 +101 81 0/subop/add %ebx 0x10/imm32 +102 { +103 # if (ycurr >= ymax) break +104 39/compare %edx 3/r32/ebx +105 0f 8d/jump-if->= break/disp32 +106 # var xcurr/eax: int = x*8 + 7 +107 8b/-> *(ebp+0x10) 0/r32/eax # font-width - 1 +108 c1 4/subop/shift-left %eax 3/imm8 +109 05/add-to-eax 7/imm32 +110 # var xmin/ecx: int = x*8 +111 8b/-> *(ebp+0x10) 1/r32/ecx +112 c1 4/subop/shift-left %ecx 3/imm8 +113 # var row-bitmap/ebx: int = *letter-bitmap +114 53/push-ebx +115 8b/-> *esi 3/r32/ebx +116 { +117 # if (xcurr < xmin) break +118 39/compare %eax 1/r32/ecx +119 7c/jump-if-< break/disp8 +120 # shift LSB from row-bitmap into carry flag (CF) +121 c1 5/subop/shift-right-logical %ebx 1/imm8 +122 # if LSB, draw a pixel in the given color +123 { +124 73/jump-if-not-CF break/disp8 +125 (pixel-on-screen-buffer *(ebp+8) %eax %edx *(ebp+0x18) *(ebp+0x20) *(ebp+0x24)) +126 eb/jump $draw-grapheme-on-screen-buffer:continue/disp8 +127 } +128 # otherwise use the background color +129 (pixel-on-screen-buffer *(ebp+8) %eax %edx *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) +130 $draw-grapheme-on-screen-buffer:continue: +131 # --x +132 48/decrement-eax +133 # +134 eb/jump loop/disp8 +135 } +136 # reclaim row-bitmap +137 5b/pop-to-ebx +138 # ++y +139 42/increment-edx +140 # next bitmap row +141 46/increment-esi +142 # +143 e9/jump loop/disp32 +144 } +145 $draw-grapheme-on-screen-buffer:end: +146 # . restore registers +147 5e/pop-to-esi +148 5b/pop-to-ebx +149 5a/pop-to-edx +150 59/pop-to-ecx +151 58/pop-to-eax +152 # . epilogue +153 89/<- %esp 5/r32/ebp +154 5d/pop-to-ebp +155 c3/return +156 +157 cursor-position-on-real-screen: # -> _/eax: int, _/ecx: int +158 # . prologue +159 55/push-ebp +160 89/<- %ebp 4/r32/esp +161 # TODO: support fake screen; we currently assume 'screen' is always 0 (real) +162 8b/-> *Real-screen-cursor-x 0/r32/eax +163 8b/-> *Real-screen-cursor-y 1/r32/ecx +164 $cursor-position-on-real-screen:end: +165 # . epilogue +166 89/<- %esp 5/r32/ebp +167 5d/pop-to-ebp +168 c3/return +169 +170 set-cursor-position-on-real-screen: # x: int, y: int +171 # . prologue +172 55/push-ebp +173 89/<- %ebp 4/r32/esp +174 # . save registers +175 50/push-eax +176 # +177 8b/-> *(ebp+8) 0/r32/eax +178 89/<- *Real-screen-cursor-x 0/r32/eax +179 8b/-> *(ebp+0xc) 0/r32/eax +180 89/<- *Real-screen-cursor-y 0/r32/eax +181 $set-cursor-position-on-real-screen:end: +182 # . restore registers +183 58/pop-to-eax +184 # . epilogue +185 89/<- %esp 5/r32/ebp +186 5d/pop-to-ebp +187 c3/return +188 +189 # Not a real `show-cursor` primitive: +190 # - does not clear previous location cursor was shown at. +191 # - does not preserve what was at the cursor. Caller is responsible for +192 # tracking what was on the screen at this position before and passing it +193 # in again. +194 # - does not stop showing the cursor at this location when the cursor moves +195 draw-cursor-on-real-screen: # g: grapheme +196 # . prologue +197 55/push-ebp +198 89/<- %ebp 4/r32/esp +199 # . save registers +200 50/push-eax +201 51/push-ecx +202 # +203 (cursor-position-on-real-screen) # => eax, ecx +204 (draw-grapheme-on-real-screen *(ebp+8) %eax %ecx 0 7) +205 $draw-cursor-on-real-screen:end: +206 # . restore registers +207 59/pop-to-ecx +208 58/pop-to-eax +209 # . epilogue +210 89/<- %esp 5/r32/ebp +211 5d/pop-to-ebp +212 c3/return +213 +214 == data +215 +216 # The cursor is where certain Mu functions (usually of the form +217 # 'draw*cursor*') print to by default. +218 # +219 # We don't bother displaying the cursor when drawing. It only becomes visible +220 # on draw-cursor, which is quite rickety (see above) +221 # +222 # It's up to applications to manage cursor display: +223 # - clean up where it used to be +224 # - display the cursor before waiting for a key +225 # - ensure its location appropriately suggests the effect keystrokes will have +226 # - ensure its contents (and colors) appropriately reflect the state of the +227 # screen +228 # +229 # There's no blinking, etc. We aren't using any hardware-supported text mode +230 # here. +231 Real-screen-cursor-x: +232 0/imm32 +233 Real-screen-cursor-y: +234 0/imm32 diff --git a/html/104test.subx.html b/html/104test.subx.html index f0391984..8c145881 100644 --- a/html/104test.subx.html +++ b/html/104test.subx.html @@ -64,7 +64,7 @@ if ('onhashchange' in window) { 7 55/push-ebp 8 89/<- %ebp 4/r32/esp 9 # -10 ff 0/subop/increment *Num-test-failures +10 ff 0/subop/increment *Num-test-failures 11 $count-test-failure:end: 12 # . epilogue 13 89/<- %esp 5/r32/ebp @@ -76,17 +76,32 @@ if ('onhashchange' in window) { 19 55/push-ebp 20 89/<- %ebp 4/r32/esp 21 # -22 8b/-> *Num-test-failures 0/r32/eax +22 8b/-> *Num-test-failures 0/r32/eax 23 $num-test-failures:end: 24 # . epilogue 25 89/<- %esp 5/r32/ebp 26 5d/pop-to-ebp 27 c3/return 28 -29 == data -30 -31 Num-test-failures: -32 0/imm32 +29 running-tests?: # -> _/eax: int +30 # . prologue +31 55/push-ebp +32 89/<- %ebp 4/r32/esp +33 # +34 8b/-> *Running-tests? 0/r32/eax +35 $running-tests?:end: +36 # . epilogue +37 89/<- %esp 5/r32/ebp +38 5d/pop-to-ebp +39 c3/return +40 +41 == data +42 +43 Num-test-failures: +44 0/imm32 +45 +46 Running-tests?: +47 1/imm32/true diff --git a/html/108write.subx.html b/html/108write.subx.html index 763f35bf..b558cf81 100644 --- a/html/108write.subx.html +++ b/html/108write.subx.html @@ -201,7 +201,7 @@ if ('onhashchange' in window) { 141 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 142 # if (s == 0) return 143 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 0/imm32 # compare *(ebp+12) -144 74/jump-if-= $write:end/disp8 +144 74/jump-if-= $try-write:end/disp8 145 # . save registers 146 51/push-ecx 147 # if (f->size - f->write < s->size) return @@ -262,7 +262,7 @@ if ('onhashchange' in window) { 202 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax 203 # . restore registers 204 59/pop-to-ecx -205 $space-remaining-in-stream:end: +205 $stream-size:end: 206 # . epilogue 207 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 208 5d/pop-to-ebp diff --git a/html/315stack-debug.subx.html b/html/315stack-debug.subx.html index edb1b99e..641cdf49 100644 --- a/html/315stack-debug.subx.html +++ b/html/315stack-debug.subx.html @@ -92,12 +92,12 @@ if ('onhashchange' in window) { 34 # 35 89/<- %edx 4/r32/esp 36 # save old cursor position - 37 (cursor-position 0) # => eax, ecx + 37 (cursor-position 0) # => eax, ecx 38 # print at top-right - 39 (set-cursor-position 0 0x70 0) + 39 (set-cursor-position 0 0x70 0) 40 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 %edx 0xf 0xc) 41 # restore cursor position - 42 (set-cursor-position %eax %ecx) + 42 (set-cursor-position %eax %ecx) 43 $show-stack-state:end: 44 # . restore registers 45 5a/pop-to-edx @@ -124,11 +124,11 @@ if ('onhashchange' in window) { 66 74/jump-if-= break/disp8 67 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+8) *(ebp+0xc) *(ebp+0x10)) 68 # clear the screen and continue if we got too close to the bottom - 69 (cursor-position 0) # => eax, ecx + 69 (cursor-position 0) # => eax, ecx 70 81 7/subop/compare %ecx 0x28/imm32 71 75/jump-if-!= break/disp8 - 72 (clear-screen 0) - 73 (set-cursor-position 0 0 0) + 72 (clear-screen 0) + 73 (set-cursor-position 0 0 0) 74 } 75 $debug-print:end: 76 # . restore registers diff --git a/html/317abort.subx.html b/html/317abort.subx.html index ddc1b979..b5c936f4 100644 --- a/html/317abort.subx.html +++ b/html/317abort.subx.html @@ -65,7 +65,7 @@ if ('onhashchange' in window) { 7 55/push-ebp 8 89/<- %ebp 4/r32/esp 9 # - 10 (set-cursor-position-on-real-screen 0 0) + 10 (set-cursor-position-on-real-screen 0 0) 11 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+8) 0xf 0xc) # 0/real-screen, 0xf/fg=white, 0xc/bg=red 12 (dump-call-stack) 13 # crash @@ -140,10 +140,10 @@ if ('onhashchange' in window) { 82 c7 0/subop/copy *(ecx+4) 0/imm32 # read index 83 c7 0/subop/copy *(ecx+8) 0x01000000/imm32 # stream capacity = 16MB 84 # load 0x400 sectors starting from sector 10080 = 0x2760 - 85 (load-sectors Primary-bus-primary-drive 0x2760 0x100 %ecx) - 86 (load-sectors Primary-bus-primary-drive 0x2860 0x100 %ecx) - 87 (load-sectors Primary-bus-primary-drive 0x2960 0x100 %ecx) - 88 (load-sectors Primary-bus-primary-drive 0x2a60 0x100 %ecx) + 85 (load-sectors Primary-bus-primary-drive 0x2760 0x100 %ecx) + 86 (load-sectors Primary-bus-primary-drive 0x2860 0x100 %ecx) + 87 (load-sectors Primary-bus-primary-drive 0x2960 0x100 %ecx) + 88 (load-sectors Primary-bus-primary-drive 0x2a60 0x100 %ecx) 89 # - parse pointers to portions of this stream into labels 90 # var curr/ecx: (addr byte) = s->data 91 81 0/subop/add %ecx 0xc/imm32 diff --git a/html/400.mu.html b/html/400.mu.html index e071ade5..5208d50d 100644 --- a/html/400.mu.html +++ b/html/400.mu.html @@ -16,7 +16,10 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } .LineNr { } -.Constant { color: #008787; } +.muRegEdx { color: #878700; } +.muRegEbx { color: #8787af; } +.muRegEax { color: #875f00; } +.muRegEcx { color: #af875f; } .muComment { color: #005faf; } --> @@ -56,111 +59,113 @@ if ('onhashchange' in window) { 1 # screen 2 sig pixel-on-real-screen x: int, y: int, color: int 3 sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int, background-color: int - 4 sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int - 5 sig set-cursor-position-on-real-screen x: int, y: int - 6 sig draw-cursor-on-real-screen g: grapheme - 7 sig color-rgb color: int -> _/ecx: int, _/edx: int, _/ebx: int - 8 - 9 # keyboard - 10 sig read-key kbd: (addr keyboard) -> _/eax: byte - 11 - 12 # disk - 13 sig load-sectors disk: (addr disk), lba: int, n: int, out: (addr stream byte) - 14 sig store-sectors disk: (addr disk), lba: int, n: int, out: (addr stream byte) - 15 - 16 # mouse - 17 sig read-mouse-event -> _/eax: int, _/ecx: int - 18 - 19 # tests - 20 sig count-test-failure - 21 sig num-test-failures -> _/eax: int - 22 - 23 sig string-equal? s: (addr array byte), benchmark: (addr array byte) -> _/eax: boolean - 24 sig string-starts-with? s: (addr array byte), benchmark: (addr array byte) -> _/eax: boolean - 25 sig check-strings-equal s: (addr array byte), expected: (addr array byte), msg: (addr array byte) - 26 - 27 # debugging - 28 sig check-stack - 29 sig show-stack-state - 30 sig debug-print x: (addr array byte), fg: int, bg: int - 31 sig debug-print? -> _/eax: boolean - 32 sig turn-on-debug-print - 33 sig turn-off-debug-print - 34 sig abort e: (addr array byte) - 35 sig dump-call-stack - 36 - 37 sig count-event - 38 sig count-of-events -> _/eax: int - 39 - 40 # streams - 41 sig clear-stream f: (addr stream _) - 42 sig rewind-stream f: (addr stream _) - 43 sig stream-data-equal? f: (addr stream byte), s: (addr array byte) -> _/eax: boolean - 44 sig streams-data-equal? f: (addr stream byte), s: (addr stream byte) -> _/eax: boolean - 45 sig check-stream-equal f: (addr stream byte), s: (addr array byte), msg: (addr array byte) - 46 sig next-stream-line-equal? f: (addr stream byte), s: (addr array byte) -> _/eax: boolean - 47 sig check-next-stream-line-equal f: (addr stream byte), s: (addr array byte), msg: (addr array byte) - 48 sig write f: (addr stream byte), s: (addr array byte) - 49 sig try-write f: (addr stream byte), s: (addr array byte) -> _/eax: boolean - 50 # probably a bad idea; I definitely want to discourage its use for streams of non-bytes - 51 sig stream-size f: (addr stream byte) -> _/eax: int - 52 sig space-remaining-in-stream f: (addr stream byte) -> _/eax: int - 53 sig write-stream f: (addr stream byte), s: (addr stream byte) - 54 sig read-byte s: (addr stream byte) -> _/eax: byte - 55 sig append-byte f: (addr stream byte), n: int # really just a byte, but I want to pass in literal numbers - 56 #sig to-hex-char in/eax: int -> out/eax: int - 57 sig append-byte-hex f: (addr stream byte), n: int # really just a byte, but I want to pass in literal numbers - 58 sig write-int32-hex f: (addr stream byte), n: int - 59 sig write-int32-hex-bits f: (addr stream byte), n: int, bits: int - 60 sig hex-int? in: (addr slice) -> _/eax: boolean - 61 sig parse-hex-int in: (addr array byte) -> _/eax: int - 62 sig parse-hex-int-from-slice in: (addr slice) -> _/eax: int - 63 #sig parse-hex-int-helper start: (addr byte), end: (addr byte) -> _/eax: int - 64 sig hex-digit? c: byte -> _/eax: boolean - 65 #sig from-hex-char in/eax: byte -> out/eax: nibble - 66 sig parse-decimal-int in: (addr array byte) -> _/eax: int - 67 sig parse-decimal-int-from-slice in: (addr slice) -> _/eax: int - 68 sig parse-decimal-int-from-stream in: (addr stream byte) -> _/eax: int - 69 #sig parse-decimal-int-helper start: (addr byte), end: (addr byte) -> _/eax: int - 70 sig decimal-size n: int -> _/eax: int - 71 #sig allocate ad: (addr allocation-descriptor), n: int, out: (addr handle _) - 72 #sig allocate-raw ad: (addr allocation-descriptor), n: int, out: (addr handle _) - 73 sig lookup h: (handle _T) -> _/eax: (addr _T) - 74 sig handle-equal? a: (handle _T), b: (handle _T) -> _/eax: boolean - 75 sig copy-handle src: (handle _T), dest: (addr handle _T) - 76 #sig allocate-region ad: (addr allocation-descriptor), n: int, out: (addr handle allocation-descriptor) - 77 #sig allocate-array ad: (addr allocation-descriptor), n: int, out: (addr handle _) - 78 sig copy-array ad: (addr allocation-descriptor), src: (addr array _T), out: (addr handle array _T) - 79 #sig zero-out start: (addr byte), size: int - 80 sig slice-empty? s: (addr slice) -> _/eax: boolean - 81 sig slice-equal? s: (addr slice), p: (addr array byte) -> _/eax: boolean - 82 sig slice-starts-with? s: (addr slice), head: (addr array byte) -> _/eax: boolean - 83 sig write-slice out: (addr stream byte), s: (addr slice) - 84 # bad name alert - 85 sig slice-to-string ad: (addr allocation-descriptor), in: (addr slice), out: (addr handle array byte) - 86 sig write-int32-decimal out: (addr stream byte), n: int - 87 sig decimal-digit? c: grapheme -> _/eax: boolean - 88 sig to-decimal-digit in: grapheme -> _/eax: int - 89 # bad name alert - 90 # next-word really tokenizes - 91 # next-raw-word really reads whitespace-separated words - 92 sig next-word line: (addr stream byte), out: (addr slice) # skips '#' comments - 93 sig next-raw-word line: (addr stream byte), out: (addr slice) # does not skip '#' comments - 94 sig stream-empty? s: (addr stream _) -> _/eax: boolean - 95 sig stream-full? s: (addr stream _) -> _/eax: boolean - 96 sig stream-to-array in: (addr stream _), out: (addr handle array _) - 97 sig unquote-stream-to-array in: (addr stream _), out: (addr handle array _) - 98 sig stream-first s: (addr stream byte) -> _/eax: byte - 99 sig stream-final s: (addr stream byte) -> _/eax: byte -100 -101 #sig copy-bytes src: (addr byte), dest: (addr byte), n: int -102 sig copy-array-object src: (addr array _), dest-ah: (addr handle array _) -103 sig array-equal? a: (addr array int), b: (addr array int) -> _/eax: boolean -104 sig parse-array-of-ints s: (addr array byte), out: (addr handle array int) -105 sig parse-array-of-decimal-ints s: (addr array byte), out: (addr handle array int) -106 sig check-array-equal a: (addr array int), expected: (addr string), msg: (addr string) -107 -108 sig integer-divide a: int, b: int -> _/eax: int, _/edx: int + 4 sig draw-grapheme-on-screen-array screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int + 5 sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int + 6 sig set-cursor-position-on-real-screen x: int, y: int + 7 sig draw-cursor-on-real-screen g: grapheme + 8 sig color-rgb color: int -> _/ecx: int, _/edx: int, _/ebx: int + 9 + 10 # keyboard + 11 sig read-key kbd: (addr keyboard) -> _/eax: byte + 12 + 13 # disk + 14 sig load-sectors disk: (addr disk), lba: int, n: int, out: (addr stream byte) + 15 sig store-sectors disk: (addr disk), lba: int, n: int, out: (addr stream byte) + 16 + 17 # mouse + 18 sig read-mouse-event -> _/eax: int, _/ecx: int + 19 + 20 # tests + 21 sig count-test-failure + 22 sig num-test-failures -> _/eax: int + 23 sig running-tests? -> _/eax: boolean + 24 + 25 sig string-equal? s: (addr array byte), benchmark: (addr array byte) -> _/eax: boolean + 26 sig string-starts-with? s: (addr array byte), benchmark: (addr array byte) -> _/eax: boolean + 27 sig check-strings-equal s: (addr array byte), expected: (addr array byte), msg: (addr array byte) + 28 + 29 # debugging + 30 sig check-stack + 31 sig show-stack-state + 32 sig debug-print x: (addr array byte), fg: int, bg: int + 33 sig debug-print? -> _/eax: boolean + 34 sig turn-on-debug-print + 35 sig turn-off-debug-print + 36 sig abort e: (addr array byte) + 37 sig dump-call-stack + 38 + 39 sig count-event + 40 sig count-of-events -> _/eax: int + 41 + 42 # streams + 43 sig clear-stream f: (addr stream _) + 44 sig rewind-stream f: (addr stream _) + 45 sig stream-data-equal? f: (addr stream byte), s: (addr array byte) -> _/eax: boolean + 46 sig streams-data-equal? f: (addr stream byte), s: (addr stream byte) -> _/eax: boolean + 47 sig check-stream-equal f: (addr stream byte), s: (addr array byte), msg: (addr array byte) + 48 sig next-stream-line-equal? f: (addr stream byte), s: (addr array byte) -> _/eax: boolean + 49 sig check-next-stream-line-equal f: (addr stream byte), s: (addr array byte), msg: (addr array byte) + 50 sig write f: (addr stream byte), s: (addr array byte) + 51 sig try-write f: (addr stream byte), s: (addr array byte) -> _/eax: boolean + 52 # probably a bad idea; I definitely want to discourage its use for streams of non-bytes + 53 sig stream-size f: (addr stream byte) -> _/eax: int + 54 sig space-remaining-in-stream f: (addr stream byte) -> _/eax: int + 55 sig write-stream f: (addr stream byte), s: (addr stream byte) + 56 sig read-byte s: (addr stream byte) -> _/eax: byte + 57 sig append-byte f: (addr stream byte), n: int # really just a byte, but I want to pass in literal numbers + 58 #sig to-hex-char in/eax: int -> out/eax: int + 59 sig append-byte-hex f: (addr stream byte), n: int # really just a byte, but I want to pass in literal numbers + 60 sig write-int32-hex f: (addr stream byte), n: int + 61 sig write-int32-hex-bits f: (addr stream byte), n: int, bits: int + 62 sig hex-int? in: (addr slice) -> _/eax: boolean + 63 sig parse-hex-int in: (addr array byte) -> _/eax: int + 64 sig parse-hex-int-from-slice in: (addr slice) -> _/eax: int + 65 #sig parse-hex-int-helper start: (addr byte), end: (addr byte) -> _/eax: int + 66 sig hex-digit? c: byte -> _/eax: boolean + 67 #sig from-hex-char in/eax: byte -> out/eax: nibble + 68 sig parse-decimal-int in: (addr array byte) -> _/eax: int + 69 sig parse-decimal-int-from-slice in: (addr slice) -> _/eax: int + 70 sig parse-decimal-int-from-stream in: (addr stream byte) -> _/eax: int + 71 #sig parse-decimal-int-helper start: (addr byte), end: (addr byte) -> _/eax: int + 72 sig decimal-size n: int -> _/eax: int + 73 #sig allocate ad: (addr allocation-descriptor), n: int, out: (addr handle _) + 74 #sig allocate-raw ad: (addr allocation-descriptor), n: int, out: (addr handle _) + 75 sig lookup h: (handle _T) -> _/eax: (addr _T) + 76 sig handle-equal? a: (handle _T), b: (handle _T) -> _/eax: boolean + 77 sig copy-handle src: (handle _T), dest: (addr handle _T) + 78 #sig allocate-region ad: (addr allocation-descriptor), n: int, out: (addr handle allocation-descriptor) + 79 #sig allocate-array ad: (addr allocation-descriptor), n: int, out: (addr handle _) + 80 sig copy-array ad: (addr allocation-descriptor), src: (addr array _T), out: (addr handle array _T) + 81 #sig zero-out start: (addr byte), size: int + 82 sig slice-empty? s: (addr slice) -> _/eax: boolean + 83 sig slice-equal? s: (addr slice), p: (addr array byte) -> _/eax: boolean + 84 sig slice-starts-with? s: (addr slice), head: (addr array byte) -> _/eax: boolean + 85 sig write-slice out: (addr stream byte), s: (addr slice) + 86 # bad name alert + 87 sig slice-to-string ad: (addr allocation-descriptor), in: (addr slice), out: (addr handle array byte) + 88 sig write-int32-decimal out: (addr stream byte), n: int + 89 sig decimal-digit? c: grapheme -> _/eax: boolean + 90 sig to-decimal-digit in: grapheme -> _/eax: int + 91 # bad name alert + 92 # next-word really tokenizes + 93 # next-raw-word really reads whitespace-separated words + 94 sig next-word line: (addr stream byte), out: (addr slice) # skips '#' comments + 95 sig next-raw-word line: (addr stream byte), out: (addr slice) # does not skip '#' comments + 96 sig stream-empty? s: (addr stream _) -> _/eax: boolean + 97 sig stream-full? s: (addr stream _) -> _/eax: boolean + 98 sig stream-to-array in: (addr stream _), out: (addr handle array _) + 99 sig unquote-stream-to-array in: (addr stream _), out: (addr handle array _) +100 sig stream-first s: (addr stream byte) -> _/eax: byte +101 sig stream-final s: (addr stream byte) -> _/eax: byte +102 +103 #sig copy-bytes src: (addr byte), dest: (addr byte), n: int +104 sig copy-array-object src: (addr array _), dest-ah: (addr handle array _) +105 sig array-equal? a: (addr array int), b: (addr array int) -> _/eax: boolean +106 sig parse-array-of-ints s: (addr array byte), out: (addr handle array int) +107 sig parse-array-of-decimal-ints s: (addr array byte), out: (addr handle array int) +108 sig check-array-equal a: (addr array int), expected: (addr string), msg: (addr string) +109 +110 sig integer-divide a: int, b: int -> _/eax: int, _/edx: int diff --git a/html/403unicode.mu.html b/html/403unicode.mu.html index 81f5c9c0..3e6704f0 100644 --- a/html/403unicode.mu.html +++ b/html/403unicode.mu.html @@ -15,10 +15,15 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEdi { color: #87ffd7; } .Special { color: #ff6060; } .LineNr { } -.Delimiter { color: #c000c0; } .Constant { color: #008787; } +.muRegEdx { color: #878700; } +.muRegEcx { color: #af875f; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } +.Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } --> @@ -77,16 +82,16 @@ if ('onhashchange' in window) { 19 # 20 # The day we want to support combining characters, this function will need to 21 # take multiple code points. Or something. - 22 fn to-grapheme in: code-point -> _/eax: grapheme { - 23 var c/eax: int <- copy in - 24 var num-trailers/ecx: int <- copy 0 - 25 var first/edx: int <- copy 0 + 22 fn to-grapheme in: code-point -> _/eax: grapheme { + 23 var c/eax: int <- copy in + 24 var num-trailers/ecx: int <- copy 0 + 25 var first/edx: int <- copy 0 26 $to-grapheme:compute-length: { 27 # single byte: just return it 28 compare c, 0x7f 29 { 30 break-if-> - 31 var g/eax: grapheme <- copy c + 31 var g/eax: grapheme <- copy c 32 return g 33 } 34 # 2 bytes @@ -122,11 +127,11 @@ if ('onhashchange' in window) { 64 } 65 } 66 # emit trailer bytes, 6 bits from 'in', first two bits '10' - 67 var result/edi: grapheme <- copy 0 + 67 var result/edi: grapheme <- copy 0 68 { 69 compare num-trailers, 0 70 break-if-<= - 71 var tmp/esi: int <- copy c + 71 var tmp/esi: int <- copy c 72 tmp <- and 0x3f 73 tmp <- or 0x80 74 result <- shift-left 8 @@ -147,28 +152,28 @@ if ('onhashchange' in window) { 89 # TODO: bring in tests once we have check-ints-equal 90 91 # read the next grapheme from a stream of bytes - 92 fn read-grapheme in: (addr stream byte) -> _/eax: grapheme { + 92 fn read-grapheme in: (addr stream byte) -> _/eax: grapheme { 93 # if at eof, return EOF 94 { - 95 var eof?/eax: boolean <- stream-empty? in + 95 var eof?/eax: boolean <- stream-empty? in 96 compare eof?, 0/false 97 break-if-= 98 return 0xffffffff 99 } -100 var c/eax: byte <- read-byte in -101 var num-trailers/ecx: int <- copy 0 +100 var c/eax: byte <- read-byte in +101 var num-trailers/ecx: int <- copy 0 102 $read-grapheme:compute-length: { 103 # single byte: just return it 104 compare c, 0xc0 105 { 106 break-if->= -107 var g/eax: grapheme <- copy c +107 var g/eax: grapheme <- copy c 108 return g 109 } 110 compare c, 0xfe 111 { 112 break-if-< -113 var g/eax: grapheme <- copy c +113 var g/eax: grapheme <- copy c 114 return g 115 } 116 # 2 bytes @@ -196,13 +201,13 @@ if ('onhashchange' in window) { 138 return 0 139 } 140 # prepend trailer bytes -141 var result/edi: grapheme <- copy c -142 var num-byte-shifts/edx: int <- copy 1 +141 var result/edi: grapheme <- copy c +142 var num-byte-shifts/edx: int <- copy 1 143 { 144 compare num-trailers, 0 145 break-if-<= -146 var tmp/eax: byte <- read-byte in -147 var tmp2/eax: int <- copy tmp +146 var tmp/eax: byte <- read-byte in +147 var tmp2/eax: int <- copy tmp 148 tmp2 <- shift-left-bytes tmp2, num-byte-shifts 149 result <- or tmp2 150 # update loop state @@ -214,9 +219,9 @@ if ('onhashchange' in window) { 156 } 157 158 # needed because available primitives only shift by a literal/constant number of bits -159 fn shift-left-bytes n: int, k: int -> _/eax: int { -160 var i/ecx: int <- copy 0 -161 var result/eax: int <- copy n +159 fn shift-left-bytes n: int, k: int -> _/eax: int { +160 var i/ecx: int <- copy 0 +161 var result/eax: int <- copy n 162 { 163 compare i, k 164 break-if->= @@ -233,7 +238,7 @@ if ('onhashchange' in window) { 175 # this is like write-to-stream, except we skip leading 0 bytes 176 fn write-grapheme out: (addr stream byte), g: grapheme { 177 $write-grapheme:body: { -178 var c/eax: int <- copy g +178 var c/eax: int <- copy g 179 append-byte out, c # first byte is always written 180 c <- shift-right 8 181 compare c, 0 diff --git a/html/408float.mu.html b/html/408float.mu.html index 730715ed..679d900f 100644 --- a/html/408float.mu.html +++ b/html/408float.mu.html @@ -18,6 +18,7 @@ a { color:inherit; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEdi { color: #87ffd7; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -59,7 +60,7 @@ if ('onhashchange' in window) { 1 # Some quick-n-dirty ways to create floats. 2 3 fn fill-in-rational _out: (addr float), nr: int, dr: int { - 4 var out/edi: (addr float) <- copy _out + 4 var out/edi: (addr float) <- copy _out 5 var result/xmm0: float <- convert nr 6 var divisor/xmm1: float <- convert dr 7 result <- divide divisor @@ -67,7 +68,7 @@ if ('onhashchange' in window) { 9 } 10 11 fn fill-in-sqrt _out: (addr float), n: int { -12 var out/edi: (addr float) <- copy _out +12 var out/edi: (addr float) <- copy _out 13 var result/xmm0: float <- convert n 14 result <- square-root result 15 copy-to *out, result diff --git a/html/411string.mu.html b/html/411string.mu.html index 34405d4c..115f2639 100644 --- a/html/411string.mu.html +++ b/html/411string.mu.html @@ -15,10 +15,14 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } +.muRegEax { color: #875f00; } .Special { color: #ff6060; } .LineNr { } -.Constant { color: #008787; } .CommentedCode { color: #8a8a8a; } +.Constant { color: #008787; } +.muRegEsi { color: #87d787; } +.muRegEdi { color: #87ffd7; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muTest { color: #5f8700; } @@ -61,18 +65,18 @@ if ('onhashchange' in window) { 1 # read up to 'len' graphemes after skipping the first 'start' ones 2 fn substring in: (addr array byte), start: int, len: int, out-ah: (addr handle array byte) { 3 var in-stream: (stream byte 0x100) - 4 var in-stream-addr/esi: (addr stream byte) <- address in-stream + 4 var in-stream-addr/esi: (addr stream byte) <- address in-stream 5 write in-stream-addr, in 6 var out-stream: (stream byte 0x100) - 7 var out-stream-addr/edi: (addr stream byte) <- address out-stream + 7 var out-stream-addr/edi: (addr stream byte) <- address out-stream 8 $substring:core: { 9 # skip 'start' graphemes - 10 var i/eax: int <- copy 0 + 10 var i/eax: int <- copy 0 11 { 12 compare i, start 13 break-if->= 14 { - 15 var dummy/eax: grapheme <- read-grapheme in-stream-addr + 15 var dummy/eax: grapheme <- read-grapheme in-stream-addr 16 compare dummy, 0xffffffff/end-of-file 17 break-if-= $substring:core 18 } @@ -85,7 +89,7 @@ if ('onhashchange' in window) { 25 compare i, len 26 break-if->= 27 { - 28 var g/eax: grapheme <- read-grapheme in-stream-addr + 28 var g/eax: grapheme <- read-grapheme in-stream-addr 29 compare g, 0xffffffff/end-of-file 30 break-if-= $substring:core 31 write-grapheme out-stream-addr, g @@ -99,62 +103,62 @@ if ('onhashchange' in window) { 39 40 fn test-substring { 41 var out-h: (handle array byte) - 42 var out-ah/edi: (addr handle array byte) <- address out-h + 42 var out-ah/edi: (addr handle array byte) <- address out-h 43 # prefix substrings 44 substring 0, 0, 3, out-ah - 45 var out/eax: (addr array byte) <- lookup *out-ah + 45 var out/eax: (addr array byte) <- lookup *out-ah 46 check-strings-equal out, "", "F - test-substring/null" 47 substring "", 0, 3, out-ah - 48 var out/eax: (addr array byte) <- lookup *out-ah + 48 var out/eax: (addr array byte) <- lookup *out-ah 49 #? print-string-to-real-screen out 50 #? print-string-to-real-screen "\n" 51 check-strings-equal out, "", "F - test-substring/empty" 52 # 53 substring "abcde", 0, 3, out-ah - 54 var out/eax: (addr array byte) <- lookup *out-ah + 54 var out/eax: (addr array byte) <- lookup *out-ah 55 #? print-string-to-real-screen out 56 #? print-string-to-real-screen "\n" 57 check-strings-equal out, "abc", "F - test-substring/truncate" 58 # 59 substring "abcde", 0, 5, out-ah - 60 var out/eax: (addr array byte) <- lookup *out-ah + 60 var out/eax: (addr array byte) <- lookup *out-ah 61 check-strings-equal out, "abcde", "F - test-substring/all" 62 # 63 substring "abcde", 0, 7, out-ah - 64 var out/eax: (addr array byte) <- lookup *out-ah + 64 var out/eax: (addr array byte) <- lookup *out-ah 65 check-strings-equal out, "abcde", "F - test-substring/too-small" 66 # substrings outside string 67 substring "abcde", 6, 1, out-ah - 68 var out/eax: (addr array byte) <- lookup *out-ah + 68 var out/eax: (addr array byte) <- lookup *out-ah 69 check-strings-equal out, "", "F - test-substring/start-too-large" 70 # trim prefix 71 substring "", 2, 3, out-ah - 72 var out/eax: (addr array byte) <- lookup *out-ah + 72 var out/eax: (addr array byte) <- lookup *out-ah 73 check-strings-equal out, "", "F - test-substring/middle-empty" 74 # 75 substring "abcde", 1, 2, out-ah - 76 var out/eax: (addr array byte) <- lookup *out-ah + 76 var out/eax: (addr array byte) <- lookup *out-ah 77 check-strings-equal out, "bc", "F - test-substring/middle-truncate" 78 # 79 substring "abcde", 1, 4, out-ah - 80 var out/eax: (addr array byte) <- lookup *out-ah + 80 var out/eax: (addr array byte) <- lookup *out-ah 81 check-strings-equal out, "bcde", "F - test-substring/middle-all" 82 # 83 substring "abcde", 1, 5, out-ah - 84 var out/eax: (addr array byte) <- lookup *out-ah + 84 var out/eax: (addr array byte) <- lookup *out-ah 85 check-strings-equal out, "bcde", "F - test-substring/middle-too-small" 86 } 87 88 fn split-string in: (addr array byte), delim: grapheme, out: (addr handle array (handle array byte)) { 89 var in-stream: (stream byte 0x100) - 90 var in-stream-addr/esi: (addr stream byte) <- address in-stream + 90 var in-stream-addr/esi: (addr stream byte) <- address in-stream 91 write in-stream-addr, in 92 var tokens-stream: (stream (handle array byte) 0x100) - 93 var tokens-stream-addr/edi: (addr stream (handle array byte)) <- address tokens-stream + 93 var tokens-stream-addr/edi: (addr stream (handle array byte)) <- address tokens-stream 94 var curr-stream: (stream byte 0x100) - 95 var curr-stream-addr/ecx: (addr stream byte) <- address curr-stream + 95 var curr-stream-addr/ecx: (addr stream byte) <- address curr-stream 96 $split-string:core: { - 97 var g/eax: grapheme <- read-grapheme in-stream-addr + 97 var g/eax: grapheme <- read-grapheme in-stream-addr 98 compare g, 0xffffffff 99 break-if-= 100 #? print-grapheme-to-real-screen g @@ -164,7 +168,7 @@ if ('onhashchange' in window) { 104 break-if-!= 105 # token complete; flush 106 var token: (handle array byte) -107 var token-ah/eax: (addr handle array byte) <- address token +107 var token-ah/eax: (addr handle array byte) <- address token 108 stream-to-array curr-stream-addr, token-ah 109 write-to-stream tokens-stream-addr, token-ah 110 clear-stream curr-stream-addr @@ -178,7 +182,7 @@ if ('onhashchange' in window) { 118 119 fn test-split-string { 120 var out-h: (handle array (handle array byte)) -121 var out-ah/edi: (addr handle array (handle array byte)) <- address out-h +121 var out-ah/edi: (addr handle array (handle array byte)) <- address out-h 122 # prefix substrings 123 split-string "bab", 0x61, out-ah 124 # no crash diff --git a/html/412render-float-decimal.mu.html b/html/412render-float-decimal.mu.html index 55f594cb..155822e4 100644 --- a/html/412render-float-decimal.mu.html +++ b/html/412render-float-decimal.mu.html @@ -14,14 +14,20 @@ pre { white-space: pre-wrap; font-family: monospace; color: #000000; background- body { font-size:12pt; font-family: monospace; color: #000000; background-color: #a8a8a8; } a { color:inherit; } * { font-size:12pt; font-size: 1em; } -.PreProc { color: #c000c0; } .LineNr { } -.Constant { color: #008787; } -.muFunction { color: #af5f00; text-decoration: underline; } .Delimiter { color: #c000c0; } +.muRegEdx { color: #878700; } +.muRegEbx { color: #8787af; } +.muRegEsi { color: #87d787; } +.muRegEdi { color: #87ffd7; } +.Constant { color: #008787; } .Special { color: #ff6060; } +.PreProc { color: #c000c0; } +.muFunction { color: #af5f00; text-decoration: underline; } .muTest { color: #5f8700; } .muComment { color: #005faf; } +.muRegEax { color: #875f00; } +.muRegEcx { color: #af875f; } --> @@ -83,7 +89,7 @@ if ('onhashchange' in window) { 24 25 fn test-write-float-decimal-approximate-normal { 26 var s-storage: (stream byte 0x10) - 27 var s/ecx: (addr stream byte) <- address s-storage + 27 var s/ecx: (addr stream byte) <- address s-storage 28 # 0.5 29 var half/xmm0: float <- rational 1, 2 30 write-float-decimal-approximate s, half, 3 @@ -119,7 +125,7 @@ if ('onhashchange' in window) { 60 # print whole integers without decimals 61 fn test-write-float-decimal-approximate-integer { 62 var s-storage: (stream byte 0x10) - 63 var s/ecx: (addr stream byte) <- address s-storage + 63 var s/ecx: (addr stream byte) <- address s-storage 64 # 1 65 var one-f/xmm0: float <- rational 1, 1 66 write-float-decimal-approximate s, one-f, 3 @@ -151,7 +157,7 @@ if ('onhashchange' in window) { 92 check-stream-equal s, "1.00e3", "F - test-write-float-decimal-approximate-integer 1000" 93 # 100,000 94 clear-stream s - 95 var hundred-thousand/eax: int <- copy 0x186a0 + 95 var hundred-thousand/eax: int <- copy 0x186a0 96 var hundred-thousand-f/xmm0: float <- convert hundred-thousand 97 write-float-decimal-approximate s, hundred-thousand-f, 3 98 check-stream-equal s, "1.00e5", "F - test-write-float-decimal-approximate-integer 100,000" @@ -159,7 +165,7 @@ if ('onhashchange' in window) { 100 101 fn test-write-float-decimal-approximate-zero { 102 var s-storage: (stream byte 0x10) -103 var s/ecx: (addr stream byte) <- address s-storage +103 var s/ecx: (addr stream byte) <- address s-storage 104 var zero: float 105 write-float-decimal-approximate s, zero, 3 106 check-stream-equal s, "0", "F - test-write-float-decimal-approximate-zero" @@ -167,7 +173,7 @@ if ('onhashchange' in window) { 108 109 fn test-write-float-decimal-approximate-negative-zero { 110 var s-storage: (stream byte 0x10) -111 var s/ecx: (addr stream byte) <- address s-storage +111 var s/ecx: (addr stream byte) <- address s-storage 112 var n: int 113 copy-to n, 0x80000000 114 var negative-zero/xmm0: float <- reinterpret n @@ -177,7 +183,7 @@ if ('onhashchange' in window) { 118 119 fn test-write-float-decimal-approximate-infinity { 120 var s-storage: (stream byte 0x10) -121 var s/ecx: (addr stream byte) <- address s-storage +121 var s/ecx: (addr stream byte) <- address s-storage 122 var n: int 123 # 0|11111111|00000000000000000000000 124 # 0111|1111|1000|0000|0000|0000|0000|0000 @@ -189,7 +195,7 @@ if ('onhashchange' in window) { 130 131 fn test-write-float-decimal-approximate-negative-infinity { 132 var s-storage: (stream byte 0x10) -133 var s/ecx: (addr stream byte) <- address s-storage +133 var s/ecx: (addr stream byte) <- address s-storage 134 var n: int 135 copy-to n, 0xff800000 136 var negative-infinity/xmm0: float <- reinterpret n @@ -199,7 +205,7 @@ if ('onhashchange' in window) { 140 141 fn test-write-float-decimal-approximate-not-a-number { 142 var s-storage: (stream byte 0x10) -143 var s/ecx: (addr stream byte) <- address s-storage +143 var s/ecx: (addr stream byte) <- address s-storage 144 var n: int 145 copy-to n, 0xffffffff # exponent must be all 1's, and mantissa must be non-zero 146 var nan/xmm0: float <- reinterpret n @@ -207,21 +213,21 @@ if ('onhashchange' in window) { 148 check-stream-equal s, "NaN", "F - test-write-float-decimal-approximate-not-a-number" 149 } 150 -151 fn render-float-decimal screen: (addr screen), in: float, precision: int, x: int, y: int, color: int, background-color: int -> _/eax: int { +151 fn render-float-decimal screen: (addr screen), in: float, precision: int, x: int, y: int, color: int, background-color: int -> _/eax: int { 152 var s-storage: (stream byte 0x10) -153 var s/esi: (addr stream byte) <- address s-storage +153 var s/esi: (addr stream byte) <- address s-storage 154 write-float-decimal-approximate s, in, precision -155 var width/eax: int <- copy 0 -156 var height/ecx: int <- copy 0 -157 width, height <- screen-size screen -158 var result/eax: int <- draw-stream-rightward screen, s, x, width, y, color, background-color +155 var width/eax: int <- copy 0 +156 var height/ecx: int <- copy 0 +157 width, height <- screen-size screen +158 var result/eax: int <- draw-stream-rightward screen, s, x, width, y, color, background-color 159 return result 160 } 161 162 # 'precision' controls the maximum width past which we resort to scientific notation 163 fn write-float-decimal-approximate out: (addr stream byte), in: float, precision: int { 164 # - special names -165 var bits/eax: int <- reinterpret in +165 var bits/eax: int <- reinterpret in 166 compare bits, 0 167 { 168 break-if-!= @@ -246,7 +252,7 @@ if ('onhashchange' in window) { 187 write out, "-Inf" 188 return 189 } -190 var exponent/ecx: int <- copy bits +190 var exponent/ecx: int <- copy bits 191 exponent <- shift-right 0x17 # 23 bits of mantissa 192 exponent <- and 0xff 193 exponent <- subtract 0x7f @@ -257,7 +263,7 @@ if ('onhashchange' in window) { 198 return 199 } 200 # - regular numbers -201 var sign/edx: int <- copy bits +201 var sign/edx: int <- copy bits 202 sign <- shift-right 0x1f 203 { 204 compare sign, 1 @@ -266,18 +272,18 @@ if ('onhashchange' in window) { 207 } 208 209 # v = 1.mantissa (in base 2) << 0x17 -210 var v/ebx: int <- copy bits +210 var v/ebx: int <- copy bits 211 v <- and 0x7fffff 212 v <- or 0x00800000 # insert implicit 1 213 # e = exponent - 0x17 -214 var e/ecx: int <- copy exponent +214 var e/ecx: int <- copy exponent 215 e <- subtract 0x17 # move decimal place from before mantissa to after 216 217 # initialize buffer with decimal representation of v 218 # unlike https://research.swtch.com/ftoa, no ascii here 219 var buf-storage: (array byte 0x7f) -220 var buf/edi: (addr array byte) <- address buf-storage -221 var n/eax: int <- decimal-digits v, buf +220 var buf/edi: (addr array byte) <- address buf-storage +221 var n/eax: int <- decimal-digits v, buf 222 # I suspect we can do without reversing, but we'll follow https://research.swtch.com/ftoa 223 # closely for now. 224 reverse-digits buf, n @@ -291,7 +297,7 @@ if ('onhashchange' in window) { 232 loop 233 } 234 -235 var dp/edx: int <- copy n +235 var dp/edx: int <- copy n 236 237 # loop if e < 0 238 { @@ -307,16 +313,16 @@ if ('onhashchange' in window) { 248 249 # store the decimal digits of 'n' into 'buf', units first 250 # n must be positive -251 fn decimal-digits n: int, _buf: (addr array byte) -> _/eax: int { -252 var buf/edi: (addr array byte) <- copy _buf -253 var i/ecx: int <- copy 0 -254 var curr/eax: int <- copy n -255 var curr-byte/edx: int <- copy 0 +251 fn decimal-digits n: int, _buf: (addr array byte) -> _/eax: int { +252 var buf/edi: (addr array byte) <- copy _buf +253 var i/ecx: int <- copy 0 +254 var curr/eax: int <- copy n +255 var curr-byte/edx: int <- copy 0 256 { 257 compare curr, 0 258 break-if-= 259 curr, curr-byte <- integer-divide curr, 0xa -260 var dest/ebx: (addr byte) <- index buf, i +260 var dest/ebx: (addr byte) <- index buf, i 261 copy-byte-to *dest, curr-byte 262 i <- increment 263 loop @@ -325,18 +331,18 @@ if ('onhashchange' in window) { 266 } 267 268 fn reverse-digits _buf: (addr array byte), n: int { -269 var buf/esi: (addr array byte) <- copy _buf -270 var left/ecx: int <- copy 0 -271 var right/edx: int <- copy n +269 var buf/esi: (addr array byte) <- copy _buf +270 var left/ecx: int <- copy 0 +271 var right/edx: int <- copy n 272 right <- decrement 273 { 274 compare left, right 275 break-if->= 276 { -277 var l-a/ecx: (addr byte) <- index buf, left -278 var r-a/edx: (addr byte) <- index buf, right -279 var l/ebx: byte <- copy-byte *l-a -280 var r/eax: byte <- copy-byte *r-a +277 var l-a/ecx: (addr byte) <- index buf, left +278 var r-a/edx: (addr byte) <- index buf, right +279 var l/ebx: byte <- copy-byte *l-a +280 var r/eax: byte <- copy-byte *r-a 281 copy-byte-to *l-a, r 282 copy-byte-to *r-a, l 283 } @@ -346,37 +352,37 @@ if ('onhashchange' in window) { 287 } 288 } 289 -290 fn double-array-of-decimal-digits _buf: (addr array byte), _n: int -> _/eax: int { -291 var buf/edi: (addr array byte) <- copy _buf +290 fn double-array-of-decimal-digits _buf: (addr array byte), _n: int -> _/eax: int { +291 var buf/edi: (addr array byte) <- copy _buf 292 # initialize delta -293 var delta/edx: int <- copy 0 +293 var delta/edx: int <- copy 0 294 { -295 var curr/ebx: (addr byte) <- index buf, 0 -296 var tmp/eax: byte <- copy-byte *curr +295 var curr/ebx: (addr byte) <- index buf, 0 +296 var tmp/eax: byte <- copy-byte *curr 297 compare tmp, 5 298 break-if-< 299 delta <- copy 1 300 } 301 # loop -302 var x/eax: int <- copy 0 -303 var i/ecx: int <- copy _n +302 var x/eax: int <- copy 0 +303 var i/ecx: int <- copy _n 304 i <- decrement 305 { 306 compare i, 0 307 break-if-<= 308 # x += 2*buf[i] 309 { -310 var tmp/ecx: (addr byte) <- index buf, i -311 var tmp2/ecx: byte <- copy-byte *tmp +310 var tmp/ecx: (addr byte) <- index buf, i +311 var tmp2/ecx: byte <- copy-byte *tmp 312 x <- add tmp2 313 x <- add tmp2 314 } 315 # x, buf[i+delta] = x/10, x%10 316 { -317 var dest-index/ecx: int <- copy i +317 var dest-index/ecx: int <- copy i 318 dest-index <- add delta -319 var dest/edi: (addr byte) <- index buf, dest-index -320 var next-digit/edx: int <- copy 0 +319 var dest/edi: (addr byte) <- index buf, dest-index +320 var next-digit/edx: int <- copy 0 321 x, next-digit <- integer-divide x, 0xa 322 copy-byte-to *dest, next-digit 323 } @@ -385,51 +391,51 @@ if ('onhashchange' in window) { 326 loop 327 } 328 # final patch-up -329 var n/eax: int <- copy _n +329 var n/eax: int <- copy _n 330 compare delta, 1 331 { 332 break-if-!= -333 var curr/ebx: (addr byte) <- index buf, 0 -334 var one/edx: int <- copy 1 +333 var curr/ebx: (addr byte) <- index buf, 0 +334 var one/edx: int <- copy 1 335 copy-byte-to *curr, one 336 n <- increment 337 } 338 return n 339 } 340 -341 fn halve-array-of-decimal-digits _buf: (addr array byte), _n: int, _dp: int -> _/eax: int, _/edx: int { -342 var buf/edi: (addr array byte) <- copy _buf -343 var n/eax: int <- copy _n -344 var dp/edx: int <- copy _dp +341 fn halve-array-of-decimal-digits _buf: (addr array byte), _n: int, _dp: int -> _/eax: int, _/edx: int { +342 var buf/edi: (addr array byte) <- copy _buf +343 var n/eax: int <- copy _n +344 var dp/edx: int <- copy _dp 345 # initialize one side 346 { 347 # if buf[n-1]%2 == 0, break -348 var right-index/ecx: int <- copy n +348 var right-index/ecx: int <- copy n 349 right-index <- decrement -350 var right-a/ecx: (addr byte) <- index buf, right-index -351 var right/ecx: byte <- copy-byte *right-a -352 var right-int/ecx: int <- copy right -353 var remainder/edx: int <- copy 0 +350 var right-a/ecx: (addr byte) <- index buf, right-index +351 var right/ecx: byte <- copy-byte *right-a +352 var right-int/ecx: int <- copy right +353 var remainder/edx: int <- copy 0 354 { -355 var dummy/eax: int <- copy 0 +355 var dummy/eax: int <- copy 0 356 dummy, remainder <- integer-divide right-int, 2 357 } 358 compare remainder, 0 359 break-if-= 360 # buf[n] = 0 -361 var next-a/ecx: (addr byte) <- index buf, n -362 var zero/edx: byte <- copy 0 +361 var next-a/ecx: (addr byte) <- index buf, n +362 var zero/edx: byte <- copy 0 363 copy-byte-to *next-a, zero 364 # n++ 365 n <- increment 366 } 367 # initialize the other -368 var delta/ebx: int <- copy 0 -369 var x/esi: int <- copy 0 +368 var delta/ebx: int <- copy 0 +369 var x/esi: int <- copy 0 370 { 371 # if buf[0] >= 2, break -372 var left/ecx: (addr byte) <- index buf, 0 -373 var src/ecx: byte <- copy-byte *left +372 var left/ecx: (addr byte) <- index buf, 0 +373 var src/ecx: byte <- copy-byte *left 374 compare src, 2 375 break-if->= 376 # delta, x = 1, buf[0] @@ -441,27 +447,27 @@ if ('onhashchange' in window) { 382 dp <- decrement 383 } 384 # loop -385 var i/ecx: int <- copy 0 +385 var i/ecx: int <- copy 0 386 { 387 compare i, n 388 break-if->= 389 # x = x*10 + buf[i+delta] 390 { -391 var ten/edx: int <- copy 0xa +391 var ten/edx: int <- copy 0xa 392 x <- multiply ten -393 var src-index/edx: int <- copy i +393 var src-index/edx: int <- copy i 394 src-index <- add delta -395 var src-a/edx: (addr byte) <- index buf, src-index -396 var src/edx: byte <- copy-byte *src-a +395 var src-a/edx: (addr byte) <- index buf, src-index +396 var src/edx: byte <- copy-byte *src-a 397 x <- add src 398 } 399 # buf[i], x = x/2, x%2 400 { -401 var quotient/eax: int <- copy 0 -402 var remainder/edx: int <- copy 0 +401 var quotient/eax: int <- copy 0 +402 var remainder/edx: int <- copy 0 403 quotient, remainder <- integer-divide x, 2 404 x <- copy remainder -405 var dest/edx: (addr byte) <- index buf, i +405 var dest/edx: (addr byte) <- index buf, i 406 copy-byte-to *dest, quotient 407 } 408 # @@ -472,7 +478,7 @@ if ('onhashchange' in window) { 413 } 414 415 fn _write-float-array-of-decimal-digits out: (addr stream byte), _buf: (addr array byte), n: int, dp: int, precision: int { -416 var buf/edi: (addr array byte) <- copy _buf +416 var buf/edi: (addr array byte) <- copy _buf 417 { 418 compare dp, 0 419 break-if->= @@ -480,7 +486,7 @@ if ('onhashchange' in window) { 421 return 422 } 423 { -424 var dp2/eax: int <- copy dp +424 var dp2/eax: int <- copy dp 425 compare dp2, precision 426 break-if-<= 427 _write-float-array-of-decimal-digits-in-scientific-notation out, buf, n, dp, precision @@ -491,9 +497,9 @@ if ('onhashchange' in window) { 432 break-if-!= 433 append-byte out, 0x30/0 434 } -435 var i/eax: int <- copy 0 +435 var i/eax: int <- copy 0 436 # bounds = min(n, dp+3) -437 var limit/edx: int <- copy dp +437 var limit/edx: int <- copy dp 438 limit <- add 3 439 { 440 compare limit, n @@ -509,9 +515,9 @@ if ('onhashchange' in window) { 450 break-if-!= 451 append-byte out, 0x2e/decimal-point 452 } -453 var curr-a/ecx: (addr byte) <- index buf, i -454 var curr/ecx: byte <- copy-byte *curr-a -455 var curr-int/ecx: int <- copy curr +453 var curr-a/ecx: (addr byte) <- index buf, i +454 var curr/ecx: byte <- copy-byte *curr-a +455 var curr-int/ecx: int <- copy curr 456 curr-int <- add 0x30/0 457 append-byte out, curr-int 458 # @@ -521,8 +527,8 @@ if ('onhashchange' in window) { 462 } 463 464 fn _write-float-array-of-decimal-digits-in-scientific-notation out: (addr stream byte), _buf: (addr array byte), n: int, dp: int, precision: int { -465 var buf/edi: (addr array byte) <- copy _buf -466 var i/eax: int <- copy 0 +465 var buf/edi: (addr array byte) <- copy _buf +466 var i/eax: int <- copy 0 467 { 468 compare i, n 469 break-if->= @@ -533,9 +539,9 @@ if ('onhashchange' in window) { 474 break-if-!= 475 append-byte out, 0x2e/decimal-point 476 } -477 var curr-a/ecx: (addr byte) <- index buf, i -478 var curr/ecx: byte <- copy-byte *curr-a -479 var curr-int/ecx: int <- copy curr +477 var curr-a/ecx: (addr byte) <- index buf, i +478 var curr/ecx: byte <- copy-byte *curr-a +479 var curr-int/ecx: int <- copy curr 480 curr-int <- add 0x30/0 481 append-byte out, curr-int 482 # @@ -549,9 +555,9 @@ if ('onhashchange' in window) { 490 491 # follows the structure of write-float-decimal-approximate 492 # 'precision' controls the maximum width past which we resort to scientific notation -493 fn float-size in: float, precision: int -> _/eax: int { +493 fn float-size in: float, precision: int -> _/eax: int { 494 # - special names -495 var bits/eax: int <- reinterpret in +495 var bits/eax: int <- reinterpret in 496 compare bits, 0 497 { 498 break-if-!= @@ -572,7 +578,7 @@ if ('onhashchange' in window) { 513 break-if-!= 514 return 4 # for "-Inf" 515 } -516 var exponent/ecx: int <- copy bits +516 var exponent/ecx: int <- copy bits 517 exponent <- shift-right 0x17 # 23 bits of mantissa 518 exponent <- and 0xff 519 exponent <- subtract 0x7f @@ -583,17 +589,17 @@ if ('onhashchange' in window) { 524 } 525 # - regular numbers 526 # v = 1.mantissa (in base 2) << 0x17 -527 var v/ebx: int <- copy bits +527 var v/ebx: int <- copy bits 528 v <- and 0x7fffff 529 v <- or 0x00800000 # insert implicit 1 530 # e = exponent - 0x17 -531 var e/ecx: int <- copy exponent +531 var e/ecx: int <- copy exponent 532 e <- subtract 0x17 # move decimal place from before mantissa to after 533 534 # initialize buffer with decimal representation of v 535 var buf-storage: (array byte 0x7f) -536 var buf/edi: (addr array byte) <- address buf-storage -537 var n/eax: int <- decimal-digits v, buf +536 var buf/edi: (addr array byte) <- address buf-storage +537 var n/eax: int <- decimal-digits v, buf 538 reverse-digits buf, n 539 540 # loop if e > 0 @@ -605,7 +611,7 @@ if ('onhashchange' in window) { 546 loop 547 } 548 -549 var dp/edx: int <- copy n +549 var dp/edx: int <- copy n 550 551 # loop if e < 0 552 { @@ -622,14 +628,14 @@ if ('onhashchange' in window) { 563 return 8 # hacky for scientific notation 564 } 565 { -566 var dp2/eax: int <- copy dp +566 var dp2/eax: int <- copy dp 567 compare dp2, precision 568 break-if-<= 569 return 8 # hacky for scientific notation 570 } 571 572 # result = min(n, dp+3) -573 var result/ecx: int <- copy dp +573 var result/ecx: int <- copy dp 574 result <- add 3 575 { 576 compare result, n @@ -645,7 +651,7 @@ if ('onhashchange' in window) { 586 } 587 588 # account for sign -589 var sign/edx: int <- reinterpret in +589 var sign/edx: int <- reinterpret in 590 sign <- shift-right 0x1f 591 { 592 compare sign, 1 diff --git a/html/500fake-screen.mu.html b/html/500fake-screen.mu.html index b6b99964..9d888ee9 100644 --- a/html/500fake-screen.mu.html +++ b/html/500fake-screen.mu.html @@ -15,9 +15,15 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } +.muRegEdi { color: #87ffd7; } .Special { color: #ff6060; } .LineNr { } +.muRegEbx { color: #8787af; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -73,547 +79,614 @@ if ('onhashchange' in window) { 15 # text mode 16 width: int 17 height: int - 18 data: (handle array screen-cell) + 18 data: (handle array screen-cell) 19 cursor-x: int # [0..width) 20 cursor-y: int # [0..height) - 21 # pixel graphics - 22 pixels: (handle array byte) - 23 } - 24 - 25 type screen-cell { - 26 data: grapheme - 27 color: int - 28 background-color: int - 29 } - 30 - 31 fn initialize-screen _screen: (addr screen), width: int, height: int, pixel-graphics?: boolean { - 32 var screen/esi: (addr screen) <- copy _screen - 33 var tmp/eax: int <- copy 0 - 34 var dest/edi: (addr int) <- copy 0 - 35 # screen->width = width - 36 dest <- get screen, width - 37 tmp <- copy width - 38 copy-to *dest, tmp - 39 # screen->height = height - 40 dest <- get screen, height - 41 tmp <- copy height - 42 copy-to *dest, tmp - 43 # populate screen->data - 44 { - 45 var data-ah/edi: (addr handle array screen-cell) <- get screen, data - 46 var capacity/eax: int <- copy width - 47 capacity <- multiply height - 48 populate data-ah, capacity - 49 } - 50 # if necessary, populate screen->pixels - 51 { - 52 compare pixel-graphics?, 0/false - 53 break-if-= - 54 var pixels-ah/edi: (addr handle array byte) <- get screen, pixels - 55 var capacity/eax: int <- copy width - 56 capacity <- shift-left 3/log2-font-width - 57 capacity <- multiply height - 58 capacity <- shift-left 4/log2-font-height - 59 populate pixels-ah, capacity - 60 } - 61 # screen->cursor-x = 0 - 62 dest <- get screen, cursor-x - 63 copy-to *dest, 0 - 64 # screen->cursor-y = 0 - 65 dest <- get screen, cursor-y - 66 copy-to *dest, 0 - 67 } - 68 - 69 # in graphemes - 70 fn screen-size _screen: (addr screen) -> _/eax: int, _/ecx: int { - 71 var screen/esi: (addr screen) <- copy _screen - 72 var width/eax: int <- copy 0 - 73 var height/ecx: int <- copy 0 - 74 compare screen, 0 - 75 { - 76 break-if-!= - 77 return 0x80/128, 0x30/48 - 78 } - 79 # fake screen - 80 var tmp/edx: (addr int) <- get screen, width - 81 width <- copy *tmp - 82 tmp <- get screen, height - 83 height <- copy *tmp - 84 return width, height - 85 } - 86 - 87 # testable screen primitive - 88 fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int { - 89 var screen/esi: (addr screen) <- copy _screen - 90 { - 91 compare screen, 0 + 21 invalid-cell-index: int + 22 # pixel graphics + 23 pixels: (handle array byte) + 24 invalid-pixel-index: int + 25 } + 26 + 27 type screen-cell { + 28 data: grapheme + 29 color: int + 30 background-color: int + 31 } + 32 + 33 fn initialize-screen _screen: (addr screen), width: int, height: int, pixel-graphics?: boolean { + 34 var screen/esi: (addr screen) <- copy _screen + 35 var tmp/eax: int <- copy 0 + 36 var dest/edi: (addr int) <- copy 0 + 37 # screen->width = width + 38 dest <- get screen, width + 39 tmp <- copy width + 40 copy-to *dest, tmp + 41 # screen->height = height + 42 dest <- get screen, height + 43 tmp <- copy height + 44 copy-to *dest, tmp + 45 # populate screen->data + 46 { + 47 var data-ah/edi: (addr handle array screen-cell) <- get screen, data + 48 var capacity/eax: int <- copy width + 49 capacity <- multiply height + 50 # add 1 for sentinel + 51 capacity <- increment + 52 # + 53 populate data-ah, capacity + 54 # save sentinel index + 55 capacity <- decrement + 56 var dest/ecx: (addr int) <- get screen, invalid-cell-index + 57 copy-to *dest, capacity + 58 } + 59 # if necessary, populate screen->pixels + 60 { + 61 compare pixel-graphics?, 0/false + 62 break-if-= + 63 var pixels-ah/edi: (addr handle array byte) <- get screen, pixels + 64 var capacity/eax: int <- copy width + 65 capacity <- shift-left 3/log2-font-width + 66 capacity <- multiply height + 67 capacity <- shift-left 4/log2-font-height + 68 # add 1 for sentinel + 69 capacity <- increment + 70 # + 71 populate pixels-ah, capacity + 72 # save sentinel index + 73 capacity <- decrement + 74 var dest/ecx: (addr int) <- get screen, invalid-pixel-index + 75 copy-to *dest, capacity + 76 } + 77 # screen->cursor-x = 0 + 78 dest <- get screen, cursor-x + 79 copy-to *dest, 0 + 80 # screen->cursor-y = 0 + 81 dest <- get screen, cursor-y + 82 copy-to *dest, 0 + 83 } + 84 + 85 # in graphemes + 86 fn screen-size _screen: (addr screen) -> _/eax: int, _/ecx: int { + 87 var screen/esi: (addr screen) <- copy _screen + 88 var width/eax: int <- copy 0 + 89 var height/ecx: int <- copy 0 + 90 compare screen, 0 + 91 { 92 break-if-!= - 93 draw-grapheme-on-real-screen g, x, y, color, background-color - 94 return - 95 } - 96 # fake screen - 97 var idx/ecx: int <- screen-cell-index screen, x, y - 98 var data-ah/eax: (addr handle array screen-cell) <- get screen, data - 99 var data/eax: (addr array screen-cell) <- lookup *data-ah -100 var offset/ecx: (offset screen-cell) <- compute-offset data, idx -101 var dest-cell/ecx: (addr screen-cell) <- index data, offset -102 var dest-grapheme/eax: (addr grapheme) <- get dest-cell, data -103 var g2/edx: grapheme <- copy g -104 copy-to *dest-grapheme, g2 -105 var dest-color/eax: (addr int) <- get dest-cell, color -106 var src-color/edx: int <- copy color -107 copy-to *dest-color, src-color -108 dest-color <- get dest-cell, background-color -109 src-color <- copy background-color -110 copy-to *dest-color, src-color -111 } -112 -113 # we can't really render non-ASCII yet, but when we do we'll be ready -114 fn draw-code-point screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int { -115 var g/eax: grapheme <- copy c -116 draw-grapheme screen, g, x, y, color, background-color -117 } -118 -119 # fake screens only -120 fn screen-cell-index _screen: (addr screen), x: int, y: int -> _/ecx: int { -121 var screen/esi: (addr screen) <- copy _screen -122 # some bounds checks that aren't needed for a real screen, but might help catch problems -123 { -124 compare x, 0 -125 break-if->= -126 abort "screen-cell-index: negative x" -127 } -128 { -129 var xmax/eax: (addr int) <- get screen, width -130 var xcurr/ecx: int <- copy x -131 compare xcurr, *xmax -132 break-if-< -133 abort "screen-cell-index: x too high" -134 } -135 { -136 compare y, 0 -137 break-if->= -138 abort "screen-cell-index: negative y" -139 } -140 { -141 var ymax/eax: (addr int) <- get screen, height -142 var ycurr/ecx: int <- copy y -143 compare ycurr, *ymax -144 break-if-< -145 abort "screen-cell-index: y too high" -146 } -147 var width-addr/eax: (addr int) <- get screen, width -148 var result/ecx: int <- copy y -149 result <- multiply *width-addr -150 result <- add x -151 return result -152 } -153 -154 fn cursor-position _screen: (addr screen) -> _/eax: int, _/ecx: int { -155 var screen/esi: (addr screen) <- copy _screen -156 { -157 compare screen, 0 -158 break-if-!= -159 var x/eax: int <- copy 0 -160 var y/ecx: int <- copy 0 -161 x, y <- cursor-position-on-real-screen -162 return x, y -163 } -164 # fake screen -165 var cursor-x-addr/eax: (addr int) <- get screen, cursor-x -166 var cursor-y-addr/ecx: (addr int) <- get screen, cursor-y -167 return *cursor-x-addr, *cursor-y-addr -168 } -169 -170 fn set-cursor-position _screen: (addr screen), x: int, y: int { -171 var screen/esi: (addr screen) <- copy _screen -172 { -173 compare screen, 0 -174 break-if-!= -175 set-cursor-position-on-real-screen x, y -176 return -177 } -178 # fake screen -179 # ignore x < 0 -180 { -181 compare x, 0 -182 break-if->= -183 return -184 } -185 # ignore x >= width -186 { -187 var width-addr/eax: (addr int) <- get screen, width -188 var width/eax: int <- copy *width-addr -189 compare x, width -190 break-if-<= -191 return -192 } -193 # ignore y < 0 -194 { -195 compare y, 0 -196 break-if->= -197 return -198 } -199 # ignore y >= height + 93 return 0x80/128, 0x30/48 + 94 } + 95 # fake screen + 96 var tmp/edx: (addr int) <- get screen, width + 97 width <- copy *tmp + 98 tmp <- get screen, height + 99 height <- copy *tmp +100 return width, height +101 } +102 +103 # testable screen primitive +104 fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int { +105 var screen/esi: (addr screen) <- copy _screen +106 { +107 compare screen, 0 +108 break-if-!= +109 draw-grapheme-on-real-screen g, x, y, color, background-color +110 return +111 } +112 # fake screen +113 var idx/ecx: int <- screen-cell-index screen, x, y +114 var data-ah/eax: (addr handle array screen-cell) <- get screen, data +115 var data/eax: (addr array screen-cell) <- lookup *data-ah +116 var offset/ecx: (offset screen-cell) <- compute-offset data, idx +117 var dest-cell/ecx: (addr screen-cell) <- index data, offset +118 var dest-grapheme/eax: (addr grapheme) <- get dest-cell, data +119 var g2/edx: grapheme <- copy g +120 copy-to *dest-grapheme, g2 +121 var dest-color/eax: (addr int) <- get dest-cell, color +122 var src-color/edx: int <- copy color +123 copy-to *dest-color, src-color +124 dest-color <- get dest-cell, background-color +125 src-color <- copy background-color +126 copy-to *dest-color, src-color +127 } +128 +129 # we can't really render non-ASCII yet, but when we do we'll be ready +130 fn draw-code-point screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int { +131 var g/eax: grapheme <- copy c +132 draw-grapheme screen, g, x, y, color, background-color +133 } +134 +135 # fake screens only +136 fn screen-cell-index _screen: (addr screen), x: int, y: int -> _/ecx: int { +137 var screen/esi: (addr screen) <- copy _screen +138 # if out of bounds, silently return a pixel that's never checked +139 { +140 compare x, 0 +141 break-if->= +142 var invalid/eax: (addr int) <- get screen, invalid-cell-index +143 return *invalid +144 } +145 { +146 var xmax/eax: (addr int) <- get screen, width +147 var xcurr/ecx: int <- copy x +148 compare xcurr, *xmax +149 break-if-< +150 var invalid/eax: (addr int) <- get screen, invalid-cell-index +151 return *invalid +152 } +153 { +154 compare y, 0 +155 break-if->= +156 var invalid/eax: (addr int) <- get screen, invalid-cell-index +157 return *invalid +158 } +159 { +160 var ymax/eax: (addr int) <- get screen, height +161 var ycurr/ecx: int <- copy y +162 compare ycurr, *ymax +163 break-if-< +164 var invalid/eax: (addr int) <- get screen, invalid-cell-index +165 return *invalid +166 } +167 var width-addr/eax: (addr int) <- get screen, width +168 var result/ecx: int <- copy y +169 result <- multiply *width-addr +170 result <- add x +171 return result +172 } +173 +174 fn cursor-position _screen: (addr screen) -> _/eax: int, _/ecx: int { +175 var screen/esi: (addr screen) <- copy _screen +176 { +177 compare screen, 0 +178 break-if-!= +179 var x/eax: int <- copy 0 +180 var y/ecx: int <- copy 0 +181 x, y <- cursor-position-on-real-screen +182 return x, y +183 } +184 # fake screen +185 var cursor-x-addr/eax: (addr int) <- get screen, cursor-x +186 var cursor-y-addr/ecx: (addr int) <- get screen, cursor-y +187 return *cursor-x-addr, *cursor-y-addr +188 } +189 +190 fn set-cursor-position _screen: (addr screen), x: int, y: int { +191 var screen/esi: (addr screen) <- copy _screen +192 { +193 compare screen, 0 +194 break-if-!= +195 set-cursor-position-on-real-screen x, y +196 return +197 } +198 # fake screen +199 # ignore x < 0 200 { -201 var height-addr/eax: (addr int) <- get screen, height -202 var height/eax: int <- copy *height-addr -203 compare y, height -204 break-if-< -205 return -206 } -207 # screen->cursor-x = x -208 var dest/edi: (addr int) <- get screen, cursor-x -209 var src/eax: int <- copy x -210 copy-to *dest, src -211 # screen->cursor-y = y -212 dest <- get screen, cursor-y -213 src <- copy y -214 copy-to *dest, src -215 } -216 -217 fn draw-cursor screen: (addr screen), g: grapheme { -218 { -219 compare screen, 0 -220 break-if-!= -221 draw-cursor-on-real-screen g -222 return -223 } -224 # fake screen -225 var cursor-x/eax: int <- copy 0 -226 var cursor-y/ecx: int <- copy 0 -227 cursor-x, cursor-y <- cursor-position screen -228 draw-grapheme screen, g, cursor-x, cursor-y, 0/fg, 7/bg -229 } -230 -231 fn clear-screen _screen: (addr screen) { -232 var screen/esi: (addr screen) <- copy _screen -233 { -234 compare screen, 0 -235 break-if-!= -236 clear-real-screen -237 return -238 } -239 # fake screen -240 set-cursor-position screen, 0, 0 -241 var y/eax: int <- copy 0 -242 var height/ecx: (addr int) <- get screen, height -243 { -244 compare y, *height -245 break-if->= -246 var x/edx: int <- copy 0 -247 var width/ebx: (addr int) <- get screen, width -248 { -249 compare x, *width -250 break-if->= -251 draw-code-point screen, 0x20/space, x, y, 0/fg=black, 0/bg=black -252 x <- increment -253 loop -254 } -255 y <- increment -256 loop -257 } -258 set-cursor-position screen, 0, 0 -259 var pixels-ah/eax: (addr handle array byte) <- get screen, pixels -260 var pixels/eax: (addr array byte) <- lookup *pixels-ah -261 var i/ecx: int <- copy 0 -262 var max/edx: int <- length pixels +201 compare x, 0 +202 break-if->= +203 return +204 } +205 # ignore x >= width +206 { +207 var width-addr/eax: (addr int) <- get screen, width +208 var width/eax: int <- copy *width-addr +209 compare x, width +210 break-if-<= +211 return +212 } +213 # ignore y < 0 +214 { +215 compare y, 0 +216 break-if->= +217 return +218 } +219 # ignore y >= height +220 { +221 var height-addr/eax: (addr int) <- get screen, height +222 var height/eax: int <- copy *height-addr +223 compare y, height +224 break-if-< +225 return +226 } +227 # screen->cursor-x = x +228 var dest/edi: (addr int) <- get screen, cursor-x +229 var src/eax: int <- copy x +230 copy-to *dest, src +231 # screen->cursor-y = y +232 dest <- get screen, cursor-y +233 src <- copy y +234 copy-to *dest, src +235 } +236 +237 fn draw-cursor screen: (addr screen), g: grapheme { +238 { +239 compare screen, 0 +240 break-if-!= +241 draw-cursor-on-real-screen g +242 return +243 } +244 # fake screen +245 var cursor-x/eax: int <- copy 0 +246 var cursor-y/ecx: int <- copy 0 +247 cursor-x, cursor-y <- cursor-position screen +248 draw-grapheme screen, g, cursor-x, cursor-y, 0/fg, 7/bg +249 } +250 +251 fn clear-screen _screen: (addr screen) { +252 var screen/esi: (addr screen) <- copy _screen +253 { +254 compare screen, 0 +255 break-if-!= +256 clear-real-screen +257 return +258 } +259 # fake screen +260 set-cursor-position screen, 0, 0 +261 var y/eax: int <- copy 0 +262 var height/ecx: (addr int) <- get screen, height 263 { -264 compare i, max +264 compare y, *height 265 break-if->= -266 var curr/eax: (addr byte) <- index pixels, i -267 var zero/ebx: byte <- copy 0 -268 copy-byte-to *curr, zero -269 i <- increment -270 loop -271 } -272 } -273 -274 fn fake-screen-empty? _screen: (addr screen) -> _/eax: boolean { -275 var screen/esi: (addr screen) <- copy _screen -276 var y/eax: int <- copy 0 -277 var height/ecx: (addr int) <- get screen, height -278 { -279 compare y, *height -280 break-if->= -281 var x/edx: int <- copy 0 -282 var width/ebx: (addr int) <- get screen, width -283 { -284 compare x, *width -285 break-if->= -286 var g/eax: grapheme <- screen-grapheme-at screen, x, y -287 { -288 compare g, 0 -289 break-if-= -290 compare g, 0x20/space -291 break-if-= -292 return 0/false -293 } -294 x <- increment -295 loop -296 } -297 y <- increment -298 loop -299 } -300 var pixels-ah/eax: (addr handle array byte) <- get screen, pixels -301 var pixels/eax: (addr array byte) <- lookup *pixels-ah -302 var y/ebx: int <- copy 0 -303 var height-addr/edx: (addr int) <- get screen, height -304 var height/edx: int <- copy *height-addr -305 height <- shift-left 4/log2-font-height -306 { -307 compare y, height -308 break-if->= -309 var width-addr/edx: (addr int) <- get screen, width -310 var width/edx: int <- copy *width-addr -311 width <- shift-left 3/log2-font-width -312 var x/edi: int <- copy 0 -313 { -314 compare x, width -315 break-if->= -316 var idx/ecx: int <- pixel-index screen, x, y -317 var color-addr/ecx: (addr byte) <- index pixels, idx -318 var color/ecx: byte <- copy-byte *color-addr -319 compare color, 0 -320 { -321 break-if-= -322 return 0/false -323 } -324 x <- increment -325 loop -326 } -327 y <- increment -328 loop -329 } -330 return 1/true -331 } -332 -333 fn clear-rect _screen: (addr screen), xmin: int, ymin: int, xmax: int, ymax: int, background-color: int { -334 var screen/esi: (addr screen) <- copy _screen -335 { -336 compare screen, 0 -337 break-if-!= -338 clear-rect-on-real-screen xmin, ymin, xmax, ymax, background-color -339 return -340 } -341 # fake screen -342 set-cursor-position screen, 0, 0 -343 var y/eax: int <- copy ymin -344 var ymax/ecx: int <- copy ymax -345 { -346 compare y, ymax -347 break-if->= -348 var x/edx: int <- copy xmin -349 var xmax/ebx: int <- copy xmax -350 { -351 compare x, xmax -352 break-if->= -353 draw-code-point screen, 0x20/space, x, y, 0/fg, background-color -354 x <- increment -355 loop -356 } -357 y <- increment -358 loop -359 } -360 set-cursor-position screen, 0, 0 -361 } -362 -363 # there's no grapheme that guarantees to cover every pixel, so we'll bump down -364 # to pixels for a real screen -365 fn clear-real-screen { -366 var y/eax: int <- copy 0 -367 { -368 compare y, 0x300/screen-height=768 -369 break-if->= -370 var x/edx: int <- copy 0 -371 { -372 compare x, 0x400/screen-width=1024 -373 break-if->= -374 pixel-on-real-screen x, y, 0/color=black -375 x <- increment -376 loop -377 } -378 y <- increment -379 loop -380 } +266 var x/edx: int <- copy 0 +267 var width/ebx: (addr int) <- get screen, width +268 { +269 compare x, *width +270 break-if->= +271 draw-code-point screen, 0/nul, x, y, 0/fg=black, 0/bg=black +272 x <- increment +273 loop +274 } +275 y <- increment +276 loop +277 } +278 set-cursor-position screen, 0, 0 +279 var pixels-ah/eax: (addr handle array byte) <- get screen, pixels +280 var pixels/eax: (addr array byte) <- lookup *pixels-ah +281 var i/ecx: int <- copy 0 +282 var max/edx: int <- length pixels +283 { +284 compare i, max +285 break-if->= +286 var curr/eax: (addr byte) <- index pixels, i +287 var zero/ebx: byte <- copy 0 +288 copy-byte-to *curr, zero +289 i <- increment +290 loop +291 } +292 } +293 +294 fn fake-screen-empty? _screen: (addr screen) -> _/eax: boolean { +295 var screen/esi: (addr screen) <- copy _screen +296 var y/eax: int <- copy 0 +297 var height/ecx: (addr int) <- get screen, height +298 { +299 compare y, *height +300 break-if->= +301 var x/edx: int <- copy 0 +302 var width/ebx: (addr int) <- get screen, width +303 { +304 compare x, *width +305 break-if->= +306 var g/eax: grapheme <- screen-grapheme-at screen, x, y +307 { +308 compare g, 0 +309 break-if-= +310 compare g, 0x20/space +311 break-if-= +312 return 0/false +313 } +314 x <- increment +315 loop +316 } +317 y <- increment +318 loop +319 } +320 var pixels-ah/eax: (addr handle array byte) <- get screen, pixels +321 var pixels/eax: (addr array byte) <- lookup *pixels-ah +322 var y/ebx: int <- copy 0 +323 var height-addr/edx: (addr int) <- get screen, height +324 var height/edx: int <- copy *height-addr +325 height <- shift-left 4/log2-font-height +326 { +327 compare y, height +328 break-if->= +329 var width-addr/edx: (addr int) <- get screen, width +330 var width/edx: int <- copy *width-addr +331 width <- shift-left 3/log2-font-width +332 var x/edi: int <- copy 0 +333 { +334 compare x, width +335 break-if->= +336 var idx/ecx: int <- pixel-index screen, x, y +337 var color-addr/ecx: (addr byte) <- index pixels, idx +338 var color/ecx: byte <- copy-byte *color-addr +339 compare color, 0 +340 { +341 break-if-= +342 return 0/false +343 } +344 x <- increment +345 loop +346 } +347 y <- increment +348 loop +349 } +350 return 1/true +351 } +352 +353 fn clear-rect _screen: (addr screen), xmin: int, ymin: int, xmax: int, ymax: int, background-color: int { +354 var screen/esi: (addr screen) <- copy _screen +355 { +356 compare screen, 0 +357 break-if-!= +358 clear-rect-on-real-screen xmin, ymin, xmax, ymax, background-color +359 return +360 } +361 # fake screen +362 set-cursor-position screen, 0, 0 +363 var y/eax: int <- copy ymin +364 var ymax/ecx: int <- copy ymax +365 { +366 compare y, ymax +367 break-if->= +368 var x/edx: int <- copy xmin +369 var xmax/ebx: int <- copy xmax +370 { +371 compare x, xmax +372 break-if->= +373 draw-code-point screen, 0x20/space, x, y, 0/fg, background-color +374 x <- increment +375 loop +376 } +377 y <- increment +378 loop +379 } +380 set-cursor-position screen, 0, 0 381 } 382 -383 fn clear-rect-on-real-screen xmin: int, ymin: int, xmax: int, ymax: int, background-color: int { -384 var y/eax: int <- copy ymin -385 y <- shift-left 4/log2-font-height -386 var ymax/ecx: int <- copy ymax -387 ymax <- shift-left 4/log2-font-height -388 { -389 compare y, ymax -390 break-if->= -391 var x/edx: int <- copy xmin -392 x <- shift-left 3/log2-font-width -393 var xmax/ebx: int <- copy xmax -394 xmax <- shift-left 3/log2-font-width -395 { -396 compare x, xmax -397 break-if->= -398 pixel-on-real-screen x, y, background-color -399 x <- increment -400 loop -401 } -402 y <- increment -403 loop -404 } -405 } -406 -407 fn screen-grapheme-at _screen: (addr screen), x: int, y: int -> _/eax: grapheme { -408 var screen/esi: (addr screen) <- copy _screen -409 var idx/ecx: int <- screen-cell-index screen, x, y -410 var result/eax: grapheme <- screen-grapheme-at-idx screen, idx -411 return result -412 } -413 -414 fn screen-grapheme-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: grapheme { -415 var screen/esi: (addr screen) <- copy _screen -416 var data-ah/eax: (addr handle array screen-cell) <- get screen, data -417 var data/eax: (addr array screen-cell) <- lookup *data-ah -418 var idx/ecx: int <- copy idx-on-stack -419 var offset/ecx: (offset screen-cell) <- compute-offset data, idx -420 var cell/eax: (addr screen-cell) <- index data, offset -421 var src/eax: (addr grapheme) <- get cell, data -422 return *src -423 } -424 -425 fn screen-color-at _screen: (addr screen), x: int, y: int -> _/eax: int { -426 var screen/esi: (addr screen) <- copy _screen -427 var idx/ecx: int <- screen-cell-index screen, x, y -428 var result/eax: int <- screen-color-at-idx screen, idx -429 return result -430 } -431 -432 fn screen-color-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: int { -433 var screen/esi: (addr screen) <- copy _screen -434 var data-ah/eax: (addr handle array screen-cell) <- get screen, data -435 var data/eax: (addr array screen-cell) <- lookup *data-ah -436 var idx/ecx: int <- copy idx-on-stack -437 var offset/ecx: (offset screen-cell) <- compute-offset data, idx -438 var cell/eax: (addr screen-cell) <- index data, offset -439 var src/eax: (addr int) <- get cell, color -440 var result/eax: int <- copy *src -441 return result -442 } -443 -444 fn screen-background-color-at _screen: (addr screen), x: int, y: int -> _/eax: int { -445 var screen/esi: (addr screen) <- copy _screen -446 var idx/ecx: int <- screen-cell-index screen, x, y -447 var result/eax: int <- screen-background-color-at-idx screen, idx -448 return result -449 } -450 -451 fn screen-background-color-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: int { -452 var screen/esi: (addr screen) <- copy _screen -453 var data-ah/eax: (addr handle array screen-cell) <- get screen, data -454 var data/eax: (addr array screen-cell) <- lookup *data-ah -455 var idx/ecx: int <- copy idx-on-stack -456 var offset/ecx: (offset screen-cell) <- compute-offset data, idx -457 var cell/eax: (addr screen-cell) <- index data, offset -458 var src/eax: (addr int) <- get cell, background-color -459 var result/eax: int <- copy *src -460 return result -461 } -462 -463 fn pixel screen: (addr screen), x: int, y: int, color: int { -464 { -465 compare screen, 0 -466 break-if-!= -467 pixel-on-real-screen x, y, color -468 return -469 } -470 # fake screen -471 var screen/esi: (addr screen) <- copy screen -472 var pixels-ah/eax: (addr handle array byte) <- get screen, pixels -473 var pixels/eax: (addr array byte) <- lookup *pixels-ah -474 { -475 compare pixels, 0 -476 break-if-!= -477 abort "pixel graphics not enabled for this screen" -478 } -479 var idx/ecx: int <- pixel-index screen, x, y -480 var dest/ecx: (addr byte) <- index pixels, idx -481 var src/eax: byte <- copy-byte color -482 copy-byte-to *dest, src -483 } -484 -485 fn pixel-index _screen: (addr screen), x: int, y: int -> _/ecx: int { -486 var screen/esi: (addr screen) <- copy _screen -487 { -488 compare x, 0 -489 break-if->= -490 abort "screen-cell-index: negative x" -491 } -492 { -493 var xmax-a/eax: (addr int) <- get screen, width -494 var xmax/eax: int <- copy *xmax-a -495 xmax <- shift-left 3/log2-font-width -496 compare x, xmax -497 break-if-< -498 abort "screen-cell-index: x too high" -499 } -500 { -501 compare y, 0 -502 break-if->= -503 abort "screen-cell-index: negative y" -504 } -505 { -506 var ymax-a/eax: (addr int) <- get screen, height -507 var ymax/eax: int <- copy *ymax-a -508 ymax <- shift-left 4/log2-font-height -509 compare y, ymax -510 break-if-< -511 abort "screen-cell-index: y too high" +383 # there's no grapheme that guarantees to cover every pixel, so we'll bump down +384 # to pixels for a real screen +385 fn clear-real-screen { +386 var y/eax: int <- copy 0 +387 { +388 compare y, 0x300/screen-height=768 +389 break-if->= +390 var x/edx: int <- copy 0 +391 { +392 compare x, 0x400/screen-width=1024 +393 break-if->= +394 pixel-on-real-screen x, y, 0/color=black +395 x <- increment +396 loop +397 } +398 y <- increment +399 loop +400 } +401 } +402 +403 fn clear-rect-on-real-screen xmin: int, ymin: int, xmax: int, ymax: int, background-color: int { +404 var y/eax: int <- copy ymin +405 y <- shift-left 4/log2-font-height +406 var ymax/ecx: int <- copy ymax +407 ymax <- shift-left 4/log2-font-height +408 { +409 compare y, ymax +410 break-if->= +411 var x/edx: int <- copy xmin +412 x <- shift-left 3/log2-font-width +413 var xmax/ebx: int <- copy xmax +414 xmax <- shift-left 3/log2-font-width +415 { +416 compare x, xmax +417 break-if->= +418 pixel-on-real-screen x, y, background-color +419 x <- increment +420 loop +421 } +422 y <- increment +423 loop +424 } +425 } +426 +427 fn screen-grapheme-at _screen: (addr screen), x: int, y: int -> _/eax: grapheme { +428 var screen/esi: (addr screen) <- copy _screen +429 var idx/ecx: int <- screen-cell-index screen, x, y +430 var result/eax: grapheme <- screen-grapheme-at-idx screen, idx +431 return result +432 } +433 +434 fn screen-grapheme-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: grapheme { +435 var screen/esi: (addr screen) <- copy _screen +436 var data-ah/eax: (addr handle array screen-cell) <- get screen, data +437 var data/eax: (addr array screen-cell) <- lookup *data-ah +438 var idx/ecx: int <- copy idx-on-stack +439 var offset/ecx: (offset screen-cell) <- compute-offset data, idx +440 var cell/eax: (addr screen-cell) <- index data, offset +441 var src/eax: (addr grapheme) <- get cell, data +442 return *src +443 } +444 +445 fn screen-color-at _screen: (addr screen), x: int, y: int -> _/eax: int { +446 var screen/esi: (addr screen) <- copy _screen +447 var idx/ecx: int <- screen-cell-index screen, x, y +448 var result/eax: int <- screen-color-at-idx screen, idx +449 return result +450 } +451 +452 fn screen-color-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: int { +453 var screen/esi: (addr screen) <- copy _screen +454 var data-ah/eax: (addr handle array screen-cell) <- get screen, data +455 var data/eax: (addr array screen-cell) <- lookup *data-ah +456 var idx/ecx: int <- copy idx-on-stack +457 var offset/ecx: (offset screen-cell) <- compute-offset data, idx +458 var cell/eax: (addr screen-cell) <- index data, offset +459 var src/eax: (addr int) <- get cell, color +460 var result/eax: int <- copy *src +461 return result +462 } +463 +464 fn screen-background-color-at _screen: (addr screen), x: int, y: int -> _/eax: int { +465 var screen/esi: (addr screen) <- copy _screen +466 var idx/ecx: int <- screen-cell-index screen, x, y +467 var result/eax: int <- screen-background-color-at-idx screen, idx +468 return result +469 } +470 +471 fn screen-background-color-at-idx _screen: (addr screen), idx-on-stack: int -> _/eax: int { +472 var screen/esi: (addr screen) <- copy _screen +473 var data-ah/eax: (addr handle array screen-cell) <- get screen, data +474 var data/eax: (addr array screen-cell) <- lookup *data-ah +475 var idx/ecx: int <- copy idx-on-stack +476 var offset/ecx: (offset screen-cell) <- compute-offset data, idx +477 var cell/eax: (addr screen-cell) <- index data, offset +478 var src/eax: (addr int) <- get cell, background-color +479 var result/eax: int <- copy *src +480 return result +481 } +482 +483 fn pixel screen: (addr screen), x: int, y: int, color: int { +484 { +485 compare screen, 0 +486 break-if-!= +487 pixel-on-real-screen x, y, color +488 return +489 } +490 # fake screen +491 var screen/esi: (addr screen) <- copy screen +492 var pixels-ah/eax: (addr handle array byte) <- get screen, pixels +493 var pixels/eax: (addr array byte) <- lookup *pixels-ah +494 { +495 compare pixels, 0 +496 break-if-!= +497 abort "pixel graphics not enabled for this screen" +498 } +499 var idx/ecx: int <- pixel-index screen, x, y +500 var dest/ecx: (addr byte) <- index pixels, idx +501 var src/eax: byte <- copy-byte color +502 copy-byte-to *dest, src +503 } +504 +505 fn pixel-index _screen: (addr screen), x: int, y: int -> _/ecx: int { +506 var screen/esi: (addr screen) <- copy _screen +507 { +508 compare x, 0 +509 break-if->= +510 var invalid/eax: (addr int) <- get screen, invalid-pixel-index +511 return *invalid 512 } -513 var width-addr/eax: (addr int) <- get screen, width -514 var result/ecx: int <- copy y -515 result <- multiply *width-addr -516 result <- shift-left 3/log2-font-width -517 result <- add x -518 return result -519 } -520 -521 # double-buffering primitive -522 # 'screen' must be a fake screen. 'target-screen' is usually real. -523 # Both screens must have the same size. -524 fn copy-pixels _screen: (addr screen), target-screen: (addr screen) { -525 var screen/esi: (addr screen) <- copy _screen -526 var pixels-ah/eax: (addr handle array byte) <- get screen, pixels -527 var _pixels/eax: (addr array byte) <- lookup *pixels-ah -528 var pixels/edi: (addr array byte) <- copy _pixels -529 var width-a/edx: (addr int) <- get screen, width -530 var width/edx: int <- copy *width-a -531 width <- shift-left 3/log2-font-width -532 var height-a/ebx: (addr int) <- get screen, height -533 var height/ebx: int <- copy *height-a -534 height <- shift-left 4/log2-font-height -535 var i/esi: int <- copy 0 -536 var y/ecx: int <- copy 0 -537 { -538 # screen top left pixels x y width height -539 compare y, height -540 break-if->= -541 var x/eax: int <- copy 0 -542 { -543 compare x, width -544 break-if->= -545 { -546 var color-addr/ebx: (addr byte) <- index pixels, i -547 var color/ebx: byte <- copy-byte *color-addr -548 var color2/ebx: int <- copy color -549 pixel target-screen, x, y, color2 -550 } -551 x <- increment -552 i <- increment -553 loop -554 } -555 y <- increment -556 loop -557 } -558 } +513 { +514 var xmax-a/eax: (addr int) <- get screen, width +515 var xmax/eax: int <- copy *xmax-a +516 xmax <- shift-left 3/log2-font-width +517 compare x, xmax +518 break-if-< +519 var invalid/eax: (addr int) <- get screen, invalid-pixel-index +520 return *invalid +521 } +522 { +523 compare y, 0 +524 break-if->= +525 var invalid/eax: (addr int) <- get screen, invalid-pixel-index +526 return *invalid +527 } +528 { +529 var ymax-a/eax: (addr int) <- get screen, height +530 var ymax/eax: int <- copy *ymax-a +531 ymax <- shift-left 4/log2-font-height +532 compare y, ymax +533 break-if-< +534 var invalid/eax: (addr int) <- get screen, invalid-pixel-index +535 return *invalid +536 } +537 var width-addr/eax: (addr int) <- get screen, width +538 var result/ecx: int <- copy y +539 result <- multiply *width-addr +540 result <- shift-left 3/log2-font-width +541 result <- add x +542 return result +543 } +544 +545 # double-buffering primitive +546 # 'screen' must be a fake screen. 'target-screen' is usually real. +547 # Both screens must have the same size. +548 fn copy-pixels _screen: (addr screen), target-screen: (addr screen) { +549 var screen/esi: (addr screen) <- copy _screen +550 var pixels-ah/eax: (addr handle array byte) <- get screen, pixels +551 var _pixels/eax: (addr array byte) <- lookup *pixels-ah +552 var pixels/edi: (addr array byte) <- copy _pixels +553 var width-a/edx: (addr int) <- get screen, width +554 var width/edx: int <- copy *width-a +555 width <- shift-left 3/log2-font-width +556 var height-a/ebx: (addr int) <- get screen, height +557 var height/ebx: int <- copy *height-a +558 height <- shift-left 4/log2-font-height +559 var i/esi: int <- copy 0 +560 var y/ecx: int <- copy 0 +561 { +562 # screen top left pixels x y width height +563 compare y, height +564 break-if->= +565 var x/eax: int <- copy 0 +566 { +567 compare x, width +568 break-if->= +569 { +570 var color-addr/ebx: (addr byte) <- index pixels, i +571 var color/ebx: byte <- copy-byte *color-addr +572 var color2/ebx: int <- copy color +573 pixel target-screen, x, y, color2 +574 } +575 x <- increment +576 i <- increment +577 loop +578 } +579 y <- increment +580 loop +581 } +582 } +583 +584 # It turns out double-buffering graphemes is useless because rendering fonts +585 # takes too long. (At least under Qemu.) +586 # So we'll instead convert graphemes to pixels when double-buffering. +587 # 'screen' must be a fake screen. +588 fn convert-graphemes-to-pixels _screen: (addr screen) { +589 var screen/esi: (addr screen) <- copy _screen +590 var width-a/ebx: (addr int) <- get screen, width +591 var height-a/edx: (addr int) <- get screen, height +592 var data-ah/eax: (addr handle array byte) <- get screen, pixels +593 var _data/eax: (addr array byte) <- lookup *data-ah +594 var data: (addr array byte) +595 copy-to data, _data +596 var y/ecx: int <- copy 0 +597 { +598 compare y, *height-a +599 break-if->= +600 var x/edi: int <- copy 0 +601 { +602 compare x, *width-a +603 break-if->= +604 { +605 var tmp/eax: grapheme <- screen-grapheme-at screen, x, y +606 # skip null graphemes that only get created when clearing screen +607 # there may be other pixels drawn there, and we don't want to clobber them +608 # this is a situation where fake screens aren't faithful to real screens; we don't support overlap between graphemes and raw pixels +609 compare tmp, 0 +610 break-if-= +611 var g: grapheme +612 copy-to g, tmp +613 var tmp/eax: int <- screen-color-at screen, x, y +614 var fg: int +615 copy-to fg, tmp +616 var bg/eax: int <- screen-background-color-at screen, x, y +617 draw-grapheme-on-screen-array data, g, x, y, fg, bg, *width-a, *height-a +618 } +619 x <- increment +620 loop +621 } +622 y <- increment +623 loop +624 } +625 } diff --git a/html/501draw-text.mu.html b/html/501draw-text.mu.html index 547c338c..11748c33 100644 --- a/html/501draw-text.mu.html +++ b/html/501draw-text.mu.html @@ -15,9 +15,15 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } +.muRegEdi { color: #87ffd7; } +.muRegEbx { color: #8787af; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -59,76 +65,76 @@ if ('onhashchange' in window) { 1 # some primitives for moving the cursor without making assumptions about 2 # raster order 3 fn move-cursor-left screen: (addr screen) { - 4 var cursor-x/eax: int <- copy 0 - 5 var cursor-y/ecx: int <- copy 0 - 6 cursor-x, cursor-y <- cursor-position screen + 4 var cursor-x/eax: int <- copy 0 + 5 var cursor-y/ecx: int <- copy 0 + 6 cursor-x, cursor-y <- cursor-position screen 7 compare cursor-x, 0 8 { 9 break-if-> 10 return 11 } 12 cursor-x <- decrement - 13 set-cursor-position screen, cursor-x, cursor-y + 13 set-cursor-position screen, cursor-x, cursor-y 14 } 15 16 fn move-cursor-right screen: (addr screen) { - 17 var _width/eax: int <- copy 0 - 18 var dummy/ecx: int <- copy 0 - 19 _width, dummy <- screen-size screen - 20 var limit/edx: int <- copy _width + 17 var _width/eax: int <- copy 0 + 18 var dummy/ecx: int <- copy 0 + 19 _width, dummy <- screen-size screen + 20 var limit/edx: int <- copy _width 21 limit <- decrement - 22 var cursor-x/eax: int <- copy 0 - 23 var cursor-y/ecx: int <- copy 0 - 24 cursor-x, cursor-y <- cursor-position screen + 22 var cursor-x/eax: int <- copy 0 + 23 var cursor-y/ecx: int <- copy 0 + 24 cursor-x, cursor-y <- cursor-position screen 25 compare cursor-x, limit 26 { 27 break-if-< 28 return 29 } 30 cursor-x <- increment - 31 set-cursor-position screen, cursor-x, cursor-y + 31 set-cursor-position screen, cursor-x, cursor-y 32 } 33 34 fn move-cursor-up screen: (addr screen) { - 35 var cursor-x/eax: int <- copy 0 - 36 var cursor-y/ecx: int <- copy 0 - 37 cursor-x, cursor-y <- cursor-position screen + 35 var cursor-x/eax: int <- copy 0 + 36 var cursor-y/ecx: int <- copy 0 + 37 cursor-x, cursor-y <- cursor-position screen 38 compare cursor-y, 0 39 { 40 break-if-> 41 return 42 } 43 cursor-y <- decrement - 44 set-cursor-position screen, cursor-x, cursor-y + 44 set-cursor-position screen, cursor-x, cursor-y 45 } 46 47 fn move-cursor-down screen: (addr screen) { - 48 var dummy/eax: int <- copy 0 - 49 var _height/ecx: int <- copy 0 - 50 dummy, _height <- screen-size screen - 51 var limit/edx: int <- copy _height + 48 var dummy/eax: int <- copy 0 + 49 var _height/ecx: int <- copy 0 + 50 dummy, _height <- screen-size screen + 51 var limit/edx: int <- copy _height 52 limit <- decrement - 53 var cursor-x/eax: int <- copy 0 - 54 var cursor-y/ecx: int <- copy 0 - 55 cursor-x, cursor-y <- cursor-position screen + 53 var cursor-x/eax: int <- copy 0 + 54 var cursor-y/ecx: int <- copy 0 + 55 cursor-x, cursor-y <- cursor-position screen 56 compare cursor-y, limit 57 { 58 break-if-< 59 return 60 } 61 cursor-y <- increment - 62 set-cursor-position screen, cursor-x, cursor-y + 62 set-cursor-position screen, cursor-x, cursor-y 63 } 64 65 fn move-cursor-to-left-margin-of-next-line screen: (addr screen) { - 66 var dummy/eax: int <- copy 0 - 67 var _height/ecx: int <- copy 0 - 68 dummy, _height <- screen-size screen - 69 var limit/edx: int <- copy _height + 66 var dummy/eax: int <- copy 0 + 67 var _height/ecx: int <- copy 0 + 68 dummy, _height <- screen-size screen + 69 var limit/edx: int <- copy _height 70 limit <- decrement - 71 var cursor-x/eax: int <- copy 0 - 72 var cursor-y/ecx: int <- copy 0 - 73 cursor-x, cursor-y <- cursor-position screen + 71 var cursor-x/eax: int <- copy 0 + 72 var cursor-y/ecx: int <- copy 0 + 73 cursor-x, cursor-y <- cursor-position screen 74 compare cursor-y, limit 75 { 76 break-if-< @@ -136,85 +142,85 @@ if ('onhashchange' in window) { 78 } 79 cursor-y <- increment 80 cursor-x <- copy 0 - 81 set-cursor-position screen, cursor-x, cursor-y + 81 set-cursor-position screen, cursor-x, cursor-y 82 } 83 84 fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int, background-color: int { - 85 var cursor-x/eax: int <- copy 0 - 86 var cursor-y/ecx: int <- copy 0 - 87 cursor-x, cursor-y <- cursor-position screen - 88 draw-grapheme screen, g, cursor-x, cursor-y, color, background-color + 85 var cursor-x/eax: int <- copy 0 + 86 var cursor-y/ecx: int <- copy 0 + 87 cursor-x, cursor-y <- cursor-position screen + 88 draw-grapheme screen, g, cursor-x, cursor-y, color, background-color 89 } 90 91 # we can't really render non-ASCII yet, but when we do we'll be ready 92 fn draw-code-point-at-cursor screen: (addr screen), c: code-point, color: int, background-color: int { - 93 var g/eax: grapheme <- copy c + 93 var g/eax: grapheme <- copy c 94 draw-grapheme-at-cursor screen, g, color, background-color 95 } 96 97 # draw a single line of text from x, y to xmax 98 # return the next 'x' coordinate 99 # if there isn't enough space, truncate -100 fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int { +100 fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int { 101 var stream-storage: (stream byte 0x200/print-buffer-size) -102 var stream/esi: (addr stream byte) <- address stream-storage +102 var stream/esi: (addr stream byte) <- address stream-storage 103 write stream, text -104 var xcurr/eax: int <- draw-stream-rightward screen, stream, x, xmax, y, color, background-color +104 var xcurr/eax: int <- draw-stream-rightward screen, stream, x, xmax, y, color, background-color 105 return xcurr 106 } 107 108 # draw a single-line stream from x, y to xmax 109 # return the next 'x' coordinate 110 # if there isn't enough space, truncate -111 fn draw-stream-rightward screen: (addr screen), stream: (addr stream byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int { -112 var xcurr/ecx: int <- copy x +111 fn draw-stream-rightward screen: (addr screen), stream: (addr stream byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int { +112 var xcurr/ecx: int <- copy x 113 { -114 var g/eax: grapheme <- read-grapheme stream +114 var g/eax: grapheme <- read-grapheme stream 115 compare g, 0xffffffff/end-of-file 116 break-if-= -117 draw-grapheme screen, g, xcurr, y, color, background-color +117 draw-grapheme screen, g, xcurr, y, color, background-color 118 xcurr <- increment 119 loop 120 } -121 set-cursor-position screen, xcurr, y +121 set-cursor-position screen, xcurr, y 122 return xcurr 123 } 124 -125 fn draw-text-rightward-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int { -126 var width/eax: int <- copy 0 -127 var height/ecx: int <- copy 0 -128 width, height <- screen-size screen -129 var result/eax: int <- draw-text-rightward screen, text, x, width, y, color, background-color +125 fn draw-text-rightward-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int { +126 var width/eax: int <- copy 0 +127 var height/ecx: int <- copy 0 +128 width, height <- screen-size screen +129 var result/eax: int <- draw-text-rightward screen, text, x, width, y, color, background-color 130 return result 131 } 132 133 fn draw-text-rightward-from-cursor screen: (addr screen), text: (addr array byte), xmax: int, color: int, background-color: int { -134 var cursor-x/eax: int <- copy 0 -135 var cursor-y/ecx: int <- copy 0 -136 cursor-x, cursor-y <- cursor-position screen +134 var cursor-x/eax: int <- copy 0 +135 var cursor-y/ecx: int <- copy 0 +136 cursor-x, cursor-y <- cursor-position screen 137 cursor-x <- draw-text-rightward screen, text, cursor-x, xmax, cursor-y, color, background-color -138 set-cursor-position screen, cursor-x, cursor-y +138 set-cursor-position screen, cursor-x, cursor-y 139 } 140 141 fn draw-text-rightward-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int { -142 var width/eax: int <- copy 0 -143 var height/ecx: int <- copy 0 -144 width, height <- screen-size screen +142 var width/eax: int <- copy 0 +143 var height/ecx: int <- copy 0 +144 width, height <- screen-size screen 145 draw-text-rightward-from-cursor screen, text, width, color, background-color 146 } 147 -148 fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +148 fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { 149 compare g, 0xa/newline -150 var x/eax: int <- copy x +150 var x/eax: int <- copy x 151 { 152 break-if-!= 153 # minimum effort to clear cursor -154 draw-code-point screen, 0x20/space, x, y, color, background-color +154 draw-code-point screen, 0x20/space, x, y, color, background-color 155 x <- copy xmin 156 increment y 157 return x, y 158 } -159 draw-grapheme screen, g, x, y, color, background-color +159 draw-grapheme screen, g, x, y, color, background-color 160 x <- increment 161 compare x, xmax 162 { @@ -229,14 +235,14 @@ if ('onhashchange' in window) { 171 # return the next (x, y) coordinate in raster order where drawing stopped 172 # that way the caller can draw more if given the same min and max bounding-box. 173 # if there isn't enough space, truncate -174 fn draw-text-wrapping-right-then-down screen: (addr screen), _text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +174 fn draw-text-wrapping-right-then-down screen: (addr screen), _text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { 175 var stream-storage: (stream byte 0x200/print-buffer-size) # 4 rows of text = 1/12th of a real screen 176 # fake screens unlikely to be larger 177 # so this seems a reasonable size 178 # allocated on the stack, so quickly reclaimed -179 var stream/edi: (addr stream byte) <- address stream-storage -180 var text/esi: (addr array byte) <- copy _text -181 var len/eax: int <- length text +179 var stream/edi: (addr stream byte) <- address stream-storage +180 var text/esi: (addr array byte) <- copy _text +181 var len/eax: int <- length text 182 compare len, 0x200 183 { 184 break-if-< @@ -247,8 +253,8 @@ if ('onhashchange' in window) { 189 break-if->= 190 write stream, text 191 } -192 var x/eax: int <- copy _x -193 var y/ecx: int <- copy _y +192 var x/eax: int <- copy _x +193 var y/ecx: int <- copy _y 194 x, y <- draw-stream-wrapping-right-then-down screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color 195 return x, y 196 } @@ -257,13 +263,13 @@ if ('onhashchange' in window) { 199 # return the next (x, y) coordinate in raster order where drawing stopped 200 # that way the caller can draw more if given the same min and max bounding-box. 201 # if there isn't enough space, truncate -202 fn draw-stream-wrapping-right-then-down screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { -203 var xcurr/eax: int <- copy x -204 var ycurr/ecx: int <- copy y -205 var g/ebx: grapheme <- copy 0 +202 fn draw-stream-wrapping-right-then-down screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +203 var xcurr/eax: int <- copy x +204 var ycurr/ecx: int <- copy y +205 var g/ebx: grapheme <- copy 0 206 { 207 { -208 var _g/eax: grapheme <- read-grapheme stream +208 var _g/eax: grapheme <- read-grapheme stream 209 g <- copy _g 210 } 211 compare g, 0xffffffff/end-of-file @@ -271,15 +277,15 @@ if ('onhashchange' in window) { 213 xcurr, ycurr <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color 214 loop 215 } -216 set-cursor-position screen, xcurr, ycurr +216 set-cursor-position screen, xcurr, ycurr 217 return xcurr, ycurr 218 } 219 220 fn draw-stream-wrapping-right-then-down-from-cursor screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int { -221 var cursor-x/eax: int <- copy 0 -222 var cursor-y/ecx: int <- copy 0 -223 cursor-x, cursor-y <- cursor-position screen -224 var end-x/edx: int <- copy cursor-x +221 var cursor-x/eax: int <- copy 0 +222 var cursor-y/ecx: int <- copy 0 +223 cursor-x, cursor-y <- cursor-position screen +224 var end-x/edx: int <- copy cursor-x 225 end-x <- increment 226 compare end-x, xmax 227 { @@ -291,16 +297,16 @@ if ('onhashchange' in window) { 233 } 234 235 fn draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), stream: (addr stream byte), color: int, background-color: int { -236 var width/eax: int <- copy 0 -237 var height/ecx: int <- copy 0 -238 width, height <- screen-size screen +236 var width/eax: int <- copy 0 +237 var height/ecx: int <- copy 0 +238 width, height <- screen-size screen 239 draw-stream-wrapping-right-then-down-from-cursor screen, stream, 0/xmin, 0/ymin, width, height, color, background-color 240 } 241 242 fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: int { -243 var cursor-x/eax: int <- copy 0 -244 var cursor-y/ecx: int <- copy 0 -245 cursor-x, cursor-y <- cursor-position screen +243 var cursor-x/eax: int <- copy 0 +244 var cursor-y/ecx: int <- copy 0 +245 cursor-x, cursor-y <- cursor-position screen 246 cursor-x <- increment 247 compare cursor-x, xmax 248 { @@ -308,22 +314,22 @@ if ('onhashchange' in window) { 250 cursor-x <- copy xmin 251 cursor-y <- increment 252 } -253 set-cursor-position screen, cursor-x, cursor-y +253 set-cursor-position screen, cursor-x, cursor-y 254 } 255 -256 fn draw-text-wrapping-right-then-down-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { -257 var x2/eax: int <- copy 0 -258 var y2/ecx: int <- copy 0 -259 x2, y2 <- screen-size screen # width, height +256 fn draw-text-wrapping-right-then-down-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +257 var x2/eax: int <- copy 0 +258 var y2/ecx: int <- copy 0 +259 x2, y2 <- screen-size screen # width, height 260 x2, y2 <- draw-text-wrapping-right-then-down screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color 261 return x2, y2 # cursor-x, cursor-y 262 } 263 264 fn draw-text-wrapping-right-then-down-from-cursor screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int { -265 var cursor-x/eax: int <- copy 0 -266 var cursor-y/ecx: int <- copy 0 -267 cursor-x, cursor-y <- cursor-position screen -268 var end-x/edx: int <- copy cursor-x +265 var cursor-x/eax: int <- copy 0 +266 var cursor-y/ecx: int <- copy 0 +267 cursor-x, cursor-y <- cursor-position screen +268 var end-x/edx: int <- copy cursor-x 269 end-x <- increment 270 compare end-x, xmax 271 { @@ -335,23 +341,23 @@ if ('onhashchange' in window) { 277 } 278 279 fn draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int { -280 var width/eax: int <- copy 0 -281 var height/ecx: int <- copy 0 -282 width, height <- screen-size screen +280 var width/eax: int <- copy 0 +281 var height/ecx: int <- copy 0 +282 width, height <- screen-size screen 283 draw-text-wrapping-right-then-down-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color 284 } 285 -286 fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +286 fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { 287 var stream-storage: (stream byte 0x100) -288 var stream/esi: (addr stream byte) <- address stream-storage +288 var stream/esi: (addr stream byte) <- address stream-storage 289 write-int32-hex stream, n -290 var xcurr/edx: int <- copy x -291 var ycurr/ecx: int <- copy y +290 var xcurr/edx: int <- copy x +291 var ycurr/ecx: int <- copy y 292 { -293 var g/eax: grapheme <- read-grapheme stream +293 var g/eax: grapheme <- read-grapheme stream 294 compare g, 0xffffffff/end-of-file 295 break-if-= -296 draw-grapheme screen, g, xcurr, ycurr, color, background-color +296 draw-grapheme screen, g, xcurr, ycurr, color, background-color 297 xcurr <- increment 298 compare xcurr, xmax 299 { @@ -361,23 +367,23 @@ if ('onhashchange' in window) { 303 } 304 loop 305 } -306 set-cursor-position screen, xcurr, ycurr +306 set-cursor-position screen, xcurr, ycurr 307 return xcurr, ycurr 308 } 309 -310 fn draw-int32-hex-wrapping-right-then-down-over-full-screen screen: (addr screen), n: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { -311 var x2/eax: int <- copy 0 -312 var y2/ecx: int <- copy 0 -313 x2, y2 <- screen-size screen # width, height +310 fn draw-int32-hex-wrapping-right-then-down-over-full-screen screen: (addr screen), n: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +311 var x2/eax: int <- copy 0 +312 var y2/ecx: int <- copy 0 +313 x2, y2 <- screen-size screen # width, height 314 x2, y2 <- draw-int32-hex-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color 315 return x2, y2 # cursor-x, cursor-y 316 } 317 318 fn draw-int32-hex-wrapping-right-then-down-from-cursor screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int { -319 var cursor-x/eax: int <- copy 0 -320 var cursor-y/ecx: int <- copy 0 -321 cursor-x, cursor-y <- cursor-position screen -322 var end-x/edx: int <- copy cursor-x +319 var cursor-x/eax: int <- copy 0 +320 var cursor-y/ecx: int <- copy 0 +321 cursor-x, cursor-y <- cursor-position screen +322 var end-x/edx: int <- copy cursor-x 323 end-x <- increment 324 compare end-x, xmax 325 { @@ -389,23 +395,23 @@ if ('onhashchange' in window) { 331 } 332 333 fn draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int { -334 var width/eax: int <- copy 0 -335 var height/ecx: int <- copy 0 -336 width, height <- screen-size screen +334 var width/eax: int <- copy 0 +335 var height/ecx: int <- copy 0 +336 width, height <- screen-size screen 337 draw-int32-hex-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color 338 } 339 -340 fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +340 fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { 341 var stream-storage: (stream byte 0x100) -342 var stream/esi: (addr stream byte) <- address stream-storage +342 var stream/esi: (addr stream byte) <- address stream-storage 343 write-int32-decimal stream, n -344 var xcurr/edx: int <- copy x -345 var ycurr/ecx: int <- copy y +344 var xcurr/edx: int <- copy x +345 var ycurr/ecx: int <- copy y 346 { -347 var g/eax: grapheme <- read-grapheme stream +347 var g/eax: grapheme <- read-grapheme stream 348 compare g, 0xffffffff/end-of-file 349 break-if-= -350 draw-grapheme screen, g, xcurr, ycurr, color, background-color +350 draw-grapheme screen, g, xcurr, ycurr, color, background-color 351 xcurr <- increment 352 compare xcurr, xmax 353 { @@ -415,23 +421,23 @@ if ('onhashchange' in window) { 357 } 358 loop 359 } -360 set-cursor-position screen, xcurr, ycurr +360 set-cursor-position screen, xcurr, ycurr 361 return xcurr, ycurr 362 } 363 -364 fn draw-int32-decimal-wrapping-right-then-down-over-full-screen screen: (addr screen), n: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { -365 var x2/eax: int <- copy 0 -366 var y2/ecx: int <- copy 0 -367 x2, y2 <- screen-size screen # width, height +364 fn draw-int32-decimal-wrapping-right-then-down-over-full-screen screen: (addr screen), n: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +365 var x2/eax: int <- copy 0 +366 var y2/ecx: int <- copy 0 +367 x2, y2 <- screen-size screen # width, height 368 x2, y2 <- draw-int32-decimal-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color 369 return x2, y2 # cursor-x, cursor-y 370 } 371 372 fn draw-int32-decimal-wrapping-right-then-down-from-cursor screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int { -373 var cursor-x/eax: int <- copy 0 -374 var cursor-y/ecx: int <- copy 0 -375 cursor-x, cursor-y <- cursor-position screen -376 var end-x/edx: int <- copy cursor-x +373 var cursor-x/eax: int <- copy 0 +374 var cursor-y/ecx: int <- copy 0 +375 cursor-x, cursor-y <- cursor-position screen +376 var end-x/edx: int <- copy cursor-x 377 end-x <- increment 378 compare end-x, xmax 379 { @@ -443,9 +449,9 @@ if ('onhashchange' in window) { 385 } 386 387 fn draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int { -388 var width/eax: int <- copy 0 -389 var height/ecx: int <- copy 0 -390 width, height <- screen-size screen +388 var width/eax: int <- copy 0 +389 var height/ecx: int <- copy 0 +390 width, height <- screen-size screen 391 draw-int32-decimal-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color 392 } 393 @@ -454,48 +460,48 @@ if ('onhashchange' in window) { 396 # draw a single line of text vertically from x, y to ymax 397 # return the next 'y' coordinate 398 # if there isn't enough space, truncate -399 fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int { +399 fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int { 400 var stream-storage: (stream byte 0x100) -401 var stream/esi: (addr stream byte) <- address stream-storage +401 var stream/esi: (addr stream byte) <- address stream-storage 402 write stream, text -403 var ycurr/eax: int <- draw-stream-downward screen, stream, x, y, ymax, color, background-color +403 var ycurr/eax: int <- draw-stream-downward screen, stream, x, y, ymax, color, background-color 404 return ycurr 405 } 406 407 # draw a single-line stream vertically from x, y to ymax 408 # return the next 'y' coordinate 409 # if there isn't enough space, truncate -410 fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int { -411 var ycurr/ecx: int <- copy y +410 fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int { +411 var ycurr/ecx: int <- copy y 412 { -413 var g/eax: grapheme <- read-grapheme stream +413 var g/eax: grapheme <- read-grapheme stream 414 compare g, 0xffffffff/end-of-file 415 break-if-= -416 draw-grapheme screen, g, x, ycurr, color, background-color +416 draw-grapheme screen, g, x, ycurr, color, background-color 417 ycurr <- increment 418 loop 419 } -420 set-cursor-position screen, x, ycurr +420 set-cursor-position screen, x, ycurr 421 return ycurr 422 } 423 424 fn draw-text-downward-from-cursor screen: (addr screen), text: (addr array byte), ymax: int, color: int, background-color: int { -425 var cursor-x/eax: int <- copy 0 -426 var cursor-y/ecx: int <- copy 0 -427 cursor-x, cursor-y <- cursor-position screen -428 var result/eax: int <- draw-text-downward screen, text, cursor-x, cursor-y, ymax, color, background-color +425 var cursor-x/eax: int <- copy 0 +426 var cursor-y/ecx: int <- copy 0 +427 cursor-x, cursor-y <- cursor-position screen +428 var result/eax: int <- draw-text-downward screen, text, cursor-x, cursor-y, ymax, color, background-color 429 } 430 431 # draw text down and right in the rectangle from (xmin, ymin) to (xmax, ymax), starting from (x, y), wrapping as necessary 432 # return the next (x, y) coordinate in raster order where drawing stopped 433 # that way the caller can draw more if given the same min and max bounding-box. 434 # if there isn't enough space, truncate -435 fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +435 fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { 436 var stream-storage: (stream byte 0x100) -437 var stream/esi: (addr stream byte) <- address stream-storage +437 var stream/esi: (addr stream byte) <- address stream-storage 438 write stream, text -439 var x/eax: int <- copy _x -440 var y/ecx: int <- copy _y +439 var x/eax: int <- copy _x +440 var y/ecx: int <- copy _y 441 x, y <- draw-stream-wrapping-down-then-right screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color 442 return x, y 443 } @@ -504,14 +510,14 @@ if ('onhashchange' in window) { 446 # return the next (x, y) coordinate in raster order where drawing stopped 447 # that way the caller can draw more if given the same min and max bounding-box. 448 # if there isn't enough space, truncate -449 fn draw-stream-wrapping-down-then-right screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { -450 var xcurr/edx: int <- copy x -451 var ycurr/ecx: int <- copy y +449 fn draw-stream-wrapping-down-then-right screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +450 var xcurr/edx: int <- copy x +451 var ycurr/ecx: int <- copy y 452 { -453 var g/eax: grapheme <- read-grapheme stream +453 var g/eax: grapheme <- read-grapheme stream 454 compare g, 0xffffffff/end-of-file 455 break-if-= -456 draw-grapheme screen, g, xcurr, ycurr, color, background-color +456 draw-grapheme screen, g, xcurr, ycurr, color, background-color 457 ycurr <- increment 458 compare ycurr, ymax 459 { @@ -521,23 +527,23 @@ if ('onhashchange' in window) { 463 } 464 loop 465 } -466 set-cursor-position screen, xcurr, ycurr +466 set-cursor-position screen, xcurr, ycurr 467 return xcurr, ycurr 468 } 469 -470 fn draw-text-wrapping-down-then-right-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { -471 var x2/eax: int <- copy 0 -472 var y2/ecx: int <- copy 0 -473 x2, y2 <- screen-size screen # width, height +470 fn draw-text-wrapping-down-then-right-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +471 var x2/eax: int <- copy 0 +472 var y2/ecx: int <- copy 0 +473 x2, y2 <- screen-size screen # width, height 474 x2, y2 <- draw-text-wrapping-down-then-right screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color 475 return x2, y2 # cursor-x, cursor-y 476 } 477 478 fn draw-text-wrapping-down-then-right-from-cursor screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int { -479 var cursor-x/eax: int <- copy 0 -480 var cursor-y/ecx: int <- copy 0 -481 cursor-x, cursor-y <- cursor-position screen -482 var end-y/edx: int <- copy cursor-y +479 var cursor-x/eax: int <- copy 0 +480 var cursor-y/ecx: int <- copy 0 +481 cursor-x, cursor-y <- cursor-position screen +482 var end-y/edx: int <- copy cursor-y 483 end-y <- increment 484 compare end-y, ymax 485 { @@ -549,9 +555,9 @@ if ('onhashchange' in window) { 491 } 492 493 fn draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int { -494 var width/eax: int <- copy 0 -495 var height/ecx: int <- copy 0 -496 width, height <- screen-size screen +494 var width/eax: int <- copy 0 +495 var height/ecx: int <- copy 0 +496 width, height <- screen-size screen 497 draw-text-wrapping-down-then-right-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color 498 } diff --git a/html/502test.mu.html b/html/502test.mu.html index edb32774..44bb5649 100644 --- a/html/502test.mu.html +++ b/html/502test.mu.html @@ -18,6 +18,7 @@ a { color:inherit; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muTest { color: #5f8700; } @@ -59,7 +60,7 @@ if ('onhashchange' in window) {
  1 # print msg to screen if a != b, otherwise print "."
  2 fn check-ints-equal _a: int, b: int, msg: (addr array byte) {
- 3   var a/eax: int <- copy _a
+ 3   var a/eax: int <- copy _a
  4   compare a, b
  5   {
  6     break-if-!=
@@ -76,7 +77,7 @@ if ('onhashchange' in window) {
 17 }
 18 
 19 fn check _a: boolean, msg: (addr array byte) {
-20   var a/eax: int <- copy _a
+20   var a/eax: int <- copy _a
 21   compare a, 0/false
 22   {
 23     break-if-=
@@ -89,7 +90,7 @@ if ('onhashchange' in window) {
 30 }
 31 
 32 fn check-not _a: boolean, msg: (addr array byte) {
-33   var a/eax: int <- copy _a
+33   var a/eax: int <- copy _a
 34   compare a, 0/false
 35   {
 36     break-if-!=
diff --git a/html/503manhattan-line.mu.html b/html/503manhattan-line.mu.html
index f6633818..ddba64d2 100644
--- a/html/503manhattan-line.mu.html
+++ b/html/503manhattan-line.mu.html
@@ -16,7 +16,7 @@ a { color:inherit; }
 * { font-size:12pt; font-size: 1em; }
 .PreProc { color: #c000c0; }
 .LineNr { }
-.Constant { color: #008787; }
+.muRegEax { color: #875f00; }
 .Delimiter { color: #c000c0; }
 .muFunction { color: #af5f00; text-decoration: underline; }
 .Special { color: #ff6060; }
@@ -63,7 +63,7 @@ if ('onhashchange' in window) {
  6 }
  7 
  8 fn draw-horizontal-line-on-real-screen x1: int, x2: int, y: int, color: int {
- 9   var x/eax: int <- copy x1
+ 9   var x/eax: int <- copy x1
 10   {
 11     compare x, x2
 12     break-if->=
@@ -74,7 +74,7 @@ if ('onhashchange' in window) {
 17 }
 18 
 19 fn draw-vertical-line-on-real-screen x: int, y1: int, y2: int, color: int {
-20   var y/eax: int <- copy y1
+20   var y/eax: int <- copy y1
 21   {
 22     compare y, y2
 23     break-if->=
diff --git a/html/504test-screen.mu.html b/html/504test-screen.mu.html
index 32122ddf..68ecfd49 100644
--- a/html/504test-screen.mu.html
+++ b/html/504test-screen.mu.html
@@ -14,14 +14,20 @@ pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-
 body { font-size:12pt; font-family: monospace; color: #000000; background-color: #a8a8a8; }
 a { color:inherit; }
 * { font-size:12pt; font-size: 1em; }
-.PreProc { color: #c000c0; }
-.Special { color: #ff6060; }
 .LineNr { }
-.Constant { color: #008787; }
 .Delimiter { color: #c000c0; }
+.muRegEdx { color: #878700; }
+.muRegEbx { color: #8787af; }
+.muRegEsi { color: #87d787; }
+.muRegEdi { color: #87ffd7; }
+.Constant { color: #008787; }
+.Special { color: #ff6060; }
+.PreProc { color: #c000c0; }
 .muFunction { color: #af5f00; text-decoration: underline; }
 .muTest { color: #5f8700; }
 .muComment { color: #005faf; }
+.muRegEax { color: #875f00; }
+.muRegEcx { color: #af875f; }
 -->
 
 
@@ -68,322 +74,338 @@ if ('onhashchange' in window) {
   9 }
  10 
  11 fn check-screen-row-from screen-on-stack: (addr screen), x: int, y: int, expected: (addr array byte), msg: (addr array byte) {
- 12   var screen/esi: (addr screen) <- copy screen-on-stack
- 13   var idx/ecx: int <- screen-cell-index screen, x, y
- 14   # compare 'expected' with the screen contents starting at 'idx', grapheme by grapheme
- 15   var e: (stream byte 0x100)
- 16   var e-addr/edx: (addr stream byte) <- address e
- 17   write e-addr, expected
- 18   {
- 19     var done?/eax: boolean <- stream-empty? e-addr
- 20     compare done?, 0
- 21     break-if-!=
- 22     var _g/eax: grapheme <- screen-grapheme-at-idx screen, idx
- 23     var g/ebx: grapheme <- copy _g
- 24     var expected-grapheme/eax: grapheme <- read-grapheme e-addr
- 25     # compare graphemes
- 26     $check-screen-row-from:compare-graphemes: {
- 27       # if expected-grapheme is space, null grapheme is also ok
- 28       {
- 29         compare expected-grapheme, 0x20
- 30         break-if-!=
- 31         compare g, 0
- 32         break-if-= $check-screen-row-from:compare-graphemes
- 33       }
- 34       # if (g == expected-grapheme) print "."
- 35       compare g, expected-grapheme
- 36       {
- 37         break-if-!=
- 38         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
- 39         break $check-screen-row-from:compare-graphemes
- 40       }
- 41       # otherwise print an error
- 42       count-test-failure
- 43       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
- 44       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
- 45       draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
- 46       move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
- 47       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
- 48       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
- 49       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
- 50       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
- 51       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg
- 52       draw-grapheme-at-cursor 0/screen, g, 3/cyan, 0/bg
- 53       move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
- 54       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg
- 55       move-cursor-to-left-margin-of-next-line 0/screen
- 56     }
- 57     idx <- increment
- 58     increment x
- 59     loop
- 60   }
- 61 }
- 62 
- 63 # various variants by screen-cell attribute; spaces in the 'expected' data should not match the attribute
- 64 
- 65 fn check-screen-row-in-color screen: (addr screen), fg: int, y: int, expected: (addr array byte), msg: (addr array byte) {
- 66   check-screen-row-in-color-from screen, fg, y, 0/x, expected, msg
+ 12   var screen/esi: (addr screen) <- copy screen-on-stack
+ 13   var failure-count/edi: int <- copy 0
+ 14   var idx/ecx: int <- screen-cell-index screen, x, y
+ 15   # compare 'expected' with the screen contents starting at 'idx', grapheme by grapheme
+ 16   var e: (stream byte 0x100)
+ 17   var e-addr/edx: (addr stream byte) <- address e
+ 18   write e-addr, expected
+ 19   {
+ 20     var done?/eax: boolean <- stream-empty? e-addr
+ 21     compare done?, 0
+ 22     break-if-!=
+ 23     var _g/eax: grapheme <- screen-grapheme-at-idx screen, idx
+ 24     var g/ebx: grapheme <- copy _g
+ 25     var expected-grapheme/eax: grapheme <- read-grapheme e-addr
+ 26     # compare graphemes
+ 27     $check-screen-row-from:compare-graphemes: {
+ 28       # if expected-grapheme is space, null grapheme is also ok
+ 29       {
+ 30         compare expected-grapheme, 0x20
+ 31         break-if-!=
+ 32         compare g, 0
+ 33         break-if-= $check-screen-row-from:compare-graphemes
+ 34       }
+ 35       # if (g == expected-grapheme) print "."
+ 36       compare g, expected-grapheme
+ 37       break-if-=
+ 38       # otherwise print an error
+ 39       failure-count <- increment
+ 40       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
+ 41       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
+ 42       draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
+ 43       move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+ 44       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
+ 45       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
+ 46       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
+ 47       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
+ 48       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg
+ 49       draw-grapheme-at-cursor 0/screen, g, 3/cyan, 0/bg
+ 50       move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+ 51       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg
+ 52       move-cursor-to-left-margin-of-next-line 0/screen
+ 53     }
+ 54     idx <- increment
+ 55     increment x
+ 56     loop
+ 57   }
+ 58   # if any assertions failed, count the test as failed
+ 59   compare failure-count, 0
+ 60   {
+ 61     break-if-=
+ 62     count-test-failure
+ 63     return
+ 64   }
+ 65   # otherwise print a "."
+ 66   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
  67 }
  68 
- 69 fn check-screen-row-in-color-from screen-on-stack: (addr screen), fg: int, y: int, x: int, expected: (addr array byte), msg: (addr array byte) {
- 70   var screen/esi: (addr screen) <- copy screen-on-stack
- 71   var idx/ecx: int <- screen-cell-index screen, x, y
- 72   # compare 'expected' with the screen contents starting at 'idx', grapheme by grapheme
- 73   var e: (stream byte 0x100)
- 74   var e-addr/edx: (addr stream byte) <- address e
- 75   write e-addr, expected
- 76   {
- 77     var done?/eax: boolean <- stream-empty? e-addr
- 78     compare done?, 0
- 79     break-if-!=
- 80     var _g/eax: grapheme <- screen-grapheme-at-idx screen, idx
- 81     var g/ebx: grapheme <- copy _g
- 82     var _expected-grapheme/eax: grapheme <- read-grapheme e-addr
- 83     var expected-grapheme/edi: grapheme <- copy _expected-grapheme
- 84     $check-screen-row-in-color-from:compare-cells: {
- 85       # if expected-grapheme is space, null grapheme is also ok
- 86       {
- 87         compare expected-grapheme, 0x20
- 88         break-if-!=
- 89         compare g, 0
- 90         break-if-= $check-screen-row-in-color-from:compare-cells
- 91       }
- 92       # if expected-grapheme is space, a different color is ok
- 93       {
- 94         compare expected-grapheme, 0x20
- 95         break-if-!=
- 96         var color/eax: int <- screen-color-at-idx screen, idx
- 97         compare color, fg
- 98         break-if-!= $check-screen-row-in-color-from:compare-cells
- 99       }
-100       # compare graphemes
-101       $check-screen-row-in-color-from:compare-graphemes: {
-102         # if (g == expected-grapheme) print "."
-103         compare g, expected-grapheme
-104         {
-105           break-if-!=
-106           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
-107           break $check-screen-row-in-color-from:compare-graphemes
-108         }
-109         # otherwise print an error
-110         count-test-failure
-111         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
-112         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
-113         draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
-114         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
-115         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
-116         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
-117         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
-118         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
-119         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg
-120         draw-grapheme-at-cursor 0/screen, g, 3/cyan, 0/bg
-121         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
-122         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg
-123         move-cursor-to-left-margin-of-next-line 0/screen
-124       }
-125       $check-screen-row-in-color-from:compare-colors: {
-126         var color/eax: int <- screen-color-at-idx screen, idx
-127         compare fg, color
-128         {
-129           break-if-!=
-130           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
-131           break $check-screen-row-in-color-from:compare-colors
-132         }
-133         # otherwise print an error
-134         count-test-failure
-135         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
-136         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
-137         draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
-138         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
-139         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
-140         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
-141         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
-142         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
-143         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in color ", 3/fg/cyan, 0/bg
-144         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, fg, 3/fg/cyan, 0/bg
-145         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed color ", 3/fg/cyan, 0/bg
-146         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, color, 3/fg/cyan, 0/bg
-147         move-cursor-to-left-margin-of-next-line 0/screen
-148       }
-149     }
-150     idx <- increment
-151     increment x
-152     loop
-153   }
-154 }
-155 
-156 fn check-screen-row-in-background-color screen: (addr screen), bg: int, y: int, expected: (addr array byte), msg: (addr array byte) {
-157   check-screen-row-in-background-color-from screen, bg, y, 0/x, expected, msg
-158 }
-159 
-160 fn check-screen-row-in-background-color-from screen-on-stack: (addr screen), bg: int, y: int, x: int, expected: (addr array byte), msg: (addr array byte) {
-161   var screen/esi: (addr screen) <- copy screen-on-stack
-162   var idx/ecx: int <- screen-cell-index screen, x, y
-163   # compare 'expected' with the screen contents starting at 'idx', grapheme by grapheme
-164   var e: (stream byte 0x100)
-165   var e-addr/edx: (addr stream byte) <- address e
-166   write e-addr, expected
-167   {
-168     var done?/eax: boolean <- stream-empty? e-addr
-169     compare done?, 0
-170     break-if-!=
-171     var _g/eax: grapheme <- screen-grapheme-at-idx screen, idx
-172     var g/ebx: grapheme <- copy _g
-173     var _expected-grapheme/eax: grapheme <- read-grapheme e-addr
-174     var expected-grapheme/edi: grapheme <- copy _expected-grapheme
-175     $check-screen-row-in-background-color-from:compare-cells: {
-176       # if expected-grapheme is space, null grapheme is also ok
-177       {
-178         compare expected-grapheme, 0x20
-179         break-if-!=
-180         compare g, 0
-181         break-if-= $check-screen-row-in-background-color-from:compare-cells
-182       }
-183       # if expected-grapheme is space, a different background-color is ok
-184       {
-185         compare expected-grapheme, 0x20
-186         break-if-!=
-187         var background-color/eax: int <- screen-background-color-at-idx screen, idx
-188         compare background-color, bg
-189         break-if-!= $check-screen-row-in-background-color-from:compare-cells
-190       }
-191       # compare graphemes
-192       $check-screen-row-in-background-color-from:compare-graphemes: {
-193         # if (g == expected-grapheme) print "."
-194         compare g, expected-grapheme
-195         {
-196           break-if-!=
-197           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
-198           break $check-screen-row-in-background-color-from:compare-graphemes
-199         }
-200         # otherwise print an error
-201         count-test-failure
-202         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
-203         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
-204         draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
-205         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
-206         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
-207         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
-208         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
-209         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
-210         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg
-211         draw-grapheme-at-cursor 0/screen, g, 3/cyan, 0/bg
-212         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
-213         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg
-214         move-cursor-to-left-margin-of-next-line 0/screen
-215         break $check-screen-row-in-background-color-from:compare-graphemes
-216       }
-217       $check-screen-row-in-background-color-from:compare-background-colors: {
-218         var background-color/eax: int <- screen-background-color-at-idx screen, idx
-219         compare bg, background-color
-220         {
-221           break-if-!=
-222           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
-223           break $check-screen-row-in-background-color-from:compare-background-colors
-224         }
-225         # otherwise print an error
-226         count-test-failure
-227         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
-228         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
-229         draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
-230         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
-231         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
-232         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
-233         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
-234         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
-235         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in background-color ", 3/fg/cyan, 0/bg
-236         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg/cyan, 0/bg
-237         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed background-color ", 3/fg/cyan, 0/bg
-238         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, background-color, 3/fg/cyan, 0/bg
-239         move-cursor-to-left-margin-of-next-line 0/screen
-240       }
-241     }
-242     idx <- increment
-243     increment x
-244     loop
-245   }
-246 }
-247 
-248 # helpers for checking just background color, not screen contents
-249 # these can validate bg for spaces
-250 
-251 fn check-background-color-in-screen-row screen: (addr screen), bg: int, y: int, expected-bitmap: (addr array byte), msg: (addr array byte) {
-252   check-background-color-in-screen-row-from screen, bg, y, 0/x, expected-bitmap, msg
-253 }
-254 
-255 fn check-background-color-in-screen-row-from screen-on-stack: (addr screen), bg: int, y: int, x: int, expected-bitmap: (addr array byte), msg: (addr array byte) {
-256   var screen/esi: (addr screen) <- copy screen-on-stack
-257   var idx/ecx: int <- screen-cell-index screen, x, y
-258   # compare background color where 'expected-bitmap' is a non-space
-259   var e: (stream byte 0x100)
-260   var e-addr/edx: (addr stream byte) <- address e
-261   write e-addr, expected-bitmap
-262   {
-263     var done?/eax: boolean <- stream-empty? e-addr
-264     compare done?, 0
-265     break-if-!=
-266     var _expected-bit/eax: grapheme <- read-grapheme e-addr
-267     var expected-bit/edi: grapheme <- copy _expected-bit
-268     $check-background-color-in-screen-row-from:compare-cells: {
-269       var background-color/eax: int <- screen-background-color-at-idx screen, idx
-270       # if expected-bit is space, assert that background is NOT bg
-271       compare expected-bit, 0x20
-272       {
-273         break-if-!=
-274         compare background-color, bg
-275         break-if-!= $check-background-color-in-screen-row-from:compare-cells
-276         count-test-failure
-277         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
-278         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected (", 3/fg/cyan, 0/bg
-279         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
-280         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
-281         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
-282         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") to not be in background-color ", 3/fg/cyan, 0/bg
-283         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg/cyan, 0/bg
-284         move-cursor-to-left-margin-of-next-line 0/screen
-285         break $check-background-color-in-screen-row-from:compare-cells
-286       }
-287       # otherwise assert that background IS bg
-288       compare background-color, bg
-289       break-if-= $check-background-color-in-screen-row-from:compare-cells
-290       count-test-failure
-291       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
-292       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected (", 3/fg/cyan, 0/bg
-293       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
-294       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
-295       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
-296       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in background-color ", 3/fg/cyan, 0/bg
-297       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg/cyan, 0/bg
-298       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed background-color ", 3/fg/cyan, 0/bg
-299       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, background-color, 3/fg/cyan, 0/bg
-300       move-cursor-to-left-margin-of-next-line 0/screen
-301     }
-302     idx <- increment
-303     increment x
-304     loop
-305   }
-306 }
-307 
-308 fn test-draw-single-grapheme {
-309   var screen-on-stack: screen
-310   var screen/esi: (addr screen) <- address screen-on-stack
-311   initialize-screen screen, 5, 4, 0/no-pixel-graphics
-312   draw-code-point screen, 0x61/a, 0/x, 0/y, 1/fg, 2/bg
-313   check-screen-row screen, 0/y, "a", "F - test-draw-single-grapheme"  # top-left corner of the screen
-314   check-screen-row-in-color screen, 1/fg, 0/y, "a", "F - test-draw-single-grapheme-fg"
-315   check-screen-row-in-background-color screen, 2/bg, 0/y, "a", "F - test-draw-single-grapheme-bg"
-316   check-background-color-in-screen-row screen, 2/bg, 0/y, "x ", "F - test-draw-single-grapheme-bg2"
-317 }
-318 
-319 fn test-draw-multiple-graphemes {
-320   var screen-on-stack: screen
-321   var screen/esi: (addr screen) <- address screen-on-stack
-322   initialize-screen screen, 0x10/rows, 4/cols, 0/no-pixel-graphics
-323   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "Hello, 世界", 1/fg, 2/bg
-324   check-screen-row screen, 0/y, "Hello, 世界", "F - test-draw-multiple-graphemes"
-325   check-screen-row-in-color screen, 1/fg, 0/y, "Hello, 世界", "F - test-draw-multiple-graphemes-fg"
-326   check-background-color-in-screen-row screen, 2/bg, 0/y, "xxxxxxxxx ", "F - test-draw-multiple-graphemes-bg2"
-327 }
+ 69 # various variants by screen-cell attribute; spaces in the 'expected' data should not match the attribute
+ 70 
+ 71 fn check-screen-row-in-color screen: (addr screen), fg: int, y: int, expected: (addr array byte), msg: (addr array byte) {
+ 72   check-screen-row-in-color-from screen, fg, y, 0/x, expected, msg
+ 73 }
+ 74 
+ 75 fn check-screen-row-in-color-from screen-on-stack: (addr screen), fg: int, y: int, x: int, expected: (addr array byte), msg: (addr array byte) {
+ 76   var screen/esi: (addr screen) <- copy screen-on-stack
+ 77   var idx/ecx: int <- screen-cell-index screen, x, y
+ 78   # compare 'expected' with the screen contents starting at 'idx', grapheme by grapheme
+ 79   var e: (stream byte 0x100)
+ 80   var e-addr/edx: (addr stream byte) <- address e
+ 81   write e-addr, expected
+ 82   {
+ 83     var done?/eax: boolean <- stream-empty? e-addr
+ 84     compare done?, 0
+ 85     break-if-!=
+ 86     var _g/eax: grapheme <- screen-grapheme-at-idx screen, idx
+ 87     var g/ebx: grapheme <- copy _g
+ 88     var _expected-grapheme/eax: grapheme <- read-grapheme e-addr
+ 89     var expected-grapheme/edi: grapheme <- copy _expected-grapheme
+ 90     $check-screen-row-in-color-from:compare-cells: {
+ 91       # if expected-grapheme is space, null grapheme is also ok
+ 92       {
+ 93         compare expected-grapheme, 0x20
+ 94         break-if-!=
+ 95         compare g, 0
+ 96         break-if-= $check-screen-row-in-color-from:compare-cells
+ 97       }
+ 98       # if expected-grapheme is space, a different color is ok
+ 99       {
+100         compare expected-grapheme, 0x20
+101         break-if-!=
+102         var color/eax: int <- screen-color-at-idx screen, idx
+103         compare color, fg
+104         break-if-!= $check-screen-row-in-color-from:compare-cells
+105       }
+106       # compare graphemes
+107       $check-screen-row-in-color-from:compare-graphemes: {
+108         # if (g == expected-grapheme) print "."
+109         compare g, expected-grapheme
+110         {
+111           break-if-!=
+112           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
+113           break $check-screen-row-in-color-from:compare-graphemes
+114         }
+115         # otherwise print an error
+116         count-test-failure
+117         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
+118         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
+119         draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
+120         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+121         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
+122         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
+123         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
+124         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
+125         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg
+126         draw-grapheme-at-cursor 0/screen, g, 3/cyan, 0/bg
+127         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+128         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg
+129         move-cursor-to-left-margin-of-next-line 0/screen
+130       }
+131       $check-screen-row-in-color-from:compare-colors: {
+132         var color/eax: int <- screen-color-at-idx screen, idx
+133         compare fg, color
+134         {
+135           break-if-!=
+136           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
+137           break $check-screen-row-in-color-from:compare-colors
+138         }
+139         # otherwise print an error
+140         count-test-failure
+141         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
+142         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
+143         draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
+144         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+145         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
+146         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
+147         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
+148         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
+149         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in color ", 3/fg/cyan, 0/bg
+150         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, fg, 3/fg/cyan, 0/bg
+151         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed color ", 3/fg/cyan, 0/bg
+152         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, color, 3/fg/cyan, 0/bg
+153         move-cursor-to-left-margin-of-next-line 0/screen
+154       }
+155     }
+156     idx <- increment
+157     increment x
+158     loop
+159   }
+160 }
+161 
+162 fn check-screen-row-in-background-color screen: (addr screen), bg: int, y: int, expected: (addr array byte), msg: (addr array byte) {
+163   check-screen-row-in-background-color-from screen, bg, y, 0/x, expected, msg
+164 }
+165 
+166 fn check-screen-row-in-background-color-from screen-on-stack: (addr screen), bg: int, y: int, x: int, expected: (addr array byte), msg: (addr array byte) {
+167   var screen/esi: (addr screen) <- copy screen-on-stack
+168   var idx/ecx: int <- screen-cell-index screen, x, y
+169   # compare 'expected' with the screen contents starting at 'idx', grapheme by grapheme
+170   var e: (stream byte 0x100)
+171   var e-addr/edx: (addr stream byte) <- address e
+172   write e-addr, expected
+173   {
+174     var done?/eax: boolean <- stream-empty? e-addr
+175     compare done?, 0
+176     break-if-!=
+177     var _g/eax: grapheme <- screen-grapheme-at-idx screen, idx
+178     var g/ebx: grapheme <- copy _g
+179     var _expected-grapheme/eax: grapheme <- read-grapheme e-addr
+180     var expected-grapheme/edi: grapheme <- copy _expected-grapheme
+181     $check-screen-row-in-background-color-from:compare-cells: {
+182       # if expected-grapheme is space, null grapheme is also ok
+183       {
+184         compare expected-grapheme, 0x20
+185         break-if-!=
+186         compare g, 0
+187         break-if-= $check-screen-row-in-background-color-from:compare-cells
+188       }
+189       # if expected-grapheme is space, a different background-color is ok
+190       {
+191         compare expected-grapheme, 0x20
+192         break-if-!=
+193         var background-color/eax: int <- screen-background-color-at-idx screen, idx
+194         compare background-color, bg
+195         break-if-!= $check-screen-row-in-background-color-from:compare-cells
+196       }
+197       # compare graphemes
+198       $check-screen-row-in-background-color-from:compare-graphemes: {
+199         # if (g == expected-grapheme) print "."
+200         compare g, expected-grapheme
+201         {
+202           break-if-!=
+203           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
+204           break $check-screen-row-in-background-color-from:compare-graphemes
+205         }
+206         # otherwise print an error
+207         count-test-failure
+208         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
+209         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
+210         draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
+211         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+212         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
+213         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
+214         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
+215         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
+216         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg
+217         draw-grapheme-at-cursor 0/screen, g, 3/cyan, 0/bg
+218         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+219         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg
+220         move-cursor-to-left-margin-of-next-line 0/screen
+221         break $check-screen-row-in-background-color-from:compare-graphemes
+222       }
+223       $check-screen-row-in-background-color-from:compare-background-colors: {
+224         var background-color/eax: int <- screen-background-color-at-idx screen, idx
+225         compare bg, background-color
+226         {
+227           break-if-!=
+228           draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
+229           break $check-screen-row-in-background-color-from:compare-background-colors
+230         }
+231         # otherwise print an error
+232         count-test-failure
+233         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
+234         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg
+235         draw-grapheme-at-cursor 0/screen, expected-grapheme, 3/cyan, 0/bg
+236         move-cursor-rightward-and-downward 0/screen, 0/xmin, 0x80/xmax=screen-width
+237         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg
+238         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
+239         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
+240         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
+241         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in background-color ", 3/fg/cyan, 0/bg
+242         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg/cyan, 0/bg
+243         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed background-color ", 3/fg/cyan, 0/bg
+244         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, background-color, 3/fg/cyan, 0/bg
+245         move-cursor-to-left-margin-of-next-line 0/screen
+246       }
+247     }
+248     idx <- increment
+249     increment x
+250     loop
+251   }
+252 }
+253 
+254 # helpers for checking just background color, not screen contents
+255 # these can validate bg for spaces
+256 
+257 fn check-background-color-in-screen-row screen: (addr screen), bg: int, y: int, expected-bitmap: (addr array byte), msg: (addr array byte) {
+258   check-background-color-in-screen-row-from screen, bg, y, 0/x, expected-bitmap, msg
+259 }
+260 
+261 fn check-background-color-in-screen-row-from screen-on-stack: (addr screen), bg: int, y: int, x: int, expected-bitmap: (addr array byte), msg: (addr array byte) {
+262   var screen/esi: (addr screen) <- copy screen-on-stack
+263   var failure-count: int
+264   var idx/ecx: int <- screen-cell-index screen, x, y
+265   # compare background color where 'expected-bitmap' is a non-space
+266   var e: (stream byte 0x100)
+267   var e-addr/edx: (addr stream byte) <- address e
+268   write e-addr, expected-bitmap
+269   {
+270     var done?/eax: boolean <- stream-empty? e-addr
+271     compare done?, 0
+272     break-if-!=
+273     var _expected-bit/eax: grapheme <- read-grapheme e-addr
+274     var expected-bit/edi: grapheme <- copy _expected-bit
+275     $check-background-color-in-screen-row-from:compare-cells: {
+276       var background-color/eax: int <- screen-background-color-at-idx screen, idx
+277       # if expected-bit is space, assert that background is NOT bg
+278       compare expected-bit, 0x20
+279       {
+280         break-if-!=
+281         compare background-color, bg
+282         break-if-!= $check-background-color-in-screen-row-from:compare-cells
+283         increment failure-count
+284         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
+285         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected (", 3/fg/cyan, 0/bg
+286         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
+287         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
+288         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
+289         draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") to not be in background-color ", 3/fg/cyan, 0/bg
+290         draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg/cyan, 0/bg
+291         move-cursor-to-left-margin-of-next-line 0/screen
+292         break $check-background-color-in-screen-row-from:compare-cells
+293       }
+294       # otherwise assert that background IS bg
+295       compare background-color, bg
+296       break-if-= $check-background-color-in-screen-row-from:compare-cells
+297       increment failure-count
+298       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
+299       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected (", 3/fg/cyan, 0/bg
+300       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg
+301       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg
+302       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg
+303       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") in background-color ", 3/fg/cyan, 0/bg
+304       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, bg, 3/fg/cyan, 0/bg
+305       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " but observed background-color ", 3/fg/cyan, 0/bg
+306       draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, background-color, 3/fg/cyan, 0/bg
+307       move-cursor-to-left-margin-of-next-line 0/screen
+308     }
+309     idx <- increment
+310     increment x
+311     loop
+312   }
+313   # if any assertions failed, count the test as failed
+314   compare failure-count, 0
+315   {
+316     break-if-=
+317     count-test-failure
+318     return
+319   }
+320   # otherwise print a "."
+321   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
+322 }
+323 
+324 fn test-draw-single-grapheme {
+325   var screen-on-stack: screen
+326   var screen/esi: (addr screen) <- address screen-on-stack
+327   initialize-screen screen, 5, 4, 0/no-pixel-graphics
+328   draw-code-point screen, 0x61/a, 0/x, 0/y, 1/fg, 2/bg
+329   check-screen-row screen, 0/y, "a", "F - test-draw-single-grapheme"  # top-left corner of the screen
+330   check-screen-row-in-color screen, 1/fg, 0/y, "a", "F - test-draw-single-grapheme-fg"
+331   check-screen-row-in-background-color screen, 2/bg, 0/y, "a", "F - test-draw-single-grapheme-bg"
+332   check-background-color-in-screen-row screen, 2/bg, 0/y, "x ", "F - test-draw-single-grapheme-bg2"
+333 }
+334 
+335 fn test-draw-multiple-graphemes {
+336   var screen-on-stack: screen
+337   var screen/esi: (addr screen) <- address screen-on-stack
+338   initialize-screen screen, 0x10/rows, 4/cols, 0/no-pixel-graphics
+339   draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "Hello, 世界", 1/fg, 2/bg
+340   check-screen-row screen, 0/y, "Hello, 世界", "F - test-draw-multiple-graphemes"
+341   check-screen-row-in-color screen, 1/fg, 0/y, "Hello, 世界", "F - test-draw-multiple-graphemes-fg"
+342   check-background-color-in-screen-row screen, 2/bg, 0/y, "xxxxxxxxx ", "F - test-draw-multiple-graphemes-bg2"
+343 }
 
diff --git a/html/505colors.mu.html b/html/505colors.mu.html index ee50c7e7..f6f6fe97 100644 --- a/html/505colors.mu.html +++ b/html/505colors.mu.html @@ -18,9 +18,14 @@ a { color:inherit; } .Special { color: #ff6060; } .LineNr { } .Delimiter { color: #c000c0; } +.muTest { color: #5f8700; } +.muRegEdx { color: #878700; } +.muRegEbx { color: #8787af; } .Constant { color: #008787; } +.muRegEax { color: #875f00; } +.muRegEcx { color: #af875f; } .muFunction { color: #af5f00; text-decoration: underline; } -.muTest { color: #5f8700; } +.muRegEsi { color: #87d787; } .muComment { color: #005faf; } --> @@ -61,14 +66,14 @@ if ('onhashchange' in window) { 2 # rgb are in [0, 256) 3 # hsl are also returned in [0, 256) 4 # from https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl - 5 fn hsl r: int, g: int, b: int -> _/ecx: int, _/edx: int, _/ebx: int { - 6 var _max/eax: int <- maximum r, g + 5 fn hsl r: int, g: int, b: int -> _/ecx: int, _/edx: int, _/ebx: int { + 6 var _max/eax: int <- maximum r, g 7 _max <- maximum _max, b - 8 var max/ecx: int <- copy _max - 9 var _min/eax: int <- minimum r, g + 8 var max/ecx: int <- copy _max + 9 var _min/eax: int <- minimum r, g 10 _min <- minimum _min, b - 11 var min/edx: int <- copy _min - 12 var luminance/ebx: int <- copy min + 11 var min/edx: int <- copy _min + 12 var luminance/ebx: int <- copy min 13 luminance <- add max 14 luminance <- shift-right 1 # TODO: round up instead of down 15 # if rgb are all equal, it's a shade of grey @@ -80,9 +85,9 @@ if ('onhashchange' in window) { 21 # saturation = 22 # luminance < 128 | 255*(max-min)/ (max+min) 23 # otherwise | 255*(max-min)/(2*255 - (max+min)) - 24 var nr/esi: int <- copy max + 24 var nr/esi: int <- copy max 25 nr <- subtract min - 26 var dr/eax: int <- copy 0 + 26 var dr/eax: int <- copy 0 27 compare luminance, 0x80 28 { 29 break-if->= @@ -99,24 +104,24 @@ if ('onhashchange' in window) { 40 var q/xmm0: float <- convert nr 41 var tmp/xmm1: float <- convert dr 42 q <- divide tmp - 43 var int-255/eax: int <- copy 0xff + 43 var int-255/eax: int <- copy 0xff 44 tmp <- convert int-255 45 q <- multiply tmp - 46 var saturation/esi: int <- convert q + 46 var saturation/esi: int <- convert q 47 # hue = 48 # red is max | 256.0/6* (g-b)/(max-min) 49 # green is max | 256.0/6*(2.0 + (b-r)/(max-min)) 50 # blue is max | 256.0/6*(4.0 + (r-g)/(max-min)) - 51 var zero/eax: int <- copy 0 + 51 var zero/eax: int <- copy 0 52 var hue-f/xmm0: float <- convert zero - 53 var dr/eax: int <- copy max + 53 var dr/eax: int <- copy max 54 dr <- subtract min 55 var dr-f/xmm1: float <- convert dr 56 $hsl:compute-hue-normalized: { 57 compare r, max 58 { 59 break-if-!= - 60 var nr/eax: int <- copy g + 60 var nr/eax: int <- copy g 61 nr <- subtract b 62 hue-f <- convert nr 63 hue-f <- divide dr-f @@ -125,11 +130,11 @@ if ('onhashchange' in window) { 66 compare g, max 67 { 68 break-if-!= - 69 var nr/eax: int <- copy b + 69 var nr/eax: int <- copy b 70 nr <- subtract r 71 var f/xmm2: float <- convert nr 72 f <- divide dr-f - 73 var two/ecx: int <- copy 2 + 73 var two/ecx: int <- copy 2 74 hue-f <- convert two 75 hue-f <- add f 76 break $hsl:compute-hue-normalized @@ -137,28 +142,28 @@ if ('onhashchange' in window) { 78 compare b, max 79 { 80 break-if-!= - 81 var nr/eax: int <- copy r + 81 var nr/eax: int <- copy r 82 nr <- subtract g 83 var f/xmm2: float <- convert nr 84 f <- divide dr-f - 85 var two/ecx: int <- copy 4 + 85 var two/ecx: int <- copy 4 86 hue-f <- convert two 87 hue-f <- add f 88 break $hsl:compute-hue-normalized 89 } 90 } - 91 var int-256/eax: int <- copy 0x100 + 91 var int-256/eax: int <- copy 0x100 92 var scaling-factor/xmm1: float <- convert int-256 - 93 var int-6/eax: int <- copy 6 + 93 var int-6/eax: int <- copy 6 94 var six-f/xmm2: float <- convert int-6 95 scaling-factor <- divide six-f 96 hue-f <- multiply scaling-factor - 97 var hue/eax: int <- convert hue-f + 97 var hue/eax: int <- convert hue-f 98 # if hue < 0, hue = 256 - hue 99 compare hue, 0 100 { 101 break-if->= -102 var tmp/ecx: int <- copy 0x100 +102 var tmp/ecx: int <- copy 0x100 103 tmp <- subtract hue 104 hue <- copy tmp 105 } @@ -166,9 +171,9 @@ if ('onhashchange' in window) { 107 } 108 109 fn test-hsl-black { -110 var h/ecx: int <- copy 0 -111 var s/edx: int <- copy 0 -112 var l/ebx: int <- copy 0 +110 var h/ecx: int <- copy 0 +111 var s/edx: int <- copy 0 +112 var l/ebx: int <- copy 0 113 h, s, l <- hsl 0, 0, 0 114 check-ints-equal h, 0, "F - test-hsl-black/hue" 115 check-ints-equal s, 0, "F - test-hsl-black/saturation" @@ -176,9 +181,9 @@ if ('onhashchange' in window) { 117 } 118 119 fn test-hsl-white { -120 var h/ecx: int <- copy 0 -121 var s/edx: int <- copy 0 -122 var l/ebx: int <- copy 0 +120 var h/ecx: int <- copy 0 +121 var s/edx: int <- copy 0 +122 var l/ebx: int <- copy 0 123 h, s, l <- hsl 0xff, 0xff, 0xff 124 check-ints-equal h, 0, "F - test-hsl-white/hue" 125 check-ints-equal s, 0, "F - test-hsl-white/saturation" @@ -186,9 +191,9 @@ if ('onhashchange' in window) { 127 } 128 129 fn test-hsl-grey { -130 var h/ecx: int <- copy 0 -131 var s/edx: int <- copy 0 -132 var l/ebx: int <- copy 0 +130 var h/ecx: int <- copy 0 +131 var s/edx: int <- copy 0 +132 var l/ebx: int <- copy 0 133 h, s, l <- hsl 0x30, 0x30, 0x30 134 check-ints-equal h, 0, "F - test-hsl-grey/hue" 135 check-ints-equal s, 0, "F - test-hsl-grey/saturation" @@ -197,9 +202,9 @@ if ('onhashchange' in window) { 138 139 # red hues: 0-0x54 140 fn test-hsl-slightly-red { -141 var h/ecx: int <- copy 0 -142 var s/edx: int <- copy 0 -143 var l/ebx: int <- copy 0 +141 var h/ecx: int <- copy 0 +142 var s/edx: int <- copy 0 +143 var l/ebx: int <- copy 0 144 h, s, l <- hsl 0xff, 0xfe, 0xfe 145 check-ints-equal h, 0, "F - test-hsl-slightly-red/hue" 146 check-ints-equal s, 0xff, "F - test-hsl-slightly-red/saturation" @@ -207,9 +212,9 @@ if ('onhashchange' in window) { 148 } 149 150 fn test-hsl-extremely-red { -151 var h/ecx: int <- copy 0 -152 var s/edx: int <- copy 0 -153 var l/ebx: int <- copy 0 +151 var h/ecx: int <- copy 0 +152 var s/edx: int <- copy 0 +153 var l/ebx: int <- copy 0 154 h, s, l <- hsl 0xff, 0, 0 155 check-ints-equal h, 0, "F - test-hsl-extremely-red/hue" 156 check-ints-equal s, 0xff, "F - test-hsl-extremely-red/saturation" @@ -218,9 +223,9 @@ if ('onhashchange' in window) { 159 160 # green hues: 0x55-0xaa 161 fn test-hsl-slightly-green { -162 var h/ecx: int <- copy 0 -163 var s/edx: int <- copy 0 -164 var l/ebx: int <- copy 0 +162 var h/ecx: int <- copy 0 +163 var s/edx: int <- copy 0 +164 var l/ebx: int <- copy 0 165 h, s, l <- hsl 0xfe, 0xff, 0xfe 166 check-ints-equal h, 0x55, "F - test-hsl-slightly-green/hue" 167 check-ints-equal s, 0xff, "F - test-hsl-slightly-green/saturation" @@ -228,9 +233,9 @@ if ('onhashchange' in window) { 169 } 170 171 fn test-hsl-extremely-green { -172 var h/ecx: int <- copy 0 -173 var s/edx: int <- copy 0 -174 var l/ebx: int <- copy 0 +172 var h/ecx: int <- copy 0 +173 var s/edx: int <- copy 0 +174 var l/ebx: int <- copy 0 175 h, s, l <- hsl 0, 0xff, 0 176 check-ints-equal h, 0x55, "F - test-hsl-extremely-green/hue" 177 check-ints-equal s, 0xff, "F - test-hsl-extremely-green/saturation" @@ -239,9 +244,9 @@ if ('onhashchange' in window) { 180 181 # blue hues: 0xab-0xff 182 fn test-hsl-slightly-blue { -183 var h/ecx: int <- copy 0 -184 var s/edx: int <- copy 0 -185 var l/ebx: int <- copy 0 +183 var h/ecx: int <- copy 0 +184 var s/edx: int <- copy 0 +185 var l/ebx: int <- copy 0 186 h, s, l <- hsl 0xfe, 0xfe, 0xff 187 check-ints-equal h, 0xab, "F - test-hsl-slightly-blue/hue" 188 check-ints-equal s, 0xff, "F - test-hsl-slightly-blue/saturation" @@ -249,9 +254,9 @@ if ('onhashchange' in window) { 190 } 191 192 fn test-hsl-extremely-blue { -193 var h/ecx: int <- copy 0 -194 var s/edx: int <- copy 0 -195 var l/ebx: int <- copy 0 +193 var h/ecx: int <- copy 0 +194 var s/edx: int <- copy 0 +195 var l/ebx: int <- copy 0 196 h, s, l <- hsl 0, 0, 0xff 197 check-ints-equal h, 0xab, "F - test-hsl-extremely-blue/hue" 198 check-ints-equal s, 0xff, "F - test-hsl-extremely-blue/saturation" @@ -261,9 +266,9 @@ if ('onhashchange' in window) { 202 # cyan: 0x7f 203 204 fn test-hsl-cyan { -205 var h/ecx: int <- copy 0 -206 var s/edx: int <- copy 0 -207 var l/ebx: int <- copy 0 +205 var h/ecx: int <- copy 0 +206 var s/edx: int <- copy 0 +207 var l/ebx: int <- copy 0 208 h, s, l <- hsl 0, 0xff, 0xff 209 check-ints-equal h, 0x80, "F - test-hsl-cyan/hue" 210 check-ints-equal s, 0xff, "F - test-hsl-cyan/saturation" @@ -272,8 +277,8 @@ if ('onhashchange' in window) { 213 214 ### 215 -216 fn maximum a: int, b: int -> _/eax: int { -217 var a2/eax: int <- copy a +216 fn maximum a: int, b: int -> _/eax: int { +217 var a2/eax: int <- copy a 218 compare a2, b 219 { 220 break-if-< @@ -282,8 +287,8 @@ if ('onhashchange' in window) { 223 return b 224 } 225 -226 fn minimum a: int, b: int -> _/eax: int { -227 var a2/eax: int <- copy a +226 fn minimum a: int, b: int -> _/eax: int { +227 var a2/eax: int <- copy a 228 compare a2, b 229 { 230 break-if-> diff --git a/html/506math.mu.html b/html/506math.mu.html index 9309b20c..2e4e47fa 100644 --- a/html/506math.mu.html +++ b/html/506math.mu.html @@ -15,9 +15,11 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEdi { color: #87ffd7; } .LineNr { } -.Delimiter { color: #c000c0; } .Constant { color: #008787; } +.muRegEax { color: #875f00; } +.Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .Special { color: #ff6060; } --> @@ -55,7 +57,7 @@ if ('onhashchange' in window) { https://github.com/akkartik/mu/blob/main/506math.mu
- 1 fn abs n: int -> _/eax: int {
+ 1 fn abs n: int -> _/eax: int {
  2   compare n, 0
  3   {
  4     break-if->=
@@ -64,7 +66,7 @@ if ('onhashchange' in window) {
  7   return n
  8 }
  9 
-10 fn sgn n: int -> _/eax: int {
+10 fn sgn n: int -> _/eax: int {
 11   compare n, 0
 12   {
 13     break-if-<=
@@ -77,8 +79,8 @@ if ('onhashchange' in window) {
 20   return 0
 21 }
 22 
-23 fn shift-left-by n: int, bits: int -> _/eax: int {
-24   var i/eax: int <- copy bits
+23 fn shift-left-by n: int, bits: int -> _/eax: int {
+24   var i/eax: int <- copy bits
 25   {
 26     compare i, 0
 27     break-if-<=
@@ -89,8 +91,8 @@ if ('onhashchange' in window) {
 32   return n
 33 }
 34 
-35 fn shift-right-by n: int, bits: int -> _/eax: int {
-36   var i/eax: int <- copy bits
+35 fn shift-right-by n: int, bits: int -> _/eax: int {
+36   var i/eax: int <- copy bits
 37   {
 38     compare i, 0
 39     break-if-<=
@@ -102,8 +104,8 @@ if ('onhashchange' in window) {
 45 }
 46 
 47 fn clear-lowest-bits _n: (addr int), bits: int {
-48   var dest/edi: (addr int) <- copy _n
-49   var n/eax: int <- copy *dest
+48   var dest/edi: (addr int) <- copy _n
+49   var n/eax: int <- copy *dest
 50   n <- shift-right-by n, bits
 51   n <- shift-left-by n, bits
 52   copy-to *dest, n
diff --git a/html/507line.mu.html b/html/507line.mu.html
index 76910f05..5e015dfa 100644
--- a/html/507line.mu.html
+++ b/html/507line.mu.html
@@ -18,6 +18,10 @@ a { color:inherit; }
 .Special { color: #ff6060; }
 .LineNr { }
 .Constant { color: #008787; }
+.muRegEbx { color: #8787af; }
+.muRegEdx { color: #878700; }
+.muRegEcx { color: #af875f; }
+.muRegEax { color: #875f00; }
 .Delimiter { color: #c000c0; }
 .muFunction { color: #af5f00; text-decoration: underline; }
 .muComment { color: #005faf; }
@@ -63,9 +67,9 @@ if ('onhashchange' in window) {
   5   var sy: int
   6   var err: int
   7   # dx = abs(x1-x0)
-  8   var tmp2/ecx: int <- copy x1
+  8   var tmp2/ecx: int <- copy x1
   9   tmp2 <- subtract x0
- 10   var tmp/eax: int <- abs tmp2
+ 10   var tmp/eax: int <- abs tmp2
  11   copy-to dx, tmp
  12   # sx = sgn(x1-x0)
  13   tmp <- sgn tmp2
@@ -84,10 +88,10 @@ if ('onhashchange' in window) {
  26   tmp <- add dx
  27   copy-to err, tmp
  28   #
- 29   var x/ecx: int <- copy x0
- 30   var y/edx: int <- copy y0
+ 29   var x/ecx: int <- copy x0
+ 30   var y/edx: int <- copy y0
  31   $draw-line:loop: {
- 32     pixel screen, x, y, color
+ 32     pixel screen, x, y, color
  33     # if (x == x1 && y == y1) break
  34     {
  35       compare x, x1
@@ -97,7 +101,7 @@ if ('onhashchange' in window) {
  39       break $draw-line:loop
  40     }
  41     # e2 = err*2
- 42     var e2/ebx: int <- copy err
+ 42     var e2/ebx: int <- copy err
  43     e2 <- shift-left 1
  44     # if (e2 >= dy) { err += dy; x += sx; }
  45     {
@@ -120,29 +124,29 @@ if ('onhashchange' in window) {
  62 }
  63 
  64 fn draw-horizontal-line screen: (addr screen), y: int, x0: int, x1: int, color: int {
- 65   var x/eax: int <- copy x0
+ 65   var x/eax: int <- copy x0
  66   {
  67     compare x, x1
  68     break-if->=
- 69     pixel screen, x, y, color
+ 69     pixel screen, x, y, color
  70     x <- increment
  71     loop
  72   }
  73 }
  74 
  75 fn draw-vertical-line screen: (addr screen), x: int, y0: int, y1: int, color: int {
- 76   var y/eax: int <- copy y0
+ 76   var y/eax: int <- copy y0
  77   {
  78     compare y, y1
  79     break-if->=
- 80     pixel screen, x, y, color
+ 80     pixel screen, x, y, color
  81     y <- increment
  82     loop
  83   }
  84 }
  85 
  86 fn draw-rect screen: (addr screen), xmin: int, ymin: int, xmax: int, ymax: int, color: int {
- 87   var y/eax: int <- copy ymin
+ 87   var y/eax: int <- copy ymin
  88   {
  89     compare y, ymax
  90     break-if->=
@@ -153,8 +157,8 @@ if ('onhashchange' in window) {
  95 }
  96 
  97 # 0 <= u <= 1
- 98 fn line-point u: float, x0: int, x1: int -> _/eax: int {
- 99   var one/eax: int <- copy 1
+ 98 fn line-point u: float, x0: int, x1: int -> _/eax: int {
+ 99   var one/eax: int <- copy 1
 100   var u-prime/xmm0: float <- convert one
 101   u-prime <- subtract u
 102   var result/xmm1: float <- convert x0
@@ -162,7 +166,7 @@ if ('onhashchange' in window) {
 104   var term2/xmm2: float <- convert x1
 105   term2 <- multiply u
 106   result <- add term2
-107   var result/eax: int <- convert result
+107   var result/eax: int <- convert result
 108   return result
 109 }
 
diff --git a/html/508circle.mu.html b/html/508circle.mu.html index e64f840d..f1a901f2 100644 --- a/html/508circle.mu.html +++ b/html/508circle.mu.html @@ -15,9 +15,12 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -61,7 +64,7 @@ if ('onhashchange' in window) { 3 var y: int 4 var err: int 5 # x = -r - 6 var tmp/eax: int <- copy radius + 6 var tmp/eax: int <- copy radius 7 tmp <- negate 8 copy-to x, tmp 9 # err = 2 - 2*r @@ -71,33 +74,33 @@ if ('onhashchange' in window) { 13 tmp <- add 2 14 copy-to err, tmp 15 # -16 var tmpx/ecx: int <- copy 0 -17 var tmpy/edx: int <- copy 0 +16 var tmpx/ecx: int <- copy 0 +17 var tmpy/edx: int <- copy 0 18 { 19 # pixel(cx-x, cy+y) 20 tmpx <- copy cx 21 tmpx <- subtract x 22 tmpy <- copy cy 23 tmpy <- add y -24 pixel screen, tmpx, tmpy, color +24 pixel screen, tmpx, tmpy, color 25 # pixel(cx-y, cy-x) 26 tmpx <- copy cx 27 tmpx <- subtract y 28 tmpy <- copy cy 29 tmpy <- subtract x -30 pixel screen, tmpx, tmpy, color +30 pixel screen, tmpx, tmpy, color 31 # pixel(cx+x, cy-y) 32 tmpx <- copy cx 33 tmpx <- add x 34 tmpy <- copy cy 35 tmpy <- subtract y -36 pixel screen, tmpx, tmpy, color +36 pixel screen, tmpx, tmpy, color 37 # pixel(cx+y, cy+x) 38 tmpx <- copy cx 39 tmpx <- add y 40 tmpy <- copy cy 41 tmpy <- add x -42 pixel screen, tmpx, tmpy, color +42 pixel screen, tmpx, tmpy, color 43 # r = err 44 tmp <- copy err 45 copy-to radius, tmp @@ -136,7 +139,7 @@ if ('onhashchange' in window) { 78 } 79 80 fn draw-disc screen: (addr screen), cx: int, cy: int, radius: int, color: int, border-color: int { -81 var r/eax: int <- copy 0 +81 var r/eax: int <- copy 0 82 { 83 compare r, radius 84 break-if->= diff --git a/html/509bezier.mu.html b/html/509bezier.mu.html index a956621f..1f00a2eb 100644 --- a/html/509bezier.mu.html +++ b/html/509bezier.mu.html @@ -15,9 +15,13 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } +.muRegEbx { color: #8787af; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -76,7 +80,7 @@ if ('onhashchange' in window) { 18 var sx: int 19 var sy: int 20 # sx = x2-x1 - 21 var tmp/eax: int <- copy x2 + 21 var tmp/eax: int <- copy x2 22 tmp <- subtract x1 23 copy-to sx, tmp 24 # sy = y2-y1 @@ -120,7 +124,7 @@ if ('onhashchange' in window) { 62 # swap P0 and P2 if necessary 63 { 64 # dist1 = sx*sx + sy*sy - 65 var dist1/ecx: int <- copy sx + 65 var dist1/ecx: int <- copy sx 66 { 67 dist1 <- multiply sx 68 { @@ -136,7 +140,7 @@ if ('onhashchange' in window) { 78 dist1 <- add tmp 79 } 80 # dist2 = xx*xx + yy*yy - 81 var dist2/edx: int <- copy xx + 81 var dist2/edx: int <- copy xx 82 { 83 dist2 <- multiply xx 84 { @@ -167,12 +171,12 @@ if ('onhashchange' in window) { 109 tmp <- add y1 110 copy-to y0, tmp 111 # cur = -cur -112 var negative-1/eax: int <- copy -1 +112 var negative-1/eax: int <- copy -1 113 var negative-1-f/xmm1: float <- convert negative-1 114 cur-f <- multiply negative-1-f 115 } -116 var x/ecx: int <- copy x0 -117 var y/edx: int <- copy y0 +116 var x/ecx: int <- copy x0 +117 var y/edx: int <- copy y0 118 var zero-f: float 119 # plot a curved part if necessary 120 $draw-monotonic-bezier:curve: { @@ -245,11 +249,11 @@ if ('onhashchange' in window) { 187 negate yy 188 negate xy 189 # cur = -cur -190 var negative-1/eax: int <- copy -1 +190 var negative-1/eax: int <- copy -1 191 var negative-1-f/xmm1: float <- convert negative-1 192 cur-f <- multiply negative-1-f 193 } -194 var four/ebx: int <- copy 4 +194 var four/ebx: int <- copy 4 195 var dx-f/xmm5: float <- convert four 196 var dy-f/xmm6: float <- convert four 197 # dx = 4*sy*cur*(x1-x0) + xx - xy @@ -293,7 +297,7 @@ if ('onhashchange' in window) { 235 err-f <- add xy-f 236 # 237 $draw-monotonic-bezier:loop: { -238 pixel screen, x, y, color +238 pixel screen, x, y, color 239 # if (x == x2 && y == y2) return 240 { 241 compare x, x2 @@ -303,10 +307,10 @@ if ('onhashchange' in window) { 245 return 246 } 247 # perform-y-step? = (2*err < dx) -248 var perform-y-step?/eax: boolean <- copy 0/false +248 var perform-y-step?/eax: boolean <- copy 0/false 249 var two-err-f/xmm0: float <- copy err-f 250 { -251 var two/ebx: int <- copy 2 +251 var two/ebx: int <- copy 2 252 var two-f/xmm1: float <- convert two 253 two-err-f <- multiply two-f 254 compare two-err-f, dx-f @@ -353,8 +357,8 @@ if ('onhashchange' in window) { 295 } 296 297 # 0 <= u <= 1 -298 fn bezier-point u: float, x0: int, x1: int, x2: int -> _/eax: int { -299 var one/eax: int <- copy 1 +298 fn bezier-point u: float, x0: int, x1: int, x2: int -> _/eax: int { +299 var one/eax: int <- copy 1 300 var u-prime/xmm0: float <- convert one 301 u-prime <- subtract u 302 var result/xmm1: float <- convert x0 @@ -369,7 +373,7 @@ if ('onhashchange' in window) { 311 term3 <- multiply u 312 term3 <- multiply u 313 result <- add term3 -314 var result/eax: int <- convert result +314 var result/eax: int <- convert result 315 return result 316 } diff --git a/html/boot.subx.html b/html/boot.subx.html index 7d3914d3..e53fe025 100644 --- a/html/boot.subx.html +++ b/html/boot.subx.html @@ -138,7 +138,7 @@ if ('onhashchange' in window) { 78 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es 79 bb/copy-to-bx 0x7e00/imm16 # <==== 80 cd/syscall 0x13/imm8/bios-disk-services - 81 0f 82/jump-if-carry disk_error/disp16 + 81 0f 82/jump-if-carry disk_error/disp16 82 83 # load two more tracks of disk into addresses [0x17800, 0x27400) 84 b4/copy-to-ah 2/imm8/read-drive @@ -152,7 +152,7 @@ if ('onhashchange' in window) { 92 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es 93 bb/copy-to-bx 0/imm16 94 cd/syscall 0x13/imm8/bios-disk-services - 95 0f 82/jump-if-carry disk_error/disp16 + 95 0f 82/jump-if-carry disk_error/disp16 96 97 # load two more tracks of disk into addresses [0x27400, 0x37000) 98 b4/copy-to-ah 2/imm8/read-drive @@ -166,7 +166,7 @@ if ('onhashchange' in window) { 106 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es 107 bb/copy-to-bx 0/imm16 108 cd/syscall 0x13/imm8/bios-disk-services - 109 0f 82/jump-if-carry disk_error/disp16 + 109 0f 82/jump-if-carry disk_error/disp16 110 111 # load two more tracks of disk into addresses [0x37000, 0x46c00) 112 b4/copy-to-ah 2/imm8/read-drive @@ -180,7 +180,7 @@ if ('onhashchange' in window) { 120 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es 121 bb/copy-to-bx 0/imm16 122 cd/syscall 0x13/imm8/bios-disk-services - 123 0f 82/jump-if-carry disk_error/disp16 + 123 0f 82/jump-if-carry disk_error/disp16 124 125 # load two more tracks of disk into addresses [0x46c00, 0x56800) 126 b4/copy-to-ah 2/imm8/read-drive @@ -194,628 +194,642 @@ if ('onhashchange' in window) { 134 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es 135 bb/copy-to-bx 0/imm16 136 cd/syscall 0x13/imm8/bios-disk-services - 137 0f 82/jump-if-carry disk_error/disp16 + 137 0f 82/jump-if-carry disk_error/disp16 138 - 139 # reset es - 140 bb/copy-to-bx 0/imm16 - 141 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es - 142 - 143 # adjust video mode - 144 b4/copy-to-ah 0x4f/imm8 # VBE commands - 145 b0/copy-to-al 2/imm8 # set video mode - 146 bb/copy-to-bx 0x4105/imm16 # 0x0105 | 0x4000 - 147 # 0x0105 = graphics mode 1024x768x256 - 148 # (alternative candidate: 0x0101 for 640x480x256) - 149 # 0x4000 bit = configure linear frame buffer in Bochs emulator; hopefully this doesn't hurt anything when running natively - 150 cd/syscall 0x10/imm8/bios-video-services - 151 - 152 # load information for the (hopefully) current video mode - 153 # mostly just for the address to the linear frame buffer - 154 b4/copy-to-ah 0x4f/imm8 # VBE commands - 155 b0/copy-to-al 1/imm8 # get video mode info - 156 b9/copy-to-cx 0x0105/imm16 # mode we requested - 157 bf/copy-to-di Video-mode-info/imm16 - 158 cd/syscall 0x10/imm8/bios-video-services - 159 - 160 ## switch to 32-bit mode - 161 # load global descriptor table - 162 # We can't refer to the label directly because SubX doesn't do the right - 163 # thing for lgdt, so rather than make errors worse in most places we instead - 164 # pin gdt_descriptor below. - 165 0f 01 2/subop/lgdt 0/mod/indirect 6/rm32/use-disp16 0x7ce0/disp16/gdt_descriptor - 166 # enable paging - 167 0f 20/<-cr 3/mod/direct 0/rm32/eax 0/r32/cr0 - 168 66 83 1/subop/or 3/mod/direct 0/rm32/eax 1/imm8 # eax <- or 0x1 - 169 0f 22/->cr 3/mod/direct 0/rm32/eax 0/r32/cr0 - 170 # far jump to initialize_32bit_mode that sets cs to offset 8 in the gdt in the process - 171 # We can't refer to the label directly because SubX doesn't have syntax for - 172 # segment selectors. So we instead pin initialize_32bit_mode below. - 173 ea/jump-far-absolute 0x00087d00/disp32 # address 0x7d00 in offset 8 of the gdt - 174 - 175 disk_error: - 176 # print 'D' to top-left of screen to indicate disk error - 177 # *0xb8000 <- 0x0f44 - 178 bb/copy-to-bx 0xb800/imm16 - 179 8e/->seg 3/mod/direct 3/rm32/bx 3/r32/ds - 180 b0/copy-to-al 0x44/imm8/D - 181 b4/copy-to-ah 0x0f/imm8/white-on-black - 182 bb/copy-to-bx 0/imm16 - 183 89/<- 0/mod/indirect 7/rm32/bx 0/r32/ax # *ds:bx <- ax - 184 # loop forever - 185 { - 186 eb/jump loop/disp8 - 187 } + 139 # load two more tracks of disk into addresses [0x56800, 0x66400) + 140 b4/copy-to-ah 2/imm8/read-drive + 141 # dl comes conveniently initialized at boot time with the index of the device being booted + 142 b5/copy-to-ch 0/imm8/cylinder + 143 b6/copy-to-dh 0xa/imm8/head # <==== + 144 b1/copy-to-cl 1/imm8/sector # 1-based + 145 b0/copy-to-al 0x7e/imm8/num-sectors # 2*63 = 126 + 146 # address to write sectors to = es:bx = 0x56800, contiguous with boot segment + 147 bb/copy-to-bx 0x5680/imm16 # <==== + 148 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es + 149 bb/copy-to-bx 0/imm16 + 150 cd/syscall 0x13/imm8/bios-disk-services + 151 0f 82/jump-if-carry disk_error/disp16 + 152 + 153 # reset es + 154 bb/copy-to-bx 0/imm16 + 155 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es + 156 + 157 # adjust video mode + 158 b4/copy-to-ah 0x4f/imm8 # VBE commands + 159 b0/copy-to-al 2/imm8 # set video mode + 160 bb/copy-to-bx 0x4105/imm16 # 0x0105 | 0x4000 + 161 # 0x0105 = graphics mode 1024x768x256 + 162 # (alternative candidate: 0x0101 for 640x480x256) + 163 # 0x4000 bit = configure linear frame buffer in Bochs emulator; hopefully this doesn't hurt anything when running natively + 164 cd/syscall 0x10/imm8/bios-video-services + 165 + 166 # load information for the (hopefully) current video mode + 167 # mostly just for the address to the linear frame buffer + 168 b4/copy-to-ah 0x4f/imm8 # VBE commands + 169 b0/copy-to-al 1/imm8 # get video mode info + 170 b9/copy-to-cx 0x0105/imm16 # mode we requested + 171 bf/copy-to-di Video-mode-info/imm16 + 172 cd/syscall 0x10/imm8/bios-video-services + 173 + 174 ## switch to 32-bit mode + 175 # load global descriptor table + 176 # We can't refer to the label directly because SubX doesn't do the right + 177 # thing for lgdt, so rather than make errors worse in most places we instead + 178 # pin gdt_descriptor below. + 179 0f 01 2/subop/lgdt 0/mod/indirect 6/rm32/use-disp16 0x7de0/disp16/gdt_descriptor + 180 # enable paging + 181 0f 20/<-cr 3/mod/direct 0/rm32/eax 0/r32/cr0 + 182 66 83 1/subop/or 3/mod/direct 0/rm32/eax 1/imm8 # eax <- or 0x1 + 183 0f 22/->cr 3/mod/direct 0/rm32/eax 0/r32/cr0 + 184 # far jump to initialize_32bit_mode that sets cs to offset 8 in the gdt in the process + 185 # We can't refer to the label directly because SubX doesn't have syntax for + 186 # segment selectors. So we instead pin initialize_32bit_mode below. + 187 ea/jump-far-absolute 0x00087e00/disp32 # address 0x7e00 in offset 8 of the gdt 188 - 189 ## GDT: 3 records of 8 bytes each - 190 == data 0x7ce0 - 191 gdt_descriptor: - 192 0x17/imm16 # final index of gdt = size of gdt - 1 - 193 gdt_start/imm32/start - 194 - 195 gdt_start: - 196 # offset 0: gdt_null: mandatory null descriptor - 197 00 00 00 00 00 00 00 00 - 198 # offset 8: gdt_code - 199 ff ff # limit[0:16] - 200 00 00 00 # base[0:24] - 201 9a # 1/present 00/privilege 1/descriptor type = 1001b - 202 # 1/code 0/conforming 1/readable 0/accessed = 1010b - 203 cf # 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b - 204 # limit[16:20] = 1111b - 205 00 # base[24:32] - 206 # offset 16: gdt_data - 207 ff ff # limit[0:16] - 208 00 00 00 # base[0:24] - 209 92 # 1/present 00/privilege 1/descriptor type = 1001b - 210 # 0/data 0/conforming 1/readable 0/accessed = 0010b - 211 cf # same as gdt_code - 212 00 # base[24:32] - 213 # gdt_end: - 214 - 215 ## 32-bit code from this point - 216 - 217 == code 0x7d00 - 218 initialize_32bit_mode: - 219 66 b8/copy-to-ax 0x10/imm16 # offset 16 from gdt_start - 220 8e/->seg 3/mod/direct 0/rm32/ax 3/r32/ds - 221 8e/->seg 3/mod/direct 0/rm32/ax 2/r32/ss - 222 8e/->seg 3/mod/direct 0/rm32/ax 0/r32/es - 223 8e/->seg 3/mod/direct 0/rm32/ax 4/r32/fs - 224 8e/->seg 3/mod/direct 0/rm32/ax 5/r32/gs - 225 - 226 bc/copy-to-esp 0x02000000/imm32 - 227 - 228 ## load interrupt handlers - 229 # We can't refer to the label directly because SubX doesn't do the right - 230 # thing for lidt, so rather than make errors worse in most places we instead - 231 # pin idt_descriptor below. - 232 0f 01 3/subop/lidt 0/mod/indirect 5/rm32/use-disp32 0x7e00/disp32/idt_descriptor - 233 - 234 # For now, not bothering reprogramming the IRQ to not conflict with software - 235 # exceptions. - 236 # https://wiki.osdev.org/index.php?title=8259_PIC&oldid=24650#Protected_Mode - 237 # - 238 # Interrupt 1 (keyboard) conflicts with debugger faults. We don't use a - 239 # debugger. - 240 # Reference: - 241 # https://wiki.osdev.org/Exceptions - 242 - 243 # enable timer IRQ0 and keyboard IRQ1 - 244 b0/copy-to-al 0xfc/imm8 # disable mask for IRQ0 and IRQ1 - 245 e6/write-al-into-port 0x21/imm8 - 246 - 247 fb/enable-interrupts - 248 - 249 (initialize-mouse) - 250 - 251 ## enable floating point - 252 db/floating-point-coprocessor e3/initialize - 253 # eax <- cr4 - 254 0f 20/<-cr 3/mod/direct 0/rm32/eax 4/r32/cr4 - 255 # eax <- or bit 9 - 256 0f ba/bit-test 5/subop/bit-test-and-set 3/mod/direct 0/rm32/eax 9/imm8 - 257 # cr4 <- eax - 258 0f 22/->cr 3/mod/direct 0/rm32/eax 4/r32/cr4 - 259 - 260 e9/jump Entry/disp32 - 261 - 262 == boot-sector-marker 0x7dfe - 263 # final 2 bytes of boot sector - 264 55 aa - 265 - 266 ## sector 2 onwards loaded by load_disk, not automatically on boot - 267 - 268 == data 0x7e00 - 269 idt_descriptor: - 270 ff 03 # final index of idt = size of idt - 1 - 271 idt_start/imm32/start - 272 - 273 +-- 55 lines: # interrupt descriptor table ---------------------------------------------------------------------------------------------------------------------------------------------- - 328 - 329 == code - 330 - 331 null-interrupt-handler: - 332 # prologue - 333 # Don't disable interrupts; the timer has the highest priority anyway, - 334 # and this interrupt triggers extremely frequently. - 335 fa/disable-interrupts - 336 60/push-all-registers - 337 9c/push-flags - 338 # acknowledge interrupt - 339 b0/copy-to-al 0x20/imm8 - 340 e6/write-al-into-port 0x20/imm8 - 341 31/xor %eax 0/r32/eax - 342 $null-interrupt-handler:epilogue: - 343 # epilogue - 344 9d/pop-flags - 345 61/pop-all-registers - 346 fb/enable-interrupts - 347 cf/return-from-interrupt - 348 - 349 timer-interrupt-handler: - 350 # prologue - 351 # Don't disable interrupts; the timer has the highest priority anyway, - 352 # and this interrupt triggers extremely frequently. - 353 fa/disable-interrupts - 354 60/push-all-registers - 355 9c/push-flags - 356 # acknowledge interrupt - 357 b0/copy-to-al 0x20/imm8 - 358 e6/write-al-into-port 0x20/imm8 - 359 31/xor %eax 0/r32/eax - 360 $timer-interrupt-handler:epilogue: - 361 # epilogue - 362 9d/pop-flags - 363 61/pop-all-registers - 364 fb/enable-interrupts - 365 cf/return-from-interrupt - 366 - 367 keyboard-interrupt-handler: - 368 # prologue - 369 fa/disable-interrupts - 370 60/push-all-registers - 371 9c/push-flags - 372 # acknowledge interrupt - 373 b0/copy-to-al 0x20/imm8 - 374 e6/write-al-into-port 0x20/imm8 - 375 31/xor %eax 0/r32/eax - 376 # check output buffer of 8042 keyboard controller (https://web.archive.org/web/20040604041507/http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/keyboard/atkeyboard.html) - 377 e4/read-port-into-al 0x64/imm8 - 378 a8/test-bits-in-al 0x01/imm8 # set zf if bit 0 (least significant) is not set - 379 0f 84/jump-if-not-set $keyboard-interrupt-handler:epilogue/disp32 - 380 # - if keyboard buffer is full, return - 381 # var dest-addr/ecx: (addr byte) = (keyboard-buffer + *keyboard-buffer:write) - 382 31/xor %ecx 1/r32/ecx - 383 8a/byte-> *Keyboard-buffer:write 1/r32/cl - 384 81 0/subop/add %ecx Keyboard-buffer:data/imm32 - 385 # al = *dest-addr - 386 8a/byte-> *ecx 0/r32/al - 387 # if (al != 0) return - 388 3c/compare-al-and 0/imm8 - 389 0f 85/jump-if-!= $keyboard-interrupt-handler:epilogue/disp32 - 390 # - read keycode - 391 e4/read-port-into-al 0x60/imm8 - 392 # - key released - 393 # if (al == 0xaa) shift = false # left shift is being lifted - 394 { - 395 3c/compare-al-and 0xaa/imm8 - 396 75/jump-if-!= break/disp8 - 397 # *shift = 0 - 398 c7 0/subop/copy *Keyboard-shift-pressed? 0/imm32 - 399 } - 400 # if (al == 0xb6) shift = false # right shift is being lifted - 401 { - 402 3c/compare-al-and 0xb6/imm8 - 403 75/jump-if-!= break/disp8 - 404 # *shift = 0 - 405 c7 0/subop/copy *Keyboard-shift-pressed? 0/imm32 - 406 } - 407 # if (al == 0x9d) ctrl = false # ctrl is being lifted + 189 disk_error: + 190 # print 'D' to top-left of screen to indicate disk error + 191 # *0xb8000 <- 0x0f44 + 192 bb/copy-to-bx 0xb800/imm16 + 193 8e/->seg 3/mod/direct 3/rm32/bx 3/r32/ds + 194 b0/copy-to-al 0x44/imm8/D + 195 b4/copy-to-ah 0x0f/imm8/white-on-black + 196 bb/copy-to-bx 0/imm16 + 197 89/<- 0/mod/indirect 7/rm32/bx 0/r32/ax # *ds:bx <- ax + 198 # loop forever + 199 { + 200 eb/jump loop/disp8 + 201 } + 202 + 203 ## GDT: 3 records of 8 bytes each + 204 == data 0x7de0 + 205 gdt_descriptor: + 206 0x17/imm16 # final index of gdt = size of gdt - 1 + 207 gdt_start/imm32/start + 208 + 209 gdt_start: + 210 # offset 0: gdt_null: mandatory null descriptor + 211 00 00 00 00 00 00 00 00 + 212 # offset 8: gdt_code + 213 ff ff # limit[0:16] + 214 00 00 00 # base[0:24] + 215 9a # 1/present 00/privilege 1/descriptor type = 1001b + 216 # 1/code 0/conforming 1/readable 0/accessed = 1010b + 217 cf # 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b + 218 # limit[16:20] = 1111b + 219 00 # base[24:32] + 220 # offset 16: gdt_data + 221 ff ff # limit[0:16] + 222 00 00 00 # base[0:24] + 223 92 # 1/present 00/privilege 1/descriptor type = 1001b + 224 # 0/data 0/conforming 1/readable 0/accessed = 0010b + 225 cf # same as gdt_code + 226 00 # base[24:32] + 227 # gdt_end: + 228 + 229 == boot-sector-marker 0x7dfe + 230 # final 2 bytes of boot sector + 231 55 aa + 232 + 233 ## sector 2 onwards loaded by load_disk, not automatically on boot + 234 + 235 ## 32-bit code from this point + 236 + 237 == code 0x7e00 + 238 initialize_32bit_mode: + 239 66 b8/copy-to-ax 0x10/imm16 # offset 16 from gdt_start + 240 8e/->seg 3/mod/direct 0/rm32/ax 3/r32/ds + 241 8e/->seg 3/mod/direct 0/rm32/ax 2/r32/ss + 242 8e/->seg 3/mod/direct 0/rm32/ax 0/r32/es + 243 8e/->seg 3/mod/direct 0/rm32/ax 4/r32/fs + 244 8e/->seg 3/mod/direct 0/rm32/ax 5/r32/gs + 245 + 246 bc/copy-to-esp 0x02000000/imm32 + 247 + 248 ## load interrupt handlers + 249 # We can't refer to the label directly because SubX doesn't do the right + 250 # thing for lidt, so rather than make errors worse in most places we instead + 251 # pin idt_descriptor below. + 252 0f 01 3/subop/lidt 0/mod/indirect 5/rm32/use-disp32 0x7f00/disp32/idt_descriptor + 253 + 254 # For now, not bothering reprogramming the IRQ to not conflict with software + 255 # exceptions. + 256 # https://wiki.osdev.org/index.php?title=8259_PIC&oldid=24650#Protected_Mode + 257 # + 258 # Interrupt 1 (keyboard) conflicts with debugger faults. We don't use a + 259 # debugger. + 260 # Reference: + 261 # https://wiki.osdev.org/Exceptions + 262 + 263 # enable timer IRQ0 and keyboard IRQ1 + 264 b0/copy-to-al 0xfc/imm8 # disable mask for IRQ0 and IRQ1 + 265 e6/write-al-into-port 0x21/imm8 + 266 + 267 fb/enable-interrupts + 268 + 269 (initialize-mouse) + 270 + 271 ## enable floating point + 272 db/floating-point-coprocessor e3/initialize + 273 # eax <- cr4 + 274 0f 20/<-cr 3/mod/direct 0/rm32/eax 4/r32/cr4 + 275 # eax <- or bit 9 + 276 0f ba/bit-test 5/subop/bit-test-and-set 3/mod/direct 0/rm32/eax 9/imm8 + 277 # cr4 <- eax + 278 0f 22/->cr 3/mod/direct 0/rm32/eax 4/r32/cr4 + 279 + 280 e9/jump Entry/disp32 + 281 + 282 == data 0x7f00 + 283 idt_descriptor: + 284 ff 03 # final index of idt = size of idt - 1 + 285 idt_start/imm32/start + 286 + 287 +-- 55 lines: # interrupt descriptor table ---------------------------------------------------------------------------------------------------------------------------------------------- + 342 + 343 == code + 344 + 345 null-interrupt-handler: + 346 # prologue + 347 # Don't disable interrupts; the timer has the highest priority anyway, + 348 # and this interrupt triggers extremely frequently. + 349 fa/disable-interrupts + 350 60/push-all-registers + 351 9c/push-flags + 352 # acknowledge interrupt + 353 b0/copy-to-al 0x20/imm8 + 354 e6/write-al-into-port 0x20/imm8 + 355 31/xor %eax 0/r32/eax + 356 $null-interrupt-handler:epilogue: + 357 # epilogue + 358 9d/pop-flags + 359 61/pop-all-registers + 360 fb/enable-interrupts + 361 cf/return-from-interrupt + 362 + 363 timer-interrupt-handler: + 364 # prologue + 365 # Don't disable interrupts; the timer has the highest priority anyway, + 366 # and this interrupt triggers extremely frequently. + 367 fa/disable-interrupts + 368 60/push-all-registers + 369 9c/push-flags + 370 # acknowledge interrupt + 371 b0/copy-to-al 0x20/imm8 + 372 e6/write-al-into-port 0x20/imm8 + 373 31/xor %eax 0/r32/eax + 374 $timer-interrupt-handler:epilogue: + 375 # epilogue + 376 9d/pop-flags + 377 61/pop-all-registers + 378 fb/enable-interrupts + 379 cf/return-from-interrupt + 380 + 381 keyboard-interrupt-handler: + 382 # prologue + 383 fa/disable-interrupts + 384 60/push-all-registers + 385 9c/push-flags + 386 # acknowledge interrupt + 387 b0/copy-to-al 0x20/imm8 + 388 e6/write-al-into-port 0x20/imm8 + 389 31/xor %eax 0/r32/eax + 390 # check output buffer of 8042 keyboard controller (https://web.archive.org/web/20040604041507/http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/keyboard/atkeyboard.html) + 391 e4/read-port-into-al 0x64/imm8 + 392 a8/test-bits-in-al 0x01/imm8 # set zf if bit 0 (least significant) is not set + 393 0f 84/jump-if-not-set $keyboard-interrupt-handler:epilogue/disp32 + 394 # - if keyboard buffer is full, return + 395 # var dest-addr/ecx: (addr byte) = (keyboard-buffer + *keyboard-buffer:write) + 396 31/xor %ecx 1/r32/ecx + 397 8a/byte-> *Keyboard-buffer:write 1/r32/cl + 398 81 0/subop/add %ecx Keyboard-buffer:data/imm32 + 399 # al = *dest-addr + 400 8a/byte-> *ecx 0/r32/al + 401 # if (al != 0) return + 402 3c/compare-al-and 0/imm8 + 403 0f 85/jump-if-!= $keyboard-interrupt-handler:epilogue/disp32 + 404 # - read keycode + 405 e4/read-port-into-al 0x60/imm8 + 406 # - key released + 407 # if (al == 0xaa) shift = false # left shift is being lifted 408 { - 409 3c/compare-al-and 0x9d/imm8 + 409 3c/compare-al-and 0xaa/imm8 410 75/jump-if-!= break/disp8 - 411 # *ctrl = 0 - 412 c7 0/subop/copy *Keyboard-ctrl-pressed? 0/imm32 + 411 # *shift = 0 + 412 c7 0/subop/copy *Keyboard-shift-pressed? 0/imm32 413 } - 414 # if (al & 0x80) a key is being lifted; return - 415 50/push-eax - 416 24/and-al-with 0x80/imm8 - 417 3c/compare-al-and 0/imm8 - 418 58/pop-to-eax - 419 75/jump-if-!= $keyboard-interrupt-handler:epilogue/disp8 - 420 # - key pressed - 421 # if (al == 0x2a) shift = true, return # left shift pressed + 414 # if (al == 0xb6) shift = false # right shift is being lifted + 415 { + 416 3c/compare-al-and 0xb6/imm8 + 417 75/jump-if-!= break/disp8 + 418 # *shift = 0 + 419 c7 0/subop/copy *Keyboard-shift-pressed? 0/imm32 + 420 } + 421 # if (al == 0x9d) ctrl = false # ctrl is being lifted 422 { - 423 3c/compare-al-and 0x2a/imm8 + 423 3c/compare-al-and 0x9d/imm8 424 75/jump-if-!= break/disp8 - 425 # *shift = 1 - 426 c7 0/subop/copy *Keyboard-shift-pressed? 1/imm32 - 427 # return - 428 eb/jump $keyboard-interrupt-handler:epilogue/disp8 - 429 } - 430 # if (al == 0x36) shift = true, return # right shift pressed - 431 { - 432 3c/compare-al-and 0x36/imm8 - 433 75/jump-if-!= break/disp8 - 434 # *shift = 1 - 435 c7 0/subop/copy *Keyboard-shift-pressed? 1/imm32 - 436 # return - 437 eb/jump $keyboard-interrupt-handler:epilogue/disp8 - 438 } - 439 # if (al == 0x1d) ctrl = true, return - 440 { - 441 3c/compare-al-and 0x1d/imm8 - 442 75/jump-if-!= break/disp8 - 443 # *ctrl = 1 - 444 c7 0/subop/copy *Keyboard-ctrl-pressed? 1/imm32 - 445 # return - 446 eb/jump $keyboard-interrupt-handler:epilogue/disp8 - 447 } - 448 # - convert key to character - 449 # if (shift) use keyboard shift map - 450 { - 451 81 7/subop/compare *Keyboard-shift-pressed? 0/imm32 - 452 74/jump-if-= break/disp8 - 453 # sigils don't currently support labels inside *(eax+label) - 454 05/add-to-eax Keyboard-shift-map/imm32 - 455 8a/byte-> *eax 0/r32/al - 456 eb/jump $keyboard-interrupt-handler:select-map-done/disp8 - 457 } - 458 # if (ctrl) al = *(ctrl map + al) - 459 { - 460 81 7/subop/compare *Keyboard-ctrl-pressed? 0/imm32 - 461 74/jump-if-= break/disp8 - 462 05/add-to-eax Keyboard-ctrl-map/imm32 - 463 8a/byte-> *eax 0/r32/al - 464 eb/jump $keyboard-interrupt-handler:select-map-done/disp8 - 465 } - 466 # otherwise al = *(normal map + al) - 467 05/add-to-eax Keyboard-normal-map/imm32 - 468 8a/byte-> *eax 0/r32/al - 469 $keyboard-interrupt-handler:select-map-done: - 470 # - if there's no character mapping, return - 471 { - 472 3c/compare-al-and 0/imm8 - 473 74/jump-if-= break/disp8 - 474 # - store al in keyboard buffer - 475 88/<- *ecx 0/r32/al - 476 # increment index - 477 fe/increment-byte *Keyboard-buffer:write - 478 # clear top nibble of index (keyboard buffer is circular) - 479 80 4/subop/and-byte *Keyboard-buffer:write 0x0f/imm8 - 480 } - 481 $keyboard-interrupt-handler:epilogue: - 482 # epilogue - 483 9d/pop-flags - 484 61/pop-all-registers - 485 fb/enable-interrupts - 486 cf/return-from-interrupt - 487 - 488 == data - 489 Keyboard-shift-pressed?: # boolean - 490 0/imm32 - 491 - 492 Keyboard-ctrl-pressed?: # boolean - 493 0/imm32 - 494 - 495 # var keyboard circular buffer - 496 Keyboard-buffer:write: # nibble - 497 0/imm32 - 498 Keyboard-buffer:read: # nibble - 499 0/imm32 - 500 Keyboard-buffer:data: # byte[16] - 501 00 00 00 00 - 502 00 00 00 00 - 503 00 00 00 00 - 504 00 00 00 00 + 425 # *ctrl = 0 + 426 c7 0/subop/copy *Keyboard-ctrl-pressed? 0/imm32 + 427 } + 428 # if (al & 0x80) a key is being lifted; return + 429 50/push-eax + 430 24/and-al-with 0x80/imm8 + 431 3c/compare-al-and 0/imm8 + 432 58/pop-to-eax + 433 75/jump-if-!= $keyboard-interrupt-handler:epilogue/disp8 + 434 # - key pressed + 435 # if (al == 0x2a) shift = true, return # left shift pressed + 436 { + 437 3c/compare-al-and 0x2a/imm8 + 438 75/jump-if-!= break/disp8 + 439 # *shift = 1 + 440 c7 0/subop/copy *Keyboard-shift-pressed? 1/imm32 + 441 # return + 442 eb/jump $keyboard-interrupt-handler:epilogue/disp8 + 443 } + 444 # if (al == 0x36) shift = true, return # right shift pressed + 445 { + 446 3c/compare-al-and 0x36/imm8 + 447 75/jump-if-!= break/disp8 + 448 # *shift = 1 + 449 c7 0/subop/copy *Keyboard-shift-pressed? 1/imm32 + 450 # return + 451 eb/jump $keyboard-interrupt-handler:epilogue/disp8 + 452 } + 453 # if (al == 0x1d) ctrl = true, return + 454 { + 455 3c/compare-al-and 0x1d/imm8 + 456 75/jump-if-!= break/disp8 + 457 # *ctrl = 1 + 458 c7 0/subop/copy *Keyboard-ctrl-pressed? 1/imm32 + 459 # return + 460 eb/jump $keyboard-interrupt-handler:epilogue/disp8 + 461 } + 462 # - convert key to character + 463 # if (shift) use keyboard shift map + 464 { + 465 81 7/subop/compare *Keyboard-shift-pressed? 0/imm32 + 466 74/jump-if-= break/disp8 + 467 # sigils don't currently support labels inside *(eax+label) + 468 05/add-to-eax Keyboard-shift-map/imm32 + 469 8a/byte-> *eax 0/r32/al + 470 eb/jump $keyboard-interrupt-handler:select-map-done/disp8 + 471 } + 472 # if (ctrl) al = *(ctrl map + al) + 473 { + 474 81 7/subop/compare *Keyboard-ctrl-pressed? 0/imm32 + 475 74/jump-if-= break/disp8 + 476 05/add-to-eax Keyboard-ctrl-map/imm32 + 477 8a/byte-> *eax 0/r32/al + 478 eb/jump $keyboard-interrupt-handler:select-map-done/disp8 + 479 } + 480 # otherwise al = *(normal map + al) + 481 05/add-to-eax Keyboard-normal-map/imm32 + 482 8a/byte-> *eax 0/r32/al + 483 $keyboard-interrupt-handler:select-map-done: + 484 # - if there's no character mapping, return + 485 { + 486 3c/compare-al-and 0/imm8 + 487 74/jump-if-= break/disp8 + 488 # - store al in keyboard buffer + 489 88/<- *ecx 0/r32/al + 490 # increment index + 491 fe/increment-byte *Keyboard-buffer:write + 492 # clear top nibble of index (keyboard buffer is circular) + 493 80 4/subop/and-byte *Keyboard-buffer:write 0x0f/imm8 + 494 } + 495 $keyboard-interrupt-handler:epilogue: + 496 # epilogue + 497 9d/pop-flags + 498 61/pop-all-registers + 499 fb/enable-interrupts + 500 cf/return-from-interrupt + 501 + 502 == data + 503 Keyboard-shift-pressed?: # boolean + 504 0/imm32 505 - 506 +-- 95 lines: # Keyboard maps for translating keys to ASCII ----------------------------------------------------------------------------------------------------------------------------- - 601 - 602 Video-mode-info: - 603 +-- 53 lines: # video mode info --------------------------------------------------------------------------------------------------------------------------------------------------------- - 656 - 657 Font: - 658 +--236 lines: # Bitmaps for some ASCII characters (soon Unicode) ------------------------------------------------------------------------------------------------------------------------ - 894 - 895 ## Controlling IDE (ATA) hard disks - 896 # Uses 28-bit PIO mode. - 897 # Inspired by https://colorforth.github.io/ide.html - 898 # - 899 # Resources: - 900 # https://wiki.osdev.org/ATA_PIO_Mode - 901 # https://forum.osdev.org/viewtopic.php?f=1&p=167798 - 902 # read-sector, according to https://www.scs.stanford.edu/11wi-cs140/pintos/specs/ata-3-std.pdf - 903 - 904 == data - 905 - 906 # code disk - 907 # All ports are 8-bit except data-port, which is 16-bit. - 908 Primary-bus-primary-drive: - 909 # command-port: int (write) - 910 0x1f7/imm32 - 911 # status-port: int (read) - 912 0x1f7/imm32 - 913 # alternative-status-port: int (read) - 914 0x3f6/imm32 - 915 # error-port: int (read) - 916 0x1f1/imm32 - 917 # drive-and-head-port: int - 918 0x1f6/imm32 - 919 # sector-count-port: int - 920 0x1f2/imm32 - 921 # lba-low-port: int - 922 0x1f3/imm32 - 923 # lba-mid-port: int - 924 0x1f4/imm32 - 925 # lba-high-port: int - 926 0x1f5/imm32 - 927 # data-port: int - 928 0x1f0/imm32 - 929 # drive-code: byte # only drive-specific field - 930 0xe0/imm32 # LBA mode also enabled - 931 - 932 # data disk - 933 # All ports are 8-bit except data-port, which is 16-bit. - 934 Primary-bus-secondary-drive: - 935 # command-port: int (write) - 936 0x1f7/imm32 - 937 # status-port: int (read) - 938 0x1f7/imm32 - 939 # alternative-status-port: int (read) - 940 0x3f6/imm32 - 941 # error-port: int (read) - 942 0x1f1/imm32 - 943 # drive-and-head-port: int - 944 0x1f6/imm32 - 945 # sector-count-port: int - 946 0x1f2/imm32 - 947 # lba-low-port: int - 948 0x1f3/imm32 - 949 # lba-mid-port: int - 950 0x1f4/imm32 - 951 # lba-high-port: int - 952 0x1f5/imm32 - 953 # data-port: int - 954 0x1f0/imm32 - 955 # drive-code: byte # only drive-specific field - 956 0xf0/imm32 # LBA mode also enabled - 957 - 958 == code - 959 - 960 load-sectors: # disk: (addr disk), lba: int, n: int, out: (addr stream byte) - 961 # . prologue - 962 55/push-ebp - 963 89/<- %ebp 4/r32/esp - 964 # . save registers - 965 50/push-eax - 966 51/push-ecx - 967 52/push-edx - 968 # check for drive - 969 (drive-exists? *(ebp+8)) # => eax - 970 3d/compare-eax-and 0/imm32/false - 971 0f 84/jump-if-= $load-sectors:end/disp32 - 972 # kick off read - 973 (ata-drive-select *(ebp+8) *(ebp+0xc)) - 974 (clear-ata-error *(ebp+8)) - 975 (ata-sector-count *(ebp+8) *(ebp+0x10)) - 976 (ata-lba *(ebp+8) *(ebp+0xc)) - 977 (ata-command *(ebp+8) 0x20) # read sectors with retries - 978 # for each sector - 979 { - 980 # poll for results - 981 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "waiting for sector.." 7 0) - 982 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "." 7 0) - 983 (while-ata-busy *(ebp+8)) - 984 (until-ata-data-available *(ebp+8)) - 985 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "reading\n" 7 0) - 986 # var data-port/edx = disk->data-port - 987 8b/-> *(ebp+8) 0/r32/eax - 988 8b/-> *(eax+0x24) 2/r32/edx - 989 # emit results - 990 31/xor %eax 0/r32/eax - 991 b9/copy-to-ecx 0x200/imm32 # 512 bytes per sector - 992 { - 993 81 7/subop/compare %ecx 0/imm32 - 994 74/jump-if-= break/disp8 - 995 66 ed/read-port-dx-into-ax - 996 # write 2 bytes to stream one at a time - 997 (append-byte *(ebp+0x14) %eax) - 998 49/decrement-ecx - 999 c1/shift 5/subop/right-padding-zeroes %eax 8/imm8 -1000 (append-byte *(ebp+0x14) %eax) -1001 49/decrement-ecx -1002 eb/jump loop/disp8 -1003 } -1004 # next sector -1005 ff 1/subop/decrement *(ebp+0x10) -1006 #? (draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+0x10) 0xc 0) -1007 81 7/subop/compare *(ebp+0x10) 0/imm32 -1008 7e/jump-if-<= break/disp8 -1009 (wait-400ns *(ebp+8)) -1010 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "next sector\n" 7 0) -1011 e9/jump loop/disp32 -1012 } -1013 $load-sectors:end: -1014 # . restore registers -1015 5a/pop-to-edx -1016 59/pop-to-ecx -1017 58/pop-to-eax -1018 # . epilogue -1019 89/<- %esp 5/r32/ebp -1020 5d/pop-to-ebp -1021 c3/return -1022 -1023 store-sectors: # disk: (addr disk), lba: int, n: int, in: (addr stream byte) -1024 # . prologue -1025 55/push-ebp -1026 89/<- %ebp 4/r32/esp -1027 # . save registers -1028 50/push-eax -1029 51/push-ecx -1030 52/push-edx -1031 53/push-ebx -1032 # check for drive -1033 (drive-exists? *(ebp+8)) # => eax -1034 3d/compare-eax-and 0/imm32/false -1035 0f 84/jump-if-= $store-sectors:end/disp32 -1036 # kick off write -1037 (ata-drive-select *(ebp+8) *(ebp+0xc)) -1038 (clear-ata-error *(ebp+8)) -1039 (ata-sector-count *(ebp+8) *(ebp+0x10)) -1040 (ata-lba *(ebp+8) *(ebp+0xc)) -1041 (ata-command *(ebp+8) 0x30) # write sectors with retries -1042 # for each sector -1043 #? (set-cursor-position 0 0 0) -1044 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "0" 7 0) -1045 { -1046 # wait -1047 (while-ata-busy *(ebp+8)) -1048 (until-ata-ready-for-data *(ebp+8)) -1049 # var data-port/edx = disk->data-port -1050 8b/-> *(ebp+8) 0/r32/eax -1051 8b/-> *(eax+0x24) 2/r32/edx -1052 # send data -1053 b9/copy-to-ecx 0x200/imm32 # 512 bytes per sector -1054 # . var first-byte/ebx: byte -1055 # . when it's more than 0xff, we're at an even-numbered byte -1056 bb/copy-to-ebx 0xffff/imm32 -1057 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "D" 7 0) -1058 $store-sectors:store-sector: -1059 { -1060 81 7/subop/compare %ecx 0/imm32 -1061 74/jump-if-= break/disp8 -1062 # this loop is slow, but the ATA spec also requires a small delay -1063 (stream-empty? *(ebp+0x14)) # => eax -1064 3d/compare-eax-and 0/imm32/false -1065 75/jump-if-!= break/disp8 -1066 # read byte from stream -1067 (read-byte *(ebp+0x14)) # => eax -1068 # if we're at an odd-numbered byte, save it to first-byte -1069 81 7/subop/compare %ebx 0xff/imm32 -1070 { -1071 7e/jump-if-<= break/disp8 -1072 89/<- %ebx 0/r32/eax -1073 eb/jump $store-sectors:store-sector/disp8 -1074 } -1075 # otherwise OR it with first-byte and write it out -1076 c1/shift 4/subop/left %eax 8/imm8 -1077 09/or %eax 3/r32/ebx -1078 66 ef/write-ax-into-port-dx -1079 49/decrement-ecx -1080 49/decrement-ecx -1081 # reset first-byte -1082 bb/copy-to-ebx 0xffff/imm32 -1083 eb/jump loop/disp8 -1084 } -1085 # write out final first-byte if necessary -1086 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "I" 7 0) -1087 81 7/subop/compare %ebx 0xff/imm32 -1088 { -1089 7f/jump-if-> break/disp8 -1090 89/<- %eax 3/r32/ebx -1091 66 ef/write-ax-into-port-dx -1092 49/decrement-ecx + 506 Keyboard-ctrl-pressed?: # boolean + 507 0/imm32 + 508 + 509 # var keyboard circular buffer + 510 Keyboard-buffer:write: # nibble + 511 0/imm32 + 512 Keyboard-buffer:read: # nibble + 513 0/imm32 + 514 Keyboard-buffer:data: # byte[16] + 515 00 00 00 00 + 516 00 00 00 00 + 517 00 00 00 00 + 518 00 00 00 00 + 519 + 520 +-- 95 lines: # Keyboard maps for translating keys to ASCII ----------------------------------------------------------------------------------------------------------------------------- + 615 + 616 Video-mode-info: + 617 +-- 53 lines: # video mode info --------------------------------------------------------------------------------------------------------------------------------------------------------- + 670 + 671 Font: + 672 +--236 lines: # Bitmaps for some ASCII characters (soon Unicode) ------------------------------------------------------------------------------------------------------------------------ + 908 + 909 ## Controlling IDE (ATA) hard disks + 910 # Uses 28-bit PIO mode. + 911 # Inspired by https://colorforth.github.io/ide.html + 912 # + 913 # Resources: + 914 # https://wiki.osdev.org/ATA_PIO_Mode + 915 # https://forum.osdev.org/viewtopic.php?f=1&p=167798 + 916 # read-sector, according to https://www.scs.stanford.edu/11wi-cs140/pintos/specs/ata-3-std.pdf + 917 + 918 == data + 919 + 920 # code disk + 921 # All ports are 8-bit except data-port, which is 16-bit. + 922 Primary-bus-primary-drive: + 923 # command-port: int (write) + 924 0x1f7/imm32 + 925 # status-port: int (read) + 926 0x1f7/imm32 + 927 # alternative-status-port: int (read) + 928 0x3f6/imm32 + 929 # error-port: int (read) + 930 0x1f1/imm32 + 931 # drive-and-head-port: int + 932 0x1f6/imm32 + 933 # sector-count-port: int + 934 0x1f2/imm32 + 935 # lba-low-port: int + 936 0x1f3/imm32 + 937 # lba-mid-port: int + 938 0x1f4/imm32 + 939 # lba-high-port: int + 940 0x1f5/imm32 + 941 # data-port: int + 942 0x1f0/imm32 + 943 # drive-code: byte # only drive-specific field + 944 0xe0/imm32 # LBA mode also enabled + 945 + 946 # data disk + 947 # All ports are 8-bit except data-port, which is 16-bit. + 948 Primary-bus-secondary-drive: + 949 # command-port: int (write) + 950 0x1f7/imm32 + 951 # status-port: int (read) + 952 0x1f7/imm32 + 953 # alternative-status-port: int (read) + 954 0x3f6/imm32 + 955 # error-port: int (read) + 956 0x1f1/imm32 + 957 # drive-and-head-port: int + 958 0x1f6/imm32 + 959 # sector-count-port: int + 960 0x1f2/imm32 + 961 # lba-low-port: int + 962 0x1f3/imm32 + 963 # lba-mid-port: int + 964 0x1f4/imm32 + 965 # lba-high-port: int + 966 0x1f5/imm32 + 967 # data-port: int + 968 0x1f0/imm32 + 969 # drive-code: byte # only drive-specific field + 970 0xf0/imm32 # LBA mode also enabled + 971 + 972 == code + 973 + 974 load-sectors: # disk: (addr disk), lba: int, n: int, out: (addr stream byte) + 975 # . prologue + 976 55/push-ebp + 977 89/<- %ebp 4/r32/esp + 978 # . save registers + 979 50/push-eax + 980 51/push-ecx + 981 52/push-edx + 982 # check for drive + 983 (drive-exists? *(ebp+8)) # => eax + 984 3d/compare-eax-and 0/imm32/false + 985 0f 84/jump-if-= $load-sectors:end/disp32 + 986 # kick off read + 987 (ata-drive-select *(ebp+8) *(ebp+0xc)) + 988 (clear-ata-error *(ebp+8)) + 989 (ata-sector-count *(ebp+8) *(ebp+0x10)) + 990 (ata-lba *(ebp+8) *(ebp+0xc)) + 991 (ata-command *(ebp+8) 0x20) # read sectors with retries + 992 # for each sector + 993 { + 994 # poll for results + 995 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "waiting for sector.." 7 0) + 996 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "." 7 0) + 997 (while-ata-busy *(ebp+8)) + 998 (until-ata-data-available *(ebp+8)) + 999 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "reading\n" 7 0) +1000 # var data-port/edx = disk->data-port +1001 8b/-> *(ebp+8) 0/r32/eax +1002 8b/-> *(eax+0x24) 2/r32/edx +1003 # emit results +1004 31/xor %eax 0/r32/eax +1005 b9/copy-to-ecx 0x200/imm32 # 512 bytes per sector +1006 { +1007 81 7/subop/compare %ecx 0/imm32 +1008 74/jump-if-= break/disp8 +1009 66 ed/read-port-dx-into-ax +1010 # write 2 bytes to stream one at a time +1011 (append-byte *(ebp+0x14) %eax) +1012 49/decrement-ecx +1013 c1/shift 5/subop/right-padding-zeroes %eax 8/imm8 +1014 (append-byte *(ebp+0x14) %eax) +1015 49/decrement-ecx +1016 eb/jump loop/disp8 +1017 } +1018 # next sector +1019 ff 1/subop/decrement *(ebp+0x10) +1020 #? (draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+0x10) 0xc 0) +1021 81 7/subop/compare *(ebp+0x10) 0/imm32 +1022 7e/jump-if-<= break/disp8 +1023 (wait-400ns *(ebp+8)) +1024 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "next sector\n" 7 0) +1025 e9/jump loop/disp32 +1026 } +1027 $load-sectors:end: +1028 # . restore registers +1029 5a/pop-to-edx +1030 59/pop-to-ecx +1031 58/pop-to-eax +1032 # . epilogue +1033 89/<- %esp 5/r32/ebp +1034 5d/pop-to-ebp +1035 c3/return +1036 +1037 store-sectors: # disk: (addr disk), lba: int, n: int, in: (addr stream byte) +1038 # . prologue +1039 55/push-ebp +1040 89/<- %ebp 4/r32/esp +1041 # . save registers +1042 50/push-eax +1043 51/push-ecx +1044 52/push-edx +1045 53/push-ebx +1046 # check for drive +1047 (drive-exists? *(ebp+8)) # => eax +1048 3d/compare-eax-and 0/imm32/false +1049 0f 84/jump-if-= $store-sectors:end/disp32 +1050 # kick off write +1051 (ata-drive-select *(ebp+8) *(ebp+0xc)) +1052 (clear-ata-error *(ebp+8)) +1053 (ata-sector-count *(ebp+8) *(ebp+0x10)) +1054 (ata-lba *(ebp+8) *(ebp+0xc)) +1055 (ata-command *(ebp+8) 0x30) # write sectors with retries +1056 # for each sector +1057 #? (set-cursor-position 0 0 0) +1058 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "0" 7 0) +1059 { +1060 # wait +1061 (while-ata-busy *(ebp+8)) +1062 (until-ata-ready-for-data *(ebp+8)) +1063 # var data-port/edx = disk->data-port +1064 8b/-> *(ebp+8) 0/r32/eax +1065 8b/-> *(eax+0x24) 2/r32/edx +1066 # send data +1067 b9/copy-to-ecx 0x200/imm32 # 512 bytes per sector +1068 # . var first-byte/ebx: byte +1069 # . when it's more than 0xff, we're at an even-numbered byte +1070 bb/copy-to-ebx 0xffff/imm32 +1071 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "D" 7 0) +1072 $store-sectors:store-sector: +1073 { +1074 81 7/subop/compare %ecx 0/imm32 +1075 74/jump-if-= break/disp8 +1076 # this loop is slow, but the ATA spec also requires a small delay +1077 (stream-empty? *(ebp+0x14)) # => eax +1078 3d/compare-eax-and 0/imm32/false +1079 75/jump-if-!= break/disp8 +1080 # read byte from stream +1081 (read-byte *(ebp+0x14)) # => eax +1082 # if we're at an odd-numbered byte, save it to first-byte +1083 81 7/subop/compare %ebx 0xff/imm32 +1084 { +1085 7e/jump-if-<= break/disp8 +1086 89/<- %ebx 0/r32/eax +1087 eb/jump $store-sectors:store-sector/disp8 +1088 } +1089 # otherwise OR it with first-byte and write it out +1090 c1/shift 4/subop/left %eax 8/imm8 +1091 09/or %eax 3/r32/ebx +1092 66 ef/write-ax-into-port-dx 1093 49/decrement-ecx -1094 } -1095 # pad zeroes -1096 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "P" 7 0) -1097 31/xor %eax 0/r32/eax -1098 { -1099 81 7/subop/compare %ecx 0/imm32 -1100 74/jump-if-= break/disp8 -1101 66 ef/write-ax-into-port-dx -1102 49/decrement-ecx -1103 49/decrement-ecx -1104 eb/jump loop/disp8 -1105 } -1106 # next sector -1107 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "N" 7 0) -1108 ff 1/subop/decrement *(ebp+0x10) -1109 81 7/subop/compare *(ebp+0x10) 0/imm32 -1110 7e/jump-if-<= break/disp8 -1111 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "W" 7 0) -1112 (wait-400ns *(ebp+8)) -1113 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "L" 7 0) -1114 e9/jump loop/disp32 -1115 } -1116 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "F" 7 0) -1117 (flush-ata-cache *(ebp+8)) -1118 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "Y" 7 0) -1119 $store-sectors:end: -1120 # . restore registers -1121 5b/pop-to-ebx -1122 5a/pop-to-edx -1123 59/pop-to-ecx -1124 58/pop-to-eax -1125 # . epilogue -1126 89/<- %esp 5/r32/ebp -1127 5d/pop-to-ebp -1128 c3/return -1129 -1130 +--289 lines: # disk helpers ------------------------------------------------------------------------------------------------------------------------------------------------------------ -1419 -1420 ## Controlling a PS/2 mouse -1421 # Uses no IRQs, just polling. -1422 # Thanks Dave Long: https://github.com/jtauber/cleese/blob/master/necco/kernel/bochs/py8042.py -1423 # -1424 # Resources: -1425 # https://wiki.osdev.org/Mouse_Input -1426 -1427 # results x/eax, y/ecx range from -256 to +255 -1428 # See https://wiki.osdev.org/index.php?title=Mouse_Input&oldid=25663#Format_of_First_3_Packet_Bytes -1429 read-mouse-event: # -> _/eax: int, _/ecx: int -1430 # . prologue -1431 55/push-ebp -1432 89/<- %ebp 4/r32/esp -1433 # . save registers -1434 52/push-edx -1435 53/push-ebx -1436 # if no event, return 0, 0 -1437 b8/copy-to-eax 0/imm32 -1438 b9/copy-to-ecx 0/imm32 -1439 (any-mouse-event?) # => eax -1440 3d/compare-eax-and 0/imm32/false -1441 74/jump-if-= $read-mouse-event:end/disp8 -1442 # var f1/edx: byte = inb(0x60) -1443 31/xor %eax 0/r32/eax -1444 e4/read-port-into-al 0x60/imm8 -1445 89/<- %edx 0/r32/eax -1446 (wait-for-mouse-event) -1447 # var dx/ebx: byte = inb(0x60) -1448 31/xor %eax 0/r32/eax -1449 e4/read-port-into-al 0x60/imm8 -1450 89/<- %ebx 0/r32/eax -1451 (wait-for-mouse-event) -1452 # var dy/ecx: byte = inb(0x60) -1453 31/xor %eax 0/r32/eax -1454 e4/read-port-into-al 0x60/imm8 -1455 89/<- %ecx 0/r32/eax -1456 # eax = dx -1457 89/<- %eax 3/r32/ebx -1458 # if (f1 & 0x10) dx = -dx -1459 { -1460 f6 0/subop/test-bits %dl 0x10/imm8 -1461 74/jump-if-zero break/disp8 -1462 0d/or-eax-with 0xffffff00/imm32 -1463 } -1464 # if (f1 & 0x20) dy = -dy -1465 { -1466 f6 0/subop/test-bits %dl 0x20/imm8 -1467 74/jump-if-zero break/disp8 -1468 81 1/subop/or %ecx 0xffffff00/imm32 -1469 } -1470 $read-mouse-event:end: -1471 # . restore registers -1472 5b/pop-to-ebx -1473 5a/pop-to-edx -1474 # . epilogue -1475 89/<- %esp 5/r32/ebp -1476 5d/pop-to-ebp -1477 c3/return -1478 -1479 +--147 lines: # mouse helpers ----------------------------------------------------------------------------------------------------------------------------------------------------------- -1626 -1627 # vim:ft=subx +1094 49/decrement-ecx +1095 # reset first-byte +1096 bb/copy-to-ebx 0xffff/imm32 +1097 eb/jump loop/disp8 +1098 } +1099 # write out final first-byte if necessary +1100 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "I" 7 0) +1101 81 7/subop/compare %ebx 0xff/imm32 +1102 { +1103 7f/jump-if-> break/disp8 +1104 89/<- %eax 3/r32/ebx +1105 66 ef/write-ax-into-port-dx +1106 49/decrement-ecx +1107 49/decrement-ecx +1108 } +1109 # pad zeroes +1110 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "P" 7 0) +1111 31/xor %eax 0/r32/eax +1112 { +1113 81 7/subop/compare %ecx 0/imm32 +1114 74/jump-if-= break/disp8 +1115 66 ef/write-ax-into-port-dx +1116 49/decrement-ecx +1117 49/decrement-ecx +1118 eb/jump loop/disp8 +1119 } +1120 # next sector +1121 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "N" 7 0) +1122 ff 1/subop/decrement *(ebp+0x10) +1123 81 7/subop/compare *(ebp+0x10) 0/imm32 +1124 7e/jump-if-<= break/disp8 +1125 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "W" 7 0) +1126 (wait-400ns *(ebp+8)) +1127 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "L" 7 0) +1128 e9/jump loop/disp32 +1129 } +1130 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "F" 7 0) +1131 (flush-ata-cache *(ebp+8)) +1132 #? (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "Y" 7 0) +1133 $store-sectors:end: +1134 # . restore registers +1135 5b/pop-to-ebx +1136 5a/pop-to-edx +1137 59/pop-to-ecx +1138 58/pop-to-eax +1139 # . epilogue +1140 89/<- %esp 5/r32/ebp +1141 5d/pop-to-ebp +1142 c3/return +1143 +1144 +--289 lines: # disk helpers ------------------------------------------------------------------------------------------------------------------------------------------------------------ +1433 +1434 ## Controlling a PS/2 mouse +1435 # Uses no IRQs, just polling. +1436 # Thanks Dave Long: https://github.com/jtauber/cleese/blob/master/necco/kernel/bochs/py8042.py +1437 # +1438 # Resources: +1439 # https://wiki.osdev.org/Mouse_Input +1440 +1441 # results x/eax, y/ecx range from -256 to +255 +1442 # See https://wiki.osdev.org/index.php?title=Mouse_Input&oldid=25663#Format_of_First_3_Packet_Bytes +1443 read-mouse-event: # -> _/eax: int, _/ecx: int +1444 # . prologue +1445 55/push-ebp +1446 89/<- %ebp 4/r32/esp +1447 # . save registers +1448 52/push-edx +1449 53/push-ebx +1450 # if no event, return 0, 0 +1451 b8/copy-to-eax 0/imm32 +1452 b9/copy-to-ecx 0/imm32 +1453 (any-mouse-event?) # => eax +1454 3d/compare-eax-and 0/imm32/false +1455 74/jump-if-= $read-mouse-event:end/disp8 +1456 # var f1/edx: byte = inb(0x60) +1457 31/xor %eax 0/r32/eax +1458 e4/read-port-into-al 0x60/imm8 +1459 89/<- %edx 0/r32/eax +1460 (wait-for-mouse-event) +1461 # var dx/ebx: byte = inb(0x60) +1462 31/xor %eax 0/r32/eax +1463 e4/read-port-into-al 0x60/imm8 +1464 89/<- %ebx 0/r32/eax +1465 (wait-for-mouse-event) +1466 # var dy/ecx: byte = inb(0x60) +1467 31/xor %eax 0/r32/eax +1468 e4/read-port-into-al 0x60/imm8 +1469 89/<- %ecx 0/r32/eax +1470 # eax = dx +1471 89/<- %eax 3/r32/ebx +1472 # if (f1 & 0x10) dx = -dx +1473 { +1474 f6 0/subop/test-bits %dl 0x10/imm8 +1475 74/jump-if-zero break/disp8 +1476 0d/or-eax-with 0xffffff00/imm32 +1477 } +1478 # if (f1 & 0x20) dy = -dy +1479 { +1480 f6 0/subop/test-bits %dl 0x20/imm8 +1481 74/jump-if-zero break/disp8 +1482 81 1/subop/or %ecx 0xffffff00/imm32 +1483 } +1484 $read-mouse-event:end: +1485 # . restore registers +1486 5b/pop-to-ebx +1487 5a/pop-to-edx +1488 # . epilogue +1489 89/<- %esp 5/r32/ebp +1490 5d/pop-to-ebp +1491 c3/return +1492 +1493 +--147 lines: # mouse helpers ----------------------------------------------------------------------------------------------------------------------------------------------------------- +1640 +1641 # vim:ft=subx diff --git a/html/colors.mu.html b/html/colors.mu.html index 33a0bff2..409a8fef 100644 --- a/html/colors.mu.html +++ b/html/colors.mu.html @@ -15,12 +15,17 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } +.muRegEbx { color: #8787af; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } -.CommentedCode { color: #8a8a8a; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } +.CommentedCode { color: #8a8a8a; } .muComment { color: #005faf; } --> @@ -71,31 +76,31 @@ if ('onhashchange' in window) { 12 13 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { 14 var in-storage: (stream byte 0x10) - 15 var in/esi: (addr stream byte) <- address in-storage + 15 var in/esi: (addr stream byte) <- address in-storage 16 { 17 # print prompt - 18 var x/eax: int <- draw-text-rightward screen, "Enter 3 hex bytes for r, g, b (lowercase; no 0x prefix) separated by a single space> ", 0x10/x, 0x80/xmax, 0x28/y, 3/fg/cyan, 0/bg + 18 var x/eax: int <- draw-text-rightward screen, "Enter 3 hex bytes for r, g, b (lowercase; no 0x prefix) separated by a single space> ", 0x10/x, 0x80/xmax, 0x28/y, 3/fg/cyan, 0/bg 19 # read line from keyboard 20 clear-stream in 21 { - 22 draw-cursor screen, 0x20/space - 23 var key/eax: byte <- read-key keyboard + 22 draw-cursor screen, 0x20/space + 23 var key/eax: byte <- read-key keyboard 24 compare key, 0xa/newline 25 break-if-= 26 compare key, 0 27 loop-if-= - 28 var key2/eax: int <- copy key + 28 var key2/eax: int <- copy key 29 append-byte in, key2 - 30 var g/eax: grapheme <- copy key2 + 30 var g/eax: grapheme <- copy key2 31 draw-grapheme-at-cursor screen, g, 0xf/fg, 0/bg 32 move-cursor-right 0 33 loop 34 } - 35 clear-screen screen + 35 clear-screen screen 36 # parse - 37 var a/ecx: int <- copy 0 - 38 var b/edx: int <- copy 0 - 39 var c/ebx: int <- copy 0 + 37 var a/ecx: int <- copy 0 + 38 var b/edx: int <- copy 0 + 39 var c/ebx: int <- copy 0 40 # a, b, c = r, g, b 41 a, b, c <- parse in 42 #? set-cursor-position screen, 0x10/x, 0x1a/y @@ -114,24 +119,24 @@ if ('onhashchange' in window) { 55 56 # read exactly 3 words in a single line 57 # Each word consists of exactly 1 or 2 hex bytes. No hex prefix. - 58 fn parse in: (addr stream byte) -> _/ecx: int, _/edx: int, _/ebx: int { + 58 fn parse in: (addr stream byte) -> _/ecx: int, _/edx: int, _/ebx: int { 59 # read first byte of r - 60 var tmp/eax: byte <- read-byte in + 60 var tmp/eax: byte <- read-byte in 61 { - 62 var valid?/eax: boolean <- hex-digit? tmp + 62 var valid?/eax: boolean <- hex-digit? tmp 63 compare valid?, 0/false 64 break-if-!= 65 abort "invalid byte 0 of r" 66 } 67 tmp <- fast-hex-digit-value tmp - 68 var r/ecx: int <- copy tmp + 68 var r/ecx: int <- copy tmp 69 #? set-cursor-position 0/screen, 0x10/x, 0x10/y 70 #? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, r, 7/fg, 0/bg 71 # read second byte of r 72 tmp <- read-byte in 73 { 74 { - 75 var valid?/eax: boolean <- hex-digit? tmp + 75 var valid?/eax: boolean <- hex-digit? tmp 76 compare valid?, 0/false 77 } 78 break-if-= @@ -150,22 +155,22 @@ if ('onhashchange' in window) { 91 tmp <- read-byte in # skip space 92 } 93 # read first byte of g - 94 var tmp/eax: byte <- read-byte in + 94 var tmp/eax: byte <- read-byte in 95 { - 96 var valid?/eax: boolean <- hex-digit? tmp + 96 var valid?/eax: boolean <- hex-digit? tmp 97 compare valid?, 0/false 98 break-if-!= 99 abort "invalid byte 0 of g" 100 } 101 tmp <- fast-hex-digit-value tmp -102 var g/edx: int <- copy tmp +102 var g/edx: int <- copy tmp 103 #? set-cursor-position 0/screen, 0x10/x, 0x13/y 104 #? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, g, 7/fg, 0/bg 105 # read second byte of g 106 tmp <- read-byte in 107 { 108 { -109 var valid?/eax: boolean <- hex-digit? tmp +109 var valid?/eax: boolean <- hex-digit? tmp 110 compare valid?, 0/false 111 } 112 break-if-= @@ -184,27 +189,27 @@ if ('onhashchange' in window) { 125 tmp <- read-byte in # skip space 126 } 127 # read first byte of b -128 var tmp/eax: byte <- read-byte in +128 var tmp/eax: byte <- read-byte in 129 { -130 var valid?/eax: boolean <- hex-digit? tmp +130 var valid?/eax: boolean <- hex-digit? tmp 131 compare valid?, 0/false 132 break-if-!= 133 abort "invalid byte 0 of b" 134 } 135 tmp <- fast-hex-digit-value tmp -136 var b/ebx: int <- copy tmp +136 var b/ebx: int <- copy tmp 137 #? set-cursor-position 0/screen, 0x10/x, 0x16/y 138 #? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, b, 7/fg, 0/bg 139 # read second byte of b 140 { 141 { -142 var done?/eax: boolean <- stream-empty? in +142 var done?/eax: boolean <- stream-empty? in 143 compare done?, 0/false 144 } 145 break-if-!= 146 tmp <- read-byte in 147 { -148 var valid?/eax: boolean <- hex-digit? tmp +148 var valid?/eax: boolean <- hex-digit? tmp 149 compare valid?, 0/false 150 } 151 break-if-= @@ -225,8 +230,8 @@ if ('onhashchange' in window) { 166 } 167 168 # no error checking -169 fn fast-hex-digit-value in: byte -> _/eax: byte { -170 var result/eax: byte <- copy in +169 fn fast-hex-digit-value in: byte -> _/eax: byte { +170 var result/eax: byte <- copy in 171 compare result, 0x39 172 { 173 break-if-> @@ -255,11 +260,11 @@ if ('onhashchange' in window) { 196 #? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, s, 7/fg, 0/bg 197 #? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg 198 #? draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen, l, 7/fg, 0/bg -199 var a/ecx: int <- copy 0 -200 var b/edx: int <- copy 0 -201 var c/ebx: int <- copy 0 -202 var color/eax: int <- copy 0 -203 var y/esi: int <- copy 2 +199 var a/ecx: int <- copy 0 +200 var b/edx: int <- copy 0 +201 var c/ebx: int <- copy 0 +202 var color/eax: int <- copy 0 +203 var y/esi: int <- copy 2 204 { 205 compare color, 0x100 206 break-if->= @@ -275,9 +280,9 @@ if ('onhashchange' in window) { 216 break-if-!= 217 compare c, l 218 break-if-!= -219 set-cursor-position screen, 0x10/x, y +219 set-cursor-position screen, 0x10/x, y 220 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, color, 7/fg, 0/bg -221 set-cursor-position screen, 0x14/x, y +221 set-cursor-position screen, 0x14/x, y 222 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg 223 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 0/fg, color 224 #? draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, " ", 7/fg, 0/bg diff --git a/html/ex10.mu.html b/html/ex10.mu.html index 93781f42..bf197ab7 100644 --- a/html/ex10.mu.html +++ b/html/ex10.mu.html @@ -15,9 +15,11 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -72,9 +74,9 @@ if ('onhashchange' in window) { 14 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { 15 # repeatedly print out mouse driver results if non-zero 16 $main:event-loop: { -17 var dx/eax: int <- copy 0 -18 var dy/ecx: int <- copy 0 -19 dx, dy <- read-mouse-event +17 var dx/eax: int <- copy 0 +18 var dy/ecx: int <- copy 0 +19 dx, dy <- read-mouse-event 20 { 21 compare dx, 0 22 break-if-!= @@ -83,16 +85,16 @@ if ('onhashchange' in window) { 25 loop $main:event-loop 26 } 27 { -28 var dummy1/eax: int <- copy 0 -29 var dummy2/ecx: int <- copy 0 +28 var dummy1/eax: int <- copy 0 +29 var dummy2/ecx: int <- copy 0 30 dummy1, dummy2 <- draw-text-wrapping-right-then-down-over-full-screen screen, " ", 0/x, 0x10/y, 0x31/fg, 0/bg 31 } 32 { -33 var dummy/ecx: int <- copy 0 +33 var dummy/ecx: int <- copy 0 34 dx, dummy <- draw-int32-decimal-wrapping-right-then-down-over-full-screen screen, dx, 0/x, 0x10/y, 0x31/fg, 0/bg 35 } 36 { -37 var dummy/eax: int <- copy 0 +37 var dummy/eax: int <- copy 0 38 dummy, dy <- draw-int32-decimal-wrapping-right-then-down-over-full-screen screen, dy, 5/x, 0x10/y, 0x31/fg, 0/bg 39 } 40 loop diff --git a/html/ex11.mu.html b/html/ex11.mu.html index 084d01d7..2fad6210 100644 --- a/html/ex11.mu.html +++ b/html/ex11.mu.html @@ -15,9 +15,15 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } +.muRegEdi { color: #87ffd7; } +.muRegEbx { color: #8787af; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -71,7 +77,7 @@ if ('onhashchange' in window) { 13 14 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { 15 var env-storage: environment - 16 var env/esi: (addr environment) <- address env-storage + 16 var env/esi: (addr environment) <- address env-storage 17 initialize-environment env, 0x200 0x20, 0x180 0x90, 0x180 0x160 18 { 19 render screen, env @@ -93,17 +99,17 @@ if ('onhashchange' in window) { 35 } 36 37 fn render screen: (addr screen), _self: (addr environment) { - 38 clear-screen screen - 39 var self/esi: (addr environment) <- copy _self - 40 var tmp-ah/ecx: (addr handle point) <- get self, p0 - 41 var tmp/eax: (addr point) <- lookup *tmp-ah - 42 var p0/ebx: (addr point) <- copy tmp + 38 clear-screen screen + 39 var self/esi: (addr environment) <- copy _self + 40 var tmp-ah/ecx: (addr handle point) <- get self, p0 + 41 var tmp/eax: (addr point) <- lookup *tmp-ah + 42 var p0/ebx: (addr point) <- copy tmp 43 tmp-ah <- get self, p1 44 tmp <- lookup *tmp-ah - 45 var p1/edx: (addr point) <- copy tmp + 45 var p1/edx: (addr point) <- copy tmp 46 tmp-ah <- get self, p2 47 tmp <- lookup *tmp-ah - 48 var p2/ecx: (addr point) <- copy tmp + 48 var p2/ecx: (addr point) <- copy tmp 49 # control lines 50 line screen, p0, p1, 7/color 51 line screen, p1, p2, 7/color @@ -114,51 +120,51 @@ if ('onhashchange' in window) { 56 disc screen, p1, 3/radius, 7/color 0xf/border 57 disc screen, p2, 3/radius, 7/color 0xf/border 58 # cursor last of all - 59 var cursor-ah/eax: (addr handle point) <- get self, cursor - 60 var cursor/eax: (addr point) <- lookup *cursor-ah + 59 var cursor-ah/eax: (addr handle point) <- get self, cursor + 60 var cursor/eax: (addr point) <- lookup *cursor-ah 61 cursor screen, cursor, 0xa/side, 3/color 62 } 63 64 fn bezier screen: (addr screen), _p0: (addr point), _p1: (addr point), _p2: (addr point), color: int { - 65 var p0/esi: (addr point) <- copy _p0 - 66 var x0/ecx: (addr int) <- get p0, x - 67 var y0/edx: (addr int) <- get p0, y - 68 var p1/esi: (addr point) <- copy _p1 - 69 var x1/ebx: (addr int) <- get p1, x - 70 var y1/eax: (addr int) <- get p1, y - 71 var p2/esi: (addr point) <- copy _p2 - 72 var x2/edi: (addr int) <- get p2, x - 73 var y2/esi: (addr int) <- get p2, y + 65 var p0/esi: (addr point) <- copy _p0 + 66 var x0/ecx: (addr int) <- get p0, x + 67 var y0/edx: (addr int) <- get p0, y + 68 var p1/esi: (addr point) <- copy _p1 + 69 var x1/ebx: (addr int) <- get p1, x + 70 var y1/eax: (addr int) <- get p1, y + 71 var p2/esi: (addr point) <- copy _p2 + 72 var x2/edi: (addr int) <- get p2, x + 73 var y2/esi: (addr int) <- get p2, y 74 draw-monotonic-bezier screen, *x0 *y0, *x1 *y1, *x2 *y2, color 75 } 76 77 fn cursor screen: (addr screen), _p: (addr point), side: int, color: int { - 78 var half-side/eax: int <- copy side + 78 var half-side/eax: int <- copy side 79 half-side <- shift-right 1 - 80 var p/esi: (addr point) <- copy _p - 81 var x-a/ecx: (addr int) <- get p, x - 82 var left-x/ecx: int <- copy *x-a + 80 var p/esi: (addr point) <- copy _p + 81 var x-a/ecx: (addr int) <- get p, x + 82 var left-x/ecx: int <- copy *x-a 83 left-x <- subtract half-side - 84 var y-a/edx: (addr int) <- get p, y - 85 var top-y/edx: int <- copy *y-a + 84 var y-a/edx: (addr int) <- get p, y + 85 var top-y/edx: int <- copy *y-a 86 top-y <- subtract half-side - 87 var max/eax: int <- copy left-x + 87 var max/eax: int <- copy left-x 88 max <- add side 89 draw-horizontal-line screen, top-y, left-x, max, color 90 max <- copy top-y 91 max <- add side 92 draw-vertical-line screen, left-x, top-y, max, color - 93 var right-x/ebx: int <- copy left-x + 93 var right-x/ebx: int <- copy left-x 94 right-x <- add side 95 draw-vertical-line screen, right-x, top-y, max, color - 96 var bottom-y/edx: int <- copy top-y + 96 var bottom-y/edx: int <- copy top-y 97 bottom-y <- add side 98 draw-horizontal-line screen, bottom-y, left-x, right-x, color 99 } 100 101 fn edit keyboard: (addr keyboard), _self: (addr environment) { -102 var self/esi: (addr environment) <- copy _self -103 var key/eax: byte <- read-key keyboard +102 var self/esi: (addr environment) <- copy _self +103 var key/eax: byte <- read-key keyboard 104 compare key, 0 105 loop-if-= 106 { @@ -194,27 +200,27 @@ if ('onhashchange' in window) { 136 } 137 138 fn toggle-cursor _self: (addr environment) { -139 var self/esi: (addr environment) <- copy _self -140 var cursor-ah/edi: (addr handle point) <- get self, cursor -141 var p0-ah/ecx: (addr handle point) <- get self, p0 -142 var p1-ah/edx: (addr handle point) <- get self, p1 -143 var p2-ah/ebx: (addr handle point) <- get self, p2 +139 var self/esi: (addr environment) <- copy _self +140 var cursor-ah/edi: (addr handle point) <- get self, cursor +141 var p0-ah/ecx: (addr handle point) <- get self, p0 +142 var p1-ah/edx: (addr handle point) <- get self, p1 +143 var p2-ah/ebx: (addr handle point) <- get self, p2 144 { -145 var p0?/eax: boolean <- handle-equal? *p0-ah, *cursor-ah +145 var p0?/eax: boolean <- handle-equal? *p0-ah, *cursor-ah 146 compare p0?, 0/false 147 break-if-= 148 copy-object p1-ah, cursor-ah 149 return 150 } 151 { -152 var p1?/eax: boolean <- handle-equal? *p1-ah, *cursor-ah +152 var p1?/eax: boolean <- handle-equal? *p1-ah, *cursor-ah 153 compare p1?, 0/false 154 break-if-= 155 copy-object p2-ah, cursor-ah 156 return 157 } 158 { -159 var p2?/eax: boolean <- handle-equal? *p2-ah, *cursor-ah +159 var p2?/eax: boolean <- handle-equal? *p2-ah, *cursor-ah 160 compare p2?, 0/false 161 break-if-= 162 copy-object p0-ah, cursor-ah @@ -224,10 +230,10 @@ if ('onhashchange' in window) { 166 } 167 168 fn cursor-left _self: (addr environment) { -169 var self/esi: (addr environment) <- copy _self -170 var cursor-ah/esi: (addr handle point) <- get self, cursor -171 var cursor/eax: (addr point) <- lookup *cursor-ah -172 var cursor-x/eax: (addr int) <- get cursor, x +169 var self/esi: (addr environment) <- copy _self +170 var cursor-ah/esi: (addr handle point) <- get self, cursor +171 var cursor/eax: (addr point) <- lookup *cursor-ah +172 var cursor-x/eax: (addr int) <- get cursor, x 173 compare *cursor-x, 0x20 174 { 175 break-if-< @@ -236,10 +242,10 @@ if ('onhashchange' in window) { 178 } 179 180 fn cursor-right _self: (addr environment) { -181 var self/esi: (addr environment) <- copy _self -182 var cursor-ah/esi: (addr handle point) <- get self, cursor -183 var cursor/eax: (addr point) <- lookup *cursor-ah -184 var cursor-x/eax: (addr int) <- get cursor, x +181 var self/esi: (addr environment) <- copy _self +182 var cursor-ah/esi: (addr handle point) <- get self, cursor +183 var cursor/eax: (addr point) <- lookup *cursor-ah +184 var cursor-x/eax: (addr int) <- get cursor, x 185 compare *cursor-x, 0x3f0 186 { 187 break-if-> @@ -248,10 +254,10 @@ if ('onhashchange' in window) { 190 } 191 192 fn cursor-up _self: (addr environment) { -193 var self/esi: (addr environment) <- copy _self -194 var cursor-ah/esi: (addr handle point) <- get self, cursor -195 var cursor/eax: (addr point) <- lookup *cursor-ah -196 var cursor-y/eax: (addr int) <- get cursor, y +193 var self/esi: (addr environment) <- copy _self +194 var cursor-ah/esi: (addr handle point) <- get self, cursor +195 var cursor/eax: (addr point) <- lookup *cursor-ah +196 var cursor-y/eax: (addr int) <- get cursor, y 197 compare *cursor-y, 0x20 198 { 199 break-if-< @@ -260,10 +266,10 @@ if ('onhashchange' in window) { 202 } 203 204 fn cursor-down _self: (addr environment) { -205 var self/esi: (addr environment) <- copy _self -206 var cursor-ah/esi: (addr handle point) <- get self, cursor -207 var cursor/eax: (addr point) <- lookup *cursor-ah -208 var cursor-y/eax: (addr int) <- get cursor, y +205 var self/esi: (addr environment) <- copy _self +206 var cursor-ah/esi: (addr handle point) <- get self, cursor +207 var cursor/eax: (addr point) <- lookup *cursor-ah +208 var cursor-y/eax: (addr int) <- get cursor, y 209 compare *cursor-y, 0x2f0 210 { 211 break-if-> @@ -272,46 +278,46 @@ if ('onhashchange' in window) { 214 } 215 216 fn line screen: (addr screen), _p0: (addr point), _p1: (addr point), color: int { -217 var p0/esi: (addr point) <- copy _p0 -218 var x0/ecx: (addr int) <- get p0, x -219 var y0/edx: (addr int) <- get p0, y -220 var p1/esi: (addr point) <- copy _p1 -221 var x1/ebx: (addr int) <- get p1, x -222 var y1/eax: (addr int) <- get p1, y +217 var p0/esi: (addr point) <- copy _p0 +218 var x0/ecx: (addr int) <- get p0, x +219 var y0/edx: (addr int) <- get p0, y +220 var p1/esi: (addr point) <- copy _p1 +221 var x1/ebx: (addr int) <- get p1, x +222 var y1/eax: (addr int) <- get p1, y 223 draw-line screen, *x0 *y0, *x1 *y1, color 224 } 225 226 fn disc screen: (addr screen), _p: (addr point), radius: int, color: int, border-color: int { -227 var p/esi: (addr point) <- copy _p -228 var x/ecx: (addr int) <- get p, x -229 var y/edx: (addr int) <- get p, y +227 var p/esi: (addr point) <- copy _p +228 var x/ecx: (addr int) <- get p, x +229 var y/edx: (addr int) <- get p, y 230 draw-disc screen, *x *y, radius, color, border-color 231 } 232 233 fn initialize-environment _self: (addr environment), x0: int, y0: int, x1: int, y1: int, x2: int, y2: int { -234 var self/esi: (addr environment) <- copy _self -235 var p0-ah/eax: (addr handle point) <- get self, p0 +234 var self/esi: (addr environment) <- copy _self +235 var p0-ah/eax: (addr handle point) <- get self, p0 236 allocate p0-ah -237 var p0/eax: (addr point) <- lookup *p0-ah +237 var p0/eax: (addr point) <- lookup *p0-ah 238 initialize-point p0, x0 y0 -239 var p1-ah/eax: (addr handle point) <- get self, p1 +239 var p1-ah/eax: (addr handle point) <- get self, p1 240 allocate p1-ah -241 var p1/eax: (addr point) <- lookup *p1-ah +241 var p1/eax: (addr point) <- lookup *p1-ah 242 initialize-point p1, x1 y1 -243 var p2-ah/eax: (addr handle point) <- get self, p2 +243 var p2-ah/eax: (addr handle point) <- get self, p2 244 allocate p2-ah -245 var p2/eax: (addr point) <- lookup *p2-ah +245 var p2/eax: (addr point) <- lookup *p2-ah 246 initialize-point p2, x2 y2 247 # cursor initially at p0 -248 var cursor-ah/edi: (addr handle point) <- get self, cursor -249 var src-ah/esi: (addr handle point) <- get self, p0 +248 var cursor-ah/edi: (addr handle point) <- get self, cursor +249 var src-ah/esi: (addr handle point) <- get self, p0 250 copy-object src-ah, cursor-ah 251 } 252 253 fn initialize-point _p: (addr point), x: int, y: int { -254 var p/esi: (addr point) <- copy _p -255 var dest/eax: (addr int) <- get p, x -256 var src/ecx: int <- copy x +254 var p/esi: (addr point) <- copy _p +255 var dest/eax: (addr int) <- get p, x +256 var src/ecx: int <- copy x 257 copy-to *dest, src 258 dest <- get p, y 259 src <- copy y diff --git a/html/ex2.mu.html b/html/ex2.mu.html index ee5edcd4..1a5dee6a 100644 --- a/html/ex2.mu.html +++ b/html/ex2.mu.html @@ -15,9 +15,12 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -66,17 +69,17 @@ if ('onhashchange' in window) { 8 # bochs -f bochsrc # bochsrc loads code.img 9 10 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { -11 var y/eax: int <- copy 0 +11 var y/eax: int <- copy 0 12 { 13 compare y, 0x300/screen-height=768 14 break-if->= -15 var x/edx: int <- copy 0 +15 var x/edx: int <- copy 0 16 { 17 compare x, 0x400/screen-width=1024 18 break-if->= -19 var color/ecx: int <- copy x +19 var color/ecx: int <- copy x 20 color <- and 0xff -21 pixel screen x, y, color +21 pixel screen x, y, color 22 x <- increment 23 loop 24 } diff --git a/html/ex3.mu.html b/html/ex3.mu.html index b7217423..f1fce2c5 100644 --- a/html/ex3.mu.html +++ b/html/ex3.mu.html @@ -18,6 +18,9 @@ a { color:inherit; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEdx { color: #878700; } +.muRegEcx { color: #af875f; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -70,10 +73,10 @@ if ('onhashchange' in window) { 12 # screen every time you press a key (letter or digit) 13 14 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { -15 var x/ecx: int <- copy 0 -16 var y/edx: int <- copy 0 +15 var x/ecx: int <- copy 0 +16 var y/edx: int <- copy 0 17 { -18 var key/eax: byte <- read-key keyboard +18 var key/eax: byte <- read-key keyboard 19 compare key, 0 20 loop-if-= # busy wait 21 pixel-on-real-screen x, y, 0x31/green diff --git a/html/ex4.mu.html b/html/ex4.mu.html index ba6cf99b..f3b8ea83 100644 --- a/html/ex4.mu.html +++ b/html/ex4.mu.html @@ -67,7 +67,7 @@ if ('onhashchange' in window) { 10 # Expected output: letter 'A' in green near the top-left corner of screen 11 12 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { -13 draw-code-point screen, 0x41/A, 2/row, 1/col, 0xa/fg, 0/bg +13 draw-code-point screen, 0x41/A, 2/row, 1/col, 0xa/fg, 0/bg 14 } diff --git a/html/ex5.mu.html b/html/ex5.mu.html index f1595d7b..19d1f3fc 100644 --- a/html/ex5.mu.html +++ b/html/ex5.mu.html @@ -18,6 +18,7 @@ a { color:inherit; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -69,7 +70,7 @@ if ('onhashchange' in window) { 11 # Expected output: text in green near the top-left corner of screen 12 13 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { -14 var dummy/eax: int <- draw-text-rightward screen, "hello from baremetal Mu!", 0x10/x, 0x400/xmax, 0x10/y, 0xa/fg, 0/bg +14 var dummy/eax: int <- draw-text-rightward screen, "hello from baremetal Mu!", 0x10/x, 0x400/xmax, 0x10/y, 0xa/fg, 0/bg 15 dummy <- draw-text-rightward screen, "you shouldn't see this", 0x10/x, 0xa0/xmax, 0x30/y, 3/fg, 0/bg # xmax is too narrow 16 } diff --git a/html/ex6.mu.html b/html/ex6.mu.html index 47ef7b14..fe36611c 100644 --- a/html/ex6.mu.html +++ b/html/ex6.mu.html @@ -15,9 +15,11 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -70,8 +72,8 @@ if ('onhashchange' in window) { 12 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { 13 # drawing text within a bounding box 14 draw-box-on-real-screen 0xf, 0x1f, 0x79, 0x51, 0x4 -15 var x/eax: int <- copy 0x20 -16 var y/ecx: int <- copy 0x20 +15 var x/eax: int <- copy 0x20 +16 var y/ecx: int <- copy 0x20 17 x, y <- draw-text-wrapping-right-then-down screen, "hello ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/fg, 0/bg 18 x, y <- draw-text-wrapping-right-then-down screen, "from ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/fg, 0/bg 19 x, y <- draw-text-wrapping-right-then-down screen, "baremetal ", 0x10/xmin, 0x20/ymin, 0x78/xmax, 0x50/ymax, x, y, 0xa/fg, 0/bg diff --git a/html/ex7.mu.html b/html/ex7.mu.html index 8fc47169..1775dffb 100644 --- a/html/ex7.mu.html +++ b/html/ex7.mu.html @@ -18,6 +18,7 @@ a { color:inherit; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -69,11 +70,11 @@ if ('onhashchange' in window) { 11 # k, l. 12 13 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { -14 var space/eax: grapheme <- copy 0x20 -15 set-cursor-position screen, 0, 0 +14 var space/eax: grapheme <- copy 0x20 +15 set-cursor-position screen, 0, 0 16 { -17 draw-cursor screen, space -18 var key/eax: byte <- read-key keyboard +17 draw-cursor screen, space +18 var key/eax: byte <- read-key keyboard 19 { 20 compare key, 0x68/h 21 break-if-!= @@ -95,7 +96,7 @@ if ('onhashchange' in window) { 37 { 38 compare key, 0x6c/l 39 break-if-!= -40 var g/eax: code-point <- copy 0x2d/dash +40 var g/eax: code-point <- copy 0x2d/dash 41 draw-code-point-at-cursor screen, 0x2d/dash, 0x31/fg, 0/bg 42 move-cursor-right 0 43 } diff --git a/html/ex8.mu.html b/html/ex8.mu.html index b4aafd6c..f6c47d7f 100644 --- a/html/ex8.mu.html +++ b/html/ex8.mu.html @@ -18,6 +18,7 @@ a { color:inherit; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -65,7 +66,7 @@ if ('onhashchange' in window) { 7 # Set a breakpoint at 0x7c00 and start stepping. 8 9 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { -10 var n/eax: int <- copy 0 +10 var n/eax: int <- copy 0 11 var result/xmm0: float <- convert n 12 } diff --git a/html/ex9.mu.html b/html/ex9.mu.html index f64c025c..59a91c10 100644 --- a/html/ex9.mu.html +++ b/html/ex9.mu.html @@ -15,9 +15,12 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEdi { color: #87ffd7; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -75,24 +78,24 @@ if ('onhashchange' in window) { 17 18 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { 19 var text-storage: (stream byte 0x200) -20 var text/esi: (addr stream byte) <- address text-storage -21 load-sectors data-disk, 0/lba, 1/num-sectors, text +20 var text/esi: (addr stream byte) <- address text-storage +21 load-sectors data-disk, 0/lba, 1/num-sectors, text 22 -23 var word-count/eax: int <- word-count text +23 var word-count/eax: int <- word-count text 24 25 var result-storage: (stream byte 0x10) -26 var result/edi: (addr stream byte) <- address result-storage +26 var result/edi: (addr stream byte) <- address result-storage 27 write-int32-decimal result, word-count -28 store-sectors data-disk, 0/lba, 1/num-sectors, result +28 store-sectors data-disk, 0/lba, 1/num-sectors, result 29 } 30 -31 fn word-count in: (addr stream byte) -> _/eax: int { -32 var result/edi: int <- copy 0 +31 fn word-count in: (addr stream byte) -> _/eax: int { +32 var result/edi: int <- copy 0 33 { -34 var done?/eax: boolean <- stream-empty? in +34 var done?/eax: boolean <- stream-empty? in 35 compare done?, 0/false 36 break-if-!= -37 var g/eax: grapheme <- read-grapheme in +37 var g/eax: grapheme <- read-grapheme in 38 { 39 compare g, 0x20/space 40 break-if-!= diff --git a/html/hest-life.mu.html b/html/hest-life.mu.html index 32456854..3fab52de 100644 --- a/html/hest-life.mu.html +++ b/html/hest-life.mu.html @@ -14,14 +14,20 @@ pre { white-space: pre-wrap; font-family: monospace; color: #000000; background- body { font-size:12pt; font-family: monospace; color: #000000; background-color: #a8a8a8; } a { color:inherit; } * { font-size:12pt; font-size: 1em; } -.PreProc { color: #c000c0; } -.Special { color: #ff6060; } .LineNr { } -.Constant { color: #008787; } -.CommentedCode { color: #8a8a8a; } .Delimiter { color: #c000c0; } +.CommentedCode { color: #8a8a8a; } +.muRegEdx { color: #878700; } +.muRegEbx { color: #8787af; } +.muRegEsi { color: #87d787; } +.muRegEdi { color: #87ffd7; } +.Constant { color: #008787; } +.Special { color: #ff6060; } +.PreProc { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } +.muRegEax { color: #875f00; } +.muRegEcx { color: #af875f; } --> @@ -80,1009 +86,1012 @@ if ('onhashchange' in window) { 21 # -: zoom out 22 23 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { - 24 var env-storage: environment - 25 var env/esi: (addr environment) <- address env-storage - 26 initialize-environment env + 24 var env-storage: environment + 25 var env/esi: (addr environment) <- address env-storage + 26 initialize-environment env 27 var second-buffer: screen - 28 var second-screen/edi: (addr screen) <- address second-buffer - 29 initialize-screen second-screen, 0x80, 0x30, 1/include-pixels - 30 render second-screen, env - 31 copy-pixels second-screen, screen - 32 { - 33 edit keyboard, env - 34 var play?/eax: (addr boolean) <- get env, play? - 35 compare *play?, 0/false - 36 { - 37 break-if-= - 38 step env - 39 render second-screen, env - 40 copy-pixels second-screen, screen - 41 } - 42 linger env - 43 loop - 44 } - 45 } - 46 - 47 type environment { - 48 data: (handle array handle array cell) - 49 zoom: int # 0 = 1024 px per cell; 5 = 4px per cell; each step adjusts by a factor of 4 - 50 tick: int - 51 play?: boolean - 52 loop: int # if non-zero, return tick to 0 after this point - 53 } - 54 - 55 type cell { - 56 curr: boolean - 57 next: boolean - 58 } - 59 - 60 fn render screen: (addr screen), _self: (addr environment) { - 61 var self/esi: (addr environment) <- copy _self - 62 var zoom/eax: (addr int) <- get self, zoom - 63 compare *zoom, 0 - 64 { - 65 break-if-!= - 66 clear-screen screen - 67 render0 screen, self - 68 } - 69 compare *zoom, 1 - 70 { - 71 break-if-!= - 72 clear-screen screen - 73 render1 screen, self - 74 } - 75 compare *zoom, 4 - 76 { - 77 break-if-!= - 78 render4 screen, self - 79 } - 80 # clock - 81 var tick-a/eax: (addr int) <- get self, tick - 82 set-cursor-position screen, 0x78/x, 0/y - 83 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, *tick-a, 7/fg 0/bg - 84 } - 85 - 86 # Lots of hardcoded constants for now. - 87 # TODO: split this up into a primitive to render a single cell and its - 88 # incoming edges (but not the neighboring nodes they emanate from) - 89 fn render0 screen: (addr screen), _self: (addr environment) { - 90 var self/esi: (addr environment) <- copy _self - 91 # cell border - 92 draw-vertical-line screen, 0xc0/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey - 93 draw-vertical-line screen, 0x340/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey - 94 draw-horizontal-line screen, 0x40/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey - 95 draw-horizontal-line screen, 0x2c0/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey - 96 # neighboring inputs, corners - 97 var color/eax: int <- state-color self, 0x7f/cur-topleftx, 0x5f/cur-toplefty - 98 draw-rect screen, 0x90/xmin 0x10/ymin, 0xb0/xmax 0x30/ymax, color - 99 color <- state-color self, 0x81/cur-toprightx, 0x5f/cur-toprighty - 100 draw-rect screen, 0x350/xmin 0x10/ymin, 0x370/xmax 0x30/ymax, color - 101 color <- state-color self, 0x7f/cur-botleftx, 0x61/cur-botlefty - 102 draw-rect screen, 0x90/xmin 0x2d0/ymin, 0xb0/xmax 0x2f0/ymax, color - 103 color <- state-color self, 0x81/cur-botrightx, 0x61/cur-botrighty - 104 draw-rect screen, 0x350/xmin 0x2d0/ymin, 0x370/xmax 0x2f0/ymax, color - 105 # neighboring inputs, edges - 106 color <- state-color self, 0x80/cur-topx, 0x5f/cur-topy - 107 draw-rect screen, 0x1f0/xmin 0x10/ymin, 0x210/xmax 0x30/ymax, color - 108 color <- state-color self, 0x7f/cur-leftx, 0x60/cur-lefty - 109 draw-rect screen, 0x90/xmin 0x170/ymin, 0xb0/xmax 0x190/ymax, color - 110 color <- state-color self, 0x80/cur-botx, 0x61/cur-boty - 111 draw-rect screen, 0x1f0/xmin 0x2d0/ymin, 0x210/xmax 0x2f0/ymax, color - 112 color <- state-color self, 0x81/cur-rightx, 0x60/cur-righty - 113 draw-rect screen, 0x350/xmin 0x170/ymin, 0x370/xmax 0x190/ymax, color - 114 # sum node - 115 draw-rect screen, 0x170/xsmin 0x140/ysmin, 0x190/xsmax 0x160/ysmax, 0x40/color - 116 set-cursor-position screen, 0x2d/scol, 0x13/srow - 117 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "+", 0xf/color, 0/bg - 118 # conveyors from neighboring inputs to sum node - 119 draw-monotonic-bezier screen, 0xa0/x0 0x20/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color - 120 draw-monotonic-bezier screen, 0xa0/x0 0x180/y0, 0xc0/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color - 121 draw-monotonic-bezier screen, 0xa0/x0 0x2e0/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color - 122 draw-monotonic-bezier screen, 0x200/x0 0x20/y0, 0x180/x1 0x90/y1, 0x180/xs 0x150/ys, 4/color - 123 draw-monotonic-bezier screen, 0x200/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 4/color - 124 draw-monotonic-bezier screen, 0x360/x0 0x20/y0, 0x180/x1 0xc0/y1, 0x180/xs 0x150/ys, 4/color - 125 draw-monotonic-bezier screen, 0x360/x0 0x180/y0, 0x35c/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color - 126 draw-monotonic-bezier screen, 0x360/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 4/color - 127 # filter node - 128 draw-rect screen, 0x200/xfmin 0x1c0/yfmin, 0x220/xfmax 0x1e0/yfmax, 0x31/color - 129 set-cursor-position screen, 0x40/fcol, 0x1b/frow - 130 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "?", 0xf/color, 0/bg - 131 # conveyor from sum node to filter node - 132 draw-line screen 0x180/xs, 0x150/ys, 0x210/xf, 0x1d0/yf, 0xa2/color - 133 # cell outputs at corners - 134 var color/eax: int <- state-color self, 0x80/curx, 0x60/cury - 135 draw-rect screen, 0xd0/xmin 0x50/ymin, 0xf0/xmax 0x70/ymax, color - 136 draw-rect screen, 0x310/xmin 0x50/ymin, 0x330/xmax 0x70/ymax, color - 137 draw-rect screen, 0xd0/xmin 0x290/ymin, 0xf0/xmax 0x2b0/ymax, color - 138 draw-rect screen, 0x310/xmin 0x290/ymin, 0x330/xmax 0x2b0/ymax, color - 139 # cell outputs at edges - 140 draw-rect screen, 0x1f0/xmin 0x50/ymin, 0x210/xmax 0x70/ymax, color - 141 draw-rect screen, 0xd0/xmin 0x170/ymin, 0xf0/xmax 0x190/ymax, color - 142 draw-rect screen, 0x1f0/xmin 0x290/ymin, 0x210/xmax 0x2b0/ymax, color - 143 draw-rect screen, 0x310/xmin 0x170/ymin, 0x330/xmax 0x190/ymax, color - 144 # conveyors from filter to outputs - 145 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x60/y1, 0xe0/x2 0x60/y2, 0x2a/color - 146 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0xe0/x1 0x1c0/y1, 0xe0/x2 0x180/y2, 0x2a/color - 147 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x2a0/y1, 0xe0/x2 0x2a0/y2, 0x2a/color - 148 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x210/x1 0x60/y1, 0x200/x2 0x60/y2, 0x2a/color - 149 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x210/x1 0x230/y1, 0x200/x2 0x2a0/y2, 0x2a/color - 150 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x120/y1, 0x320/x2 0x60/y2, 0x2a/color - 151 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x1c0/y1 0x320/x2 0x180/y2, 0x2a/color - 152 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x230/y1, 0x320/x2 0x2a0/y2, 0x2a/color - 153 # time-variant portion: 16 repeating steps - 154 var tick-a/eax: (addr int) <- get self, tick - 155 var progress/eax: int <- copy *tick-a - 156 progress <- and 0xf - 157 # 7 time steps for getting inputs to sum - 158 { - 159 compare progress, 7 - 160 break-if->= - 161 var u/xmm7: float <- convert progress - 162 var six/eax: int <- copy 6 - 163 var six-f/xmm0: float <- convert six - 164 u <- divide six-f - 165 # points on conveyors from neighboring cells - 166 draw-bezier-point screen, u, 0xa0/x0 0x20/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius - 167 draw-bezier-point screen, u, 0xa0/x0 0x180/y0, 0xc0/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius - 168 draw-bezier-point screen, u, 0xa0/x0 0x2e0/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius - 169 draw-bezier-point screen, u, 0x200/x0 0x20/y0, 0x180/x1 0x90/y1, 0x180/xs 0x150/ys, 7/color, 4/radius - 170 draw-bezier-point screen, u, 0x200/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 7/color, 4/radius - 171 draw-bezier-point screen, u, 0x360/x0 0x20/y0, 0x180/x1 0xc0/y1, 0x180/xs 0x150/ys, 7/color, 4/radius - 172 draw-bezier-point screen, u, 0x360/x0 0x180/y0, 0x35c/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius - 173 draw-bezier-point screen, u, 0x360/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 7/color, 4/radius - 174 return - 175 } - 176 # two time steps for getting count to filter - 177 progress <- subtract 7 - 178 { - 179 compare progress, 2 - 180 break-if->= - 181 progress <- increment # (0, 1) => (1, 2) - 182 var u/xmm7: float <- convert progress - 183 var three/eax: int <- copy 3 - 184 var three-f/xmm0: float <- convert three - 185 u <- divide three-f - 186 draw-linear-point screen, u, 0x180/xs, 0x150/ys, 0x210/xf, 0x1d0/yf, 7/color, 4/radius - 187 set-cursor-position screen, 0x3a/scol, 0x18/srow - 188 var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x60/cury - 189 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg - 190 return - 191 } - 192 # final 7 time steps for updating output - 193 progress <- subtract 2 - 194 # points on conveyors to outputs - 195 var u/xmm7: float <- convert progress - 196 var six/eax: int <- copy 6 - 197 var six-f/xmm0: float <- convert six - 198 u <- divide six-f - 199 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x60/y1, 0xe0/x2 0x60/y2, 7/color, 4/radius - 200 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0xe0/x1 0x1c0/y1, 0xe0/x2 0x180/y2, 7/color, 4/radius - 201 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x2a0/y1, 0xe0/x2 0x2a0/y2, 7/color, 4/radius - 202 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x210/xf 0x60/y1, 0x200/x2 0x60/y2, 7/color, 4/radius - 203 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x210/xf 0x230/y1, 0x200/x2 0x2a0/y2, 7/color, 4/radius - 204 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x120/y1, 0x320/x2 0x60/y2, 7/color, 4/radius - 205 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x1c0/y1, 0x320/x2 0x180/y2, 7/color, 4/radius - 206 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x230/y1, 0x320/x2 0x2a0/y2, 7/color, 4/radius - 207 } - 208 - 209 fn render1 screen: (addr screen), _self: (addr environment) { - 210 var self/esi: (addr environment) <- copy _self - 211 # cell borders - 212 draw-vertical-line screen, 0xe0/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey - 213 draw-vertical-line screen, 0x200/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey - 214 draw-vertical-line screen, 0x320/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey - 215 draw-horizontal-line screen, 0x60/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey - 216 draw-horizontal-line screen, 0x180/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey - 217 draw-horizontal-line screen, 0x2a0/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey - 218 # cell 0: outputs - 219 var color/eax: int <- state-color self, 0x80/curx, 0x60/cury - 220 draw-rect screen, 0xe8/xmin 0x68/ymin, 0x118/xmax 0x98/ymax, color - 221 draw-rect screen, 0xe8/xmin 0xd0/ymin, 0x118/xmax 0x100/ymax, color - 222 draw-rect screen, 0xe8/xmin 0x148/ymin, 0x118/xmax 0x178/ymax, color - 223 draw-rect screen, 0x158/xmin 0x68/ymin, 0x188/xmax 0x98/ymax, color - 224 draw-rect screen, 0x158/xmin 0x148/ymin, 0x188/xmax 0x178/ymax, color - 225 draw-rect screen, 0x1c8/xmin 0x68/ymin, 0x1f8/xmax 0x98/ymax, color - 226 draw-rect screen, 0x1c8/xmin 0xd0/ymin, 0x1f8/xmax 0x100/ymax, color - 227 draw-rect screen, 0x1c8/xmin 0x148/ymin, 0x1f8/xmax 0x178/ymax, color - 228 # cell 1: outputs - 229 var color/eax: int <- state-color self, 0x81/curx, 0x60/cury - 230 draw-rect screen, 0x208/xmin 0x68/ymin, 0x238/xmax 0x98/ymax, color - 231 draw-rect screen, 0x208/xmin 0xd0/ymin, 0x238/xmax 0x100/ymax, color - 232 draw-rect screen, 0x208/xmin 0x148/ymin, 0x238/xmax 0x178/ymax, color - 233 draw-rect screen, 0x278/xmin 0x68/ymin, 0x2a8/xmax 0x98/ymax, color - 234 draw-rect screen, 0x278/xmin 0x148/ymin, 0x2a8/xmax 0x178/ymax, color - 235 draw-rect screen, 0x2e8/xmin 0x68/ymin, 0x318/xmax 0x98/ymax, color - 236 draw-rect screen, 0x2e8/xmin 0xd0/ymin, 0x318/xmax 0x100/ymax, color - 237 draw-rect screen, 0x2e8/xmin 0x148/ymin, 0x318/xmax 0x178/ymax, color - 238 # cell 2: outputs - 239 var color/eax: int <- state-color self, 0x80/curx, 0x61/cury - 240 draw-rect screen, 0xe8/xmin 0x188/ymin, 0x118/xmax 0x1b8/ymax, color - 241 draw-rect screen, 0xe8/xmin 0x1f0/ymin, 0x118/xmax 0x220/ymax, color - 242 draw-rect screen, 0xe8/xmin 0x268/ymin, 0x118/xmax 0x298/ymax, color - 243 draw-rect screen, 0x158/xmin 0x188/ymin, 0x188/xmax 0x1b8/ymax, color - 244 draw-rect screen, 0x158/xmin 0x268/ymin, 0x188/xmax 0x298/ymax, color - 245 draw-rect screen, 0x1c8/xmin 0x188/ymin, 0x1f8/xmax 0x1b8/ymax, color - 246 draw-rect screen, 0x1c8/xmin 0x1f0/ymin, 0x1f8/xmax 0x220/ymax, color - 247 draw-rect screen, 0x1c8/xmin 0x268/ymin, 0x1f8/xmax 0x298/ymax, color - 248 # cell 3: outputs - 249 var color/eax: int <- state-color self, 0x81/curx, 0x61/cury - 250 draw-rect screen, 0x208/xmin 0x188/ymin, 0x238/xmax 0x1b8/ymax, color - 251 draw-rect screen, 0x208/xmin 0x1f0/ymin, 0x238/xmax 0x220/ymax, color - 252 draw-rect screen, 0x208/xmin 0x268/ymin, 0x238/xmax 0x298/ymax, color - 253 draw-rect screen, 0x278/xmin 0x188/ymin, 0x2a8/xmax 0x1b8/ymax, color - 254 draw-rect screen, 0x278/xmin 0x268/ymin, 0x2a8/xmax 0x298/ymax, color - 255 draw-rect screen, 0x2e8/xmin 0x188/ymin, 0x318/xmax 0x1b8/ymax, color - 256 draw-rect screen, 0x2e8/xmin 0x1f0/ymin, 0x318/xmax 0x220/ymax, color - 257 draw-rect screen, 0x2e8/xmin 0x268/ymin, 0x318/xmax 0x298/ymax, color - 258 # neighboring nodes - 259 var color/eax: int <- state-color self, 0x7f/curx, 0x5f/cury - 260 draw-rect screen, 0xa8/xmin 0x28/ymin, 0xd8/xmax 0x58/ymax, color - 261 var color/eax: int <- state-color self, 0x80/curx, 0x5f/cury - 262 draw-rect screen, 0x158/xmin 0x28/ymin, 0x188/xmax 0x58/ymax, color - 263 draw-rect screen, 0x1c8/xmin 0x28/ymin, 0x1f8/xmax 0x58/ymax, color - 264 var color/eax: int <- state-color self, 0x81/curx, 0x5f/cury - 265 draw-rect screen, 0x208/xmin 0x28/ymin, 0x238/xmax 0x58/ymax, color - 266 draw-rect screen, 0x278/xmin 0x28/ymin, 0x2a8/xmax 0x58/ymax, color - 267 var color/eax: int <- state-color self, 0x82/curx, 0x5f/cury - 268 draw-rect screen, 0x328/xmin 0x28/ymin, 0x358/xmax 0x58/ymax, color - 269 var color/eax: int <- state-color self, 0x7f/curx, 0x60/cury - 270 draw-rect screen, 0xa8/xmin 0xd0/ymin, 0xd8/xmax 0x100/ymax, color - 271 draw-rect screen, 0xa8/xmin 0x148/ymin, 0xd8/xmax 0x178/ymax, color - 272 var color/eax: int <- state-color self, 0x82/curx, 0x60/cury - 273 draw-rect screen, 0x328/xmin 0xd0/ymin, 0x358/xmax 0x100/ymax, color - 274 draw-rect screen, 0x328/xmin 0x148/ymin, 0x358/xmax 0x178/ymax, color - 275 var color/eax: int <- state-color self, 0x7f/curx, 0x61/cury - 276 draw-rect screen, 0xa8/xmin 0x188/ymin, 0xd8/xmax 0x1b8/ymax, color - 277 draw-rect screen, 0xa8/xmin 0x1f0/ymin, 0xd8/xmax 0x220/ymax, color - 278 var color/eax: int <- state-color self, 0x82/curx, 0x61/cury - 279 draw-rect screen, 0x328/xmin 0x188/ymin, 0x358/xmax 0x1b8/ymax, color - 280 draw-rect screen, 0x328/xmin 0x1f0/ymin, 0x358/xmax 0x220/ymax, color - 281 var color/eax: int <- state-color self, 0x7f/curx, 0x62/cury - 282 draw-rect screen, 0xa8/xmin 0x2a8/ymin, 0xd8/xmax 0x2d8/ymax, color - 283 var color/eax: int <- state-color self, 0x80/curx, 0x62/cury - 284 draw-rect screen, 0x158/xmin 0x2a8/ymin, 0x188/xmax 0x2d8/ymax, color - 285 draw-rect screen, 0x1c8/xmin 0x2a8/ymin, 0x1f8/xmax 0x2d8/ymax, color - 286 var color/eax: int <- state-color self, 0x81/curx, 0x62/cury - 287 draw-rect screen, 0x208/xmin 0x2a8/ymin, 0x238/xmax 0x2d8/ymax, color - 288 draw-rect screen, 0x278/xmin 0x2a8/ymin, 0x2a8/xmax 0x2d8/ymax, color - 289 var color/eax: int <- state-color self, 0x82/curx, 0x62/cury - 290 draw-rect screen, 0x328/xmin 0x2a8/ymin, 0x358/xmax 0x2d8/ymax, color - 291 # cell 0: sum and filter nodes - 292 draw-rect screen, 0x148/xsmin 0xc8/ysmin, 0x158/xsmax 0xd8/ysmax, 0x40/color - 293 draw-rect screen, 0x180/xfmin 0xf8/yfmin, 0x190/xfmax 0x108/yfmax, 0x31/color - 294 # cell 1: sum and filter nodes - 295 draw-rect screen, 0x268/xsmin 0xc8/ysmin, 0x278/xsmax 0xd8/ysmax, 0x40/color - 296 draw-rect screen, 0x2a0/xfmin 0xf8/yfmin, 0x2b0/xfmax 0x108/yfmax, 0x31/color - 297 # cell 2: sum and filter nodes - 298 draw-rect screen, 0x148/xsmin 0x1e8/ysmin, 0x158/xsmax 0x1f8/ysmax, 0x40/color - 299 draw-rect screen, 0x180/xfmin 0x218/yfmin, 0x190/xfmax 0x228/yfmax, 0x31/color - 300 # cell 3: sum and filter nodes - 301 draw-rect screen, 0x268/xsmin 0x1e8/ysmin, 0x278/xsmax 0x1f8/ysmax, 0x40/color - 302 draw-rect screen, 0x2a0/xfmin 0x218/yfmin, 0x2b0/xfmax 0x228/yfmax, 0x31/color - 303 # neighbor counts - 304 var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x60/cury - 305 set-cursor-position screen, 0x2d, 0xe - 306 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg - 307 var n/eax: int <- num-live-neighbors self, 0x81/curx, 0x60/cury - 308 set-cursor-position screen, 0x52, 0xe + 28 var second-screen/edi: (addr screen) <- address second-buffer + 29 initialize-screen second-screen, 0x80, 0x30, 1/include-pixels + 30 render second-screen, env + 31 convert-graphemes-to-pixels second-screen + 32 copy-pixels second-screen, screen + 33 { + 34 edit keyboard, env + 35 var play?/eax: (addr boolean) <- get env, play? + 36 compare *play?, 0/false + 37 { + 38 break-if-= + 39 step env + 40 clear-screen second-screen + 41 render second-screen, env + 42 convert-graphemes-to-pixels second-screen + 43 copy-pixels second-screen, screen + 44 } + 45 linger env + 46 loop + 47 } + 48 } + 49 + 50 type environment { + 51 data: (handle array handle array cell) + 52 zoom: int # 0 = 1024 px per cell; 5 = 4px per cell; each step adjusts by a factor of 4 + 53 tick: int + 54 play?: boolean + 55 loop: int # if non-zero, return tick to 0 after this point + 56 } + 57 + 58 type cell { + 59 curr: boolean + 60 next: boolean + 61 } + 62 + 63 fn render screen: (addr screen), _self: (addr environment) { + 64 var self/esi: (addr environment) <- copy _self + 65 var zoom/eax: (addr int) <- get self, zoom + 66 compare *zoom, 0 + 67 { + 68 break-if-!= + 69 clear-screen screen + 70 render0 screen, self + 71 } + 72 compare *zoom, 1 + 73 { + 74 break-if-!= + 75 clear-screen screen + 76 render1 screen, self + 77 } + 78 compare *zoom, 4 + 79 { + 80 break-if-!= + 81 render4 screen, self + 82 } + 83 # clock + 84 var tick-a/eax: (addr int) <- get self, tick + 85 set-cursor-position screen, 0x78/x, 0/y + 86 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, *tick-a, 7/fg 0/bg + 87 } + 88 + 89 # Lots of hardcoded constants for now. + 90 # TODO: split this up into a primitive to render a single cell and its + 91 # incoming edges (but not the neighboring nodes they emanate from) + 92 fn render0 screen: (addr screen), _self: (addr environment) { + 93 var self/esi: (addr environment) <- copy _self + 94 # cell border + 95 draw-vertical-line screen, 0xc0/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey + 96 draw-vertical-line screen, 0x340/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey + 97 draw-horizontal-line screen, 0x40/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey + 98 draw-horizontal-line screen, 0x2c0/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey + 99 # neighboring inputs, corners + 100 var color/eax: int <- state-color self, 0x7f/cur-topleftx, 0x5f/cur-toplefty + 101 draw-rect screen, 0x90/xmin 0x10/ymin, 0xb0/xmax 0x30/ymax, color + 102 color <- state-color self, 0x81/cur-toprightx, 0x5f/cur-toprighty + 103 draw-rect screen, 0x350/xmin 0x10/ymin, 0x370/xmax 0x30/ymax, color + 104 color <- state-color self, 0x7f/cur-botleftx, 0x61/cur-botlefty + 105 draw-rect screen, 0x90/xmin 0x2d0/ymin, 0xb0/xmax 0x2f0/ymax, color + 106 color <- state-color self, 0x81/cur-botrightx, 0x61/cur-botrighty + 107 draw-rect screen, 0x350/xmin 0x2d0/ymin, 0x370/xmax 0x2f0/ymax, color + 108 # neighboring inputs, edges + 109 color <- state-color self, 0x80/cur-topx, 0x5f/cur-topy + 110 draw-rect screen, 0x1f0/xmin 0x10/ymin, 0x210/xmax 0x30/ymax, color + 111 color <- state-color self, 0x7f/cur-leftx, 0x60/cur-lefty + 112 draw-rect screen, 0x90/xmin 0x170/ymin, 0xb0/xmax 0x190/ymax, color + 113 color <- state-color self, 0x80/cur-botx, 0x61/cur-boty + 114 draw-rect screen, 0x1f0/xmin 0x2d0/ymin, 0x210/xmax 0x2f0/ymax, color + 115 color <- state-color self, 0x81/cur-rightx, 0x60/cur-righty + 116 draw-rect screen, 0x350/xmin 0x170/ymin, 0x370/xmax 0x190/ymax, color + 117 # sum node + 118 draw-rect screen, 0x170/xsmin 0x140/ysmin, 0x190/xsmax 0x160/ysmax, 0x40/color + 119 set-cursor-position screen, 0x2d/scol, 0x13/srow + 120 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "+", 0xf/color, 0/bg + 121 # conveyors from neighboring inputs to sum node + 122 draw-monotonic-bezier screen, 0xa0/x0 0x20/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color + 123 draw-monotonic-bezier screen, 0xa0/x0 0x180/y0, 0xc0/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color + 124 draw-monotonic-bezier screen, 0xa0/x0 0x2e0/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color + 125 draw-monotonic-bezier screen, 0x200/x0 0x20/y0, 0x180/x1 0x90/y1, 0x180/xs 0x150/ys, 4/color + 126 draw-monotonic-bezier screen, 0x200/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 4/color + 127 draw-monotonic-bezier screen, 0x360/x0 0x20/y0, 0x180/x1 0xc0/y1, 0x180/xs 0x150/ys, 4/color + 128 draw-monotonic-bezier screen, 0x360/x0 0x180/y0, 0x35c/x1 0x150/ys, 0x180/xs 0x150/ys, 4/color + 129 draw-monotonic-bezier screen, 0x360/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 4/color + 130 # filter node + 131 draw-rect screen, 0x200/xfmin 0x1c0/yfmin, 0x220/xfmax 0x1e0/yfmax, 0x31/color + 132 set-cursor-position screen, 0x40/fcol, 0x1b/frow + 133 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "?", 0xf/color, 0/bg + 134 # conveyor from sum node to filter node + 135 draw-line screen 0x180/xs, 0x150/ys, 0x210/xf, 0x1d0/yf, 0xa2/color + 136 # cell outputs at corners + 137 var color/eax: int <- state-color self, 0x80/curx, 0x60/cury + 138 draw-rect screen, 0xd0/xmin 0x50/ymin, 0xf0/xmax 0x70/ymax, color + 139 draw-rect screen, 0x310/xmin 0x50/ymin, 0x330/xmax 0x70/ymax, color + 140 draw-rect screen, 0xd0/xmin 0x290/ymin, 0xf0/xmax 0x2b0/ymax, color + 141 draw-rect screen, 0x310/xmin 0x290/ymin, 0x330/xmax 0x2b0/ymax, color + 142 # cell outputs at edges + 143 draw-rect screen, 0x1f0/xmin 0x50/ymin, 0x210/xmax 0x70/ymax, color + 144 draw-rect screen, 0xd0/xmin 0x170/ymin, 0xf0/xmax 0x190/ymax, color + 145 draw-rect screen, 0x1f0/xmin 0x290/ymin, 0x210/xmax 0x2b0/ymax, color + 146 draw-rect screen, 0x310/xmin 0x170/ymin, 0x330/xmax 0x190/ymax, color + 147 # conveyors from filter to outputs + 148 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x60/y1, 0xe0/x2 0x60/y2, 0x2a/color + 149 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0xe0/x1 0x1c0/y1, 0xe0/x2 0x180/y2, 0x2a/color + 150 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x2a0/y1, 0xe0/x2 0x2a0/y2, 0x2a/color + 151 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x210/x1 0x60/y1, 0x200/x2 0x60/y2, 0x2a/color + 152 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x210/x1 0x230/y1, 0x200/x2 0x2a0/y2, 0x2a/color + 153 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x120/y1, 0x320/x2 0x60/y2, 0x2a/color + 154 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x1c0/y1 0x320/x2 0x180/y2, 0x2a/color + 155 draw-monotonic-bezier screen, 0x210/xf 0x1d0/yf, 0x320/x1 0x230/y1, 0x320/x2 0x2a0/y2, 0x2a/color + 156 # time-variant portion: 16 repeating steps + 157 var tick-a/eax: (addr int) <- get self, tick + 158 var progress/eax: int <- copy *tick-a + 159 progress <- and 0xf + 160 # 7 time steps for getting inputs to sum + 161 { + 162 compare progress, 7 + 163 break-if->= + 164 var u/xmm7: float <- convert progress + 165 var six/eax: int <- copy 6 + 166 var six-f/xmm0: float <- convert six + 167 u <- divide six-f + 168 # points on conveyors from neighboring cells + 169 draw-bezier-point screen, u, 0xa0/x0 0x20/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius + 170 draw-bezier-point screen, u, 0xa0/x0 0x180/y0, 0xc0/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius + 171 draw-bezier-point screen, u, 0xa0/x0 0x2e0/y0, 0x100/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius + 172 draw-bezier-point screen, u, 0x200/x0 0x20/y0, 0x180/x1 0x90/y1, 0x180/xs 0x150/ys, 7/color, 4/radius + 173 draw-bezier-point screen, u, 0x200/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 7/color, 4/radius + 174 draw-bezier-point screen, u, 0x360/x0 0x20/y0, 0x180/x1 0xc0/y1, 0x180/xs 0x150/ys, 7/color, 4/radius + 175 draw-bezier-point screen, u, 0x360/x0 0x180/y0, 0x35c/x1 0x150/ys, 0x180/xs 0x150/ys, 7/color, 4/radius + 176 draw-bezier-point screen, u, 0x360/x0 0x2e0/y0, 0x180/x1 0x200/y1, 0x180/xs 0x150/ys, 7/color, 4/radius + 177 return + 178 } + 179 # two time steps for getting count to filter + 180 progress <- subtract 7 + 181 { + 182 compare progress, 2 + 183 break-if->= + 184 progress <- increment # (0, 1) => (1, 2) + 185 var u/xmm7: float <- convert progress + 186 var three/eax: int <- copy 3 + 187 var three-f/xmm0: float <- convert three + 188 u <- divide three-f + 189 draw-linear-point screen, u, 0x180/xs, 0x150/ys, 0x210/xf, 0x1d0/yf, 7/color, 4/radius + 190 set-cursor-position screen, 0x3a/scol, 0x18/srow + 191 var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x60/cury + 192 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg + 193 return + 194 } + 195 # final 7 time steps for updating output + 196 progress <- subtract 2 + 197 # points on conveyors to outputs + 198 var u/xmm7: float <- convert progress + 199 var six/eax: int <- copy 6 + 200 var six-f/xmm0: float <- convert six + 201 u <- divide six-f + 202 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x60/y1, 0xe0/x2 0x60/y2, 7/color, 4/radius + 203 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0xe0/x1 0x1c0/y1, 0xe0/x2 0x180/y2, 7/color, 4/radius + 204 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x1c0/x1 0x2a0/y1, 0xe0/x2 0x2a0/y2, 7/color, 4/radius + 205 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x210/xf 0x60/y1, 0x200/x2 0x60/y2, 7/color, 4/radius + 206 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x210/xf 0x230/y1, 0x200/x2 0x2a0/y2, 7/color, 4/radius + 207 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x120/y1, 0x320/x2 0x60/y2, 7/color, 4/radius + 208 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x1c0/y1, 0x320/x2 0x180/y2, 7/color, 4/radius + 209 draw-bezier-point screen, u, 0x210/xf 0x1d0/yf, 0x320/x1 0x230/y1, 0x320/x2 0x2a0/y2, 7/color, 4/radius + 210 } + 211 + 212 fn render1 screen: (addr screen), _self: (addr environment) { + 213 var self/esi: (addr environment) <- copy _self + 214 # cell borders + 215 draw-vertical-line screen, 0xe0/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey + 216 draw-vertical-line screen, 0x200/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey + 217 draw-vertical-line screen, 0x320/x, 0/ymin, 0x300/ymax, 0x16/color=dark-grey + 218 draw-horizontal-line screen, 0x60/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey + 219 draw-horizontal-line screen, 0x180/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey + 220 draw-horizontal-line screen, 0x2a0/y, 0/xmin, 0x400/xmax, 0x16/color=dark-grey + 221 # cell 0: outputs + 222 var color/eax: int <- state-color self, 0x80/curx, 0x60/cury + 223 draw-rect screen, 0xe8/xmin 0x68/ymin, 0x118/xmax 0x98/ymax, color + 224 draw-rect screen, 0xe8/xmin 0xd0/ymin, 0x118/xmax 0x100/ymax, color + 225 draw-rect screen, 0xe8/xmin 0x148/ymin, 0x118/xmax 0x178/ymax, color + 226 draw-rect screen, 0x158/xmin 0x68/ymin, 0x188/xmax 0x98/ymax, color + 227 draw-rect screen, 0x158/xmin 0x148/ymin, 0x188/xmax 0x178/ymax, color + 228 draw-rect screen, 0x1c8/xmin 0x68/ymin, 0x1f8/xmax 0x98/ymax, color + 229 draw-rect screen, 0x1c8/xmin 0xd0/ymin, 0x1f8/xmax 0x100/ymax, color + 230 draw-rect screen, 0x1c8/xmin 0x148/ymin, 0x1f8/xmax 0x178/ymax, color + 231 # cell 1: outputs + 232 var color/eax: int <- state-color self, 0x81/curx, 0x60/cury + 233 draw-rect screen, 0x208/xmin 0x68/ymin, 0x238/xmax 0x98/ymax, color + 234 draw-rect screen, 0x208/xmin 0xd0/ymin, 0x238/xmax 0x100/ymax, color + 235 draw-rect screen, 0x208/xmin 0x148/ymin, 0x238/xmax 0x178/ymax, color + 236 draw-rect screen, 0x278/xmin 0x68/ymin, 0x2a8/xmax 0x98/ymax, color + 237 draw-rect screen, 0x278/xmin 0x148/ymin, 0x2a8/xmax 0x178/ymax, color + 238 draw-rect screen, 0x2e8/xmin 0x68/ymin, 0x318/xmax 0x98/ymax, color + 239 draw-rect screen, 0x2e8/xmin 0xd0/ymin, 0x318/xmax 0x100/ymax, color + 240 draw-rect screen, 0x2e8/xmin 0x148/ymin, 0x318/xmax 0x178/ymax, color + 241 # cell 2: outputs + 242 var color/eax: int <- state-color self, 0x80/curx, 0x61/cury + 243 draw-rect screen, 0xe8/xmin 0x188/ymin, 0x118/xmax 0x1b8/ymax, color + 244 draw-rect screen, 0xe8/xmin 0x1f0/ymin, 0x118/xmax 0x220/ymax, color + 245 draw-rect screen, 0xe8/xmin 0x268/ymin, 0x118/xmax 0x298/ymax, color + 246 draw-rect screen, 0x158/xmin 0x188/ymin, 0x188/xmax 0x1b8/ymax, color + 247 draw-rect screen, 0x158/xmin 0x268/ymin, 0x188/xmax 0x298/ymax, color + 248 draw-rect screen, 0x1c8/xmin 0x188/ymin, 0x1f8/xmax 0x1b8/ymax, color + 249 draw-rect screen, 0x1c8/xmin 0x1f0/ymin, 0x1f8/xmax 0x220/ymax, color + 250 draw-rect screen, 0x1c8/xmin 0x268/ymin, 0x1f8/xmax 0x298/ymax, color + 251 # cell 3: outputs + 252 var color/eax: int <- state-color self, 0x81/curx, 0x61/cury + 253 draw-rect screen, 0x208/xmin 0x188/ymin, 0x238/xmax 0x1b8/ymax, color + 254 draw-rect screen, 0x208/xmin 0x1f0/ymin, 0x238/xmax 0x220/ymax, color + 255 draw-rect screen, 0x208/xmin 0x268/ymin, 0x238/xmax 0x298/ymax, color + 256 draw-rect screen, 0x278/xmin 0x188/ymin, 0x2a8/xmax 0x1b8/ymax, color + 257 draw-rect screen, 0x278/xmin 0x268/ymin, 0x2a8/xmax 0x298/ymax, color + 258 draw-rect screen, 0x2e8/xmin 0x188/ymin, 0x318/xmax 0x1b8/ymax, color + 259 draw-rect screen, 0x2e8/xmin 0x1f0/ymin, 0x318/xmax 0x220/ymax, color + 260 draw-rect screen, 0x2e8/xmin 0x268/ymin, 0x318/xmax 0x298/ymax, color + 261 # neighboring nodes + 262 var color/eax: int <- state-color self, 0x7f/curx, 0x5f/cury + 263 draw-rect screen, 0xa8/xmin 0x28/ymin, 0xd8/xmax 0x58/ymax, color + 264 var color/eax: int <- state-color self, 0x80/curx, 0x5f/cury + 265 draw-rect screen, 0x158/xmin 0x28/ymin, 0x188/xmax 0x58/ymax, color + 266 draw-rect screen, 0x1c8/xmin 0x28/ymin, 0x1f8/xmax 0x58/ymax, color + 267 var color/eax: int <- state-color self, 0x81/curx, 0x5f/cury + 268 draw-rect screen, 0x208/xmin 0x28/ymin, 0x238/xmax 0x58/ymax, color + 269 draw-rect screen, 0x278/xmin 0x28/ymin, 0x2a8/xmax 0x58/ymax, color + 270 var color/eax: int <- state-color self, 0x82/curx, 0x5f/cury + 271 draw-rect screen, 0x328/xmin 0x28/ymin, 0x358/xmax 0x58/ymax, color + 272 var color/eax: int <- state-color self, 0x7f/curx, 0x60/cury + 273 draw-rect screen, 0xa8/xmin 0xd0/ymin, 0xd8/xmax 0x100/ymax, color + 274 draw-rect screen, 0xa8/xmin 0x148/ymin, 0xd8/xmax 0x178/ymax, color + 275 var color/eax: int <- state-color self, 0x82/curx, 0x60/cury + 276 draw-rect screen, 0x328/xmin 0xd0/ymin, 0x358/xmax 0x100/ymax, color + 277 draw-rect screen, 0x328/xmin 0x148/ymin, 0x358/xmax 0x178/ymax, color + 278 var color/eax: int <- state-color self, 0x7f/curx, 0x61/cury + 279 draw-rect screen, 0xa8/xmin 0x188/ymin, 0xd8/xmax 0x1b8/ymax, color + 280 draw-rect screen, 0xa8/xmin 0x1f0/ymin, 0xd8/xmax 0x220/ymax, color + 281 var color/eax: int <- state-color self, 0x82/curx, 0x61/cury + 282 draw-rect screen, 0x328/xmin 0x188/ymin, 0x358/xmax 0x1b8/ymax, color + 283 draw-rect screen, 0x328/xmin 0x1f0/ymin, 0x358/xmax 0x220/ymax, color + 284 var color/eax: int <- state-color self, 0x7f/curx, 0x62/cury + 285 draw-rect screen, 0xa8/xmin 0x2a8/ymin, 0xd8/xmax 0x2d8/ymax, color + 286 var color/eax: int <- state-color self, 0x80/curx, 0x62/cury + 287 draw-rect screen, 0x158/xmin 0x2a8/ymin, 0x188/xmax 0x2d8/ymax, color + 288 draw-rect screen, 0x1c8/xmin 0x2a8/ymin, 0x1f8/xmax 0x2d8/ymax, color + 289 var color/eax: int <- state-color self, 0x81/curx, 0x62/cury + 290 draw-rect screen, 0x208/xmin 0x2a8/ymin, 0x238/xmax 0x2d8/ymax, color + 291 draw-rect screen, 0x278/xmin 0x2a8/ymin, 0x2a8/xmax 0x2d8/ymax, color + 292 var color/eax: int <- state-color self, 0x82/curx, 0x62/cury + 293 draw-rect screen, 0x328/xmin 0x2a8/ymin, 0x358/xmax 0x2d8/ymax, color + 294 # cell 0: sum and filter nodes + 295 draw-rect screen, 0x148/xsmin 0xc8/ysmin, 0x158/xsmax 0xd8/ysmax, 0x40/color + 296 draw-rect screen, 0x180/xfmin 0xf8/yfmin, 0x190/xfmax 0x108/yfmax, 0x31/color + 297 # cell 1: sum and filter nodes + 298 draw-rect screen, 0x268/xsmin 0xc8/ysmin, 0x278/xsmax 0xd8/ysmax, 0x40/color + 299 draw-rect screen, 0x2a0/xfmin 0xf8/yfmin, 0x2b0/xfmax 0x108/yfmax, 0x31/color + 300 # cell 2: sum and filter nodes + 301 draw-rect screen, 0x148/xsmin 0x1e8/ysmin, 0x158/xsmax 0x1f8/ysmax, 0x40/color + 302 draw-rect screen, 0x180/xfmin 0x218/yfmin, 0x190/xfmax 0x228/yfmax, 0x31/color + 303 # cell 3: sum and filter nodes + 304 draw-rect screen, 0x268/xsmin 0x1e8/ysmin, 0x278/xsmax 0x1f8/ysmax, 0x40/color + 305 draw-rect screen, 0x2a0/xfmin 0x218/yfmin, 0x2b0/xfmax 0x228/yfmax, 0x31/color + 306 # neighbor counts + 307 var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x60/cury + 308 set-cursor-position screen, 0x2d, 0xe 309 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg - 310 var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x61/cury - 311 set-cursor-position screen, 0x2d, 0x20 + 310 var n/eax: int <- num-live-neighbors self, 0x81/curx, 0x60/cury + 311 set-cursor-position screen, 0x52, 0xe 312 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg - 313 var n/eax: int <- num-live-neighbors self, 0x81/curx, 0x61/cury - 314 set-cursor-position screen, 0x52, 0x20 + 313 var n/eax: int <- num-live-neighbors self, 0x80/curx, 0x61/cury + 314 set-cursor-position screen, 0x2d, 0x20 315 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg - 316 # cell 0: conveyors from neighboring inputs to sum node - 317 draw-monotonic-bezier screen, 0xc0/x0 0x40/y0, 0x100/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color - 318 draw-monotonic-bezier screen, 0xc0/x0 0xe8/y0, 0xc0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color - 319 draw-monotonic-bezier screen, 0xc0/x0 0x1a0/y0, 0xe0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color - 320 draw-monotonic-bezier screen, 0x170/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 4/color - 321 draw-monotonic-bezier screen, 0x170/x0 0x1a0/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 4/color - 322 draw-monotonic-bezier screen, 0x220/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 4/color - 323 draw-monotonic-bezier screen, 0x220/x0 0xe8/y0, 0x220/x1 0xd0/y1, 0x150/xs 0xd0/ys, 4/color - 324 draw-monotonic-bezier screen, 0x220/x0 0x1a0/y0, 0x180/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 4/color - 325 # cell 0: conveyors from filter to outputs - 326 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x160/x1 0x8c/y1, 0x100/x2 0x80/y2, 0x2a/color - 327 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0xe8/y2, 0x2a/color - 328 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0x160/y2, 0x2a/color - 329 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x188/x1 0x80/y1, 0x170/x2 0x80/y2, 0x2a/color - 330 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x188/x1 0x160/y1, 0x170/x2 0x160/y2, 0x2a/color - 331 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x80/y2, 0x2a/color - 332 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1 0x1e0/x2 0xe8/y2, 0x2a/color - 333 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x160/y2, 0x2a/color - 334 # cell 0: time-variant portion: 16 repeating steps - 335 $render1:cell0: { - 336 var tick-a/eax: (addr int) <- get self, tick - 337 var progress/eax: int <- copy *tick-a - 338 progress <- and 0xf - 339 # cell 0: 7 time steps for getting inputs to sum - 340 { - 341 compare progress, 7 - 342 break-if->= - 343 var u/xmm7: float <- convert progress - 344 var six/eax: int <- copy 6 - 345 var six-f/xmm0: float <- convert six - 346 u <- divide six-f - 347 # points on conveyors from neighboring cells - 348 draw-bezier-point screen, u, 0xc0/x0 0x40/y0, 0x100/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius - 349 draw-bezier-point screen, u, 0xc0/x0 0xe8/y0, 0xc0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius - 350 draw-bezier-point screen, u, 0xc0/x0 0x1a0/y0, 0xe0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius - 351 draw-bezier-point screen, u, 0x170/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius - 352 draw-bezier-point screen, u, 0x170/x0 0x1a0/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius - 353 draw-bezier-point screen, u, 0x220/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius - 354 draw-bezier-point screen, u, 0x220/x0 0xe8/y0, 0x220/x1 0xd0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius - 355 draw-bezier-point screen, u, 0x220/x0 0x1a0/y0, 0x180/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius - 356 break $render1:cell0 - 357 } - 358 # cell 0: two time steps for getting count to filter - 359 progress <- subtract 7 - 360 { - 361 compare progress, 2 - 362 break-if->= - 363 break $render1:cell0 - 364 } - 365 # cell 0: final 7 time steps for updating output - 366 progress <- subtract 2 - 367 # cell 0: points on conveyors to outputs - 368 var u/xmm7: float <- convert progress - 369 var six/eax: int <- copy 6 - 370 var six-f/xmm0: float <- convert six - 371 u <- divide six-f - 372 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x160/x1 0x8c/y1, 0x100/x2 0x80/y2, 7/color, 4/radius - 373 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0xe8/y2, 7/color, 4/radius - 374 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0x160/y2, 7/color, 4/radius - 375 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x188/xf 0x80/y1, 0x170/x2 0x80/y2, 7/color, 4/radius - 376 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x188/xf 0x160/y1, 0x170/x2 0x160/y2, 7/color, 4/radius - 377 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x80/y2, 7/color, 4/radius - 378 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0xe8/y2, 7/color, 4/radius - 379 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x160/y2, 7/color, 4/radius - 380 } - 381 # cell 1: conveyors from neighboring inputs to sum node - 382 draw-monotonic-bezier screen, 0x1e0/x0 0x40/y0, 0x220/x1 0xd0/ys, 0x270/xs 0xd0/ys, 4/color - 383 draw-monotonic-bezier screen, 0x1e0/x0 0xe8/y0, 0x1e0/x1 0xd0/ys, 0x270/xs 0xd0/ys, 4/color - 384 draw-monotonic-bezier screen, 0x1e0/x0 0x1a0/y0, 0x200/x1 0xd0/ys, 0x270/xs 0xd0/ys, 4/color - 385 draw-monotonic-bezier screen, 0x290/x0 0x40/y0, 0x270/x1 0x80/y1, 0x270/xs 0xd0/ys, 4/color - 386 draw-monotonic-bezier screen, 0x290/x0 0x1a0/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0xd0/ys, 4/color - 387 draw-monotonic-bezier screen, 0x340/x0 0x40/y0, 0x270/x1 0x80/y1, 0x270/xs 0xd0/ys, 4/color - 388 draw-monotonic-bezier screen, 0x340/x0 0xe8/y0, 0x340/x1 0xd0/y1, 0x270/xs 0xd0/ys, 4/color - 389 draw-monotonic-bezier screen, 0x340/x0 0x1a0/y0, 0x2a0/x1 0x1a0/y1, 0x270/xs 0xd0/ys, 4/color - 390 # cell 1: conveyors from filter to outputs - 391 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x280/x1 0x8c/y1, 0x220/x2 0x80/y2, 0x2a/color - 392 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x220/x1 0x100/y1, 0x220/x2 0xe8/y2, 0x2a/color - 393 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x220/x1 0x100/y1, 0x220/x2 0x160/y2, 0x2a/color - 394 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x2a8/x1 0x80/y1, 0x290/x2 0x80/y2, 0x2a/color - 395 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x2a8/x1 0x160/y1, 0x290/x2 0x160/y2, 0x2a/color - 396 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0x80/y2, 0x2a/color - 397 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1 0x300/x2 0xe8/y2, 0x2a/color - 398 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0x160/y2, 0x2a/color - 399 # cell 1: time-variant portion: 16 repeating steps - 400 $render1:cell1: { - 401 var tick-a/eax: (addr int) <- get self, tick - 402 var progress/eax: int <- copy *tick-a - 403 progress <- and 0xf - 404 # cell 1: 7 time steps for getting inputs to sum - 405 { - 406 compare progress, 7 - 407 break-if->= - 408 var u/xmm7: float <- convert progress - 409 var six/eax: int <- copy 6 - 410 var six-f/xmm0: float <- convert six - 411 u <- divide six-f - 412 # points on conveyors from neighboring cells - 413 draw-bezier-point screen, u, 0x1e0/x0 0x40/y0, 0x220/x1 0xd0/ys, 0x270/xs 0xd0/ys, 7/color, 4/radius - 414 draw-bezier-point screen, u, 0x1e0/x0 0xe8/y0, 0x1e0/x1 0xd0/ys, 0x270/xs 0xd0/ys, 7/color, 4/radius - 415 draw-bezier-point screen, u, 0x1e0/x0 0x1a0/y0, 0x200/x1 0xd0/ys, 0x270/xs 0xd0/ys, 7/color, 4/radius - 416 draw-bezier-point screen, u, 0x290/x0 0x40/y0, 0x270/x1 0x80/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius - 417 draw-bezier-point screen, u, 0x290/x0 0x1a0/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius - 418 draw-bezier-point screen, u, 0x340/x0 0x40/y0, 0x270/x1 0x80/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius - 419 draw-bezier-point screen, u, 0x340/x0 0xe8/y0, 0x340/x1 0xd0/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius - 420 draw-bezier-point screen, u, 0x340/x0 0x1a0/y0, 0x2a0/x1 0x1a0/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius - 421 break $render1:cell1 - 422 } - 423 # cell 1: two time steps for getting count to filter - 424 progress <- subtract 7 - 425 { - 426 compare progress, 2 - 427 break-if->= - 428 break $render1:cell1 - 429 } - 430 # cell 1: final 7 time steps for updating output - 431 progress <- subtract 2 - 432 # cell 1: points on conveyors to outputs - 433 var u/xmm7: float <- convert progress - 434 var six/eax: int <- copy 6 - 435 var six-f/xmm0: float <- convert six - 436 u <- divide six-f - 437 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x280/x1 0x8c/y1, 0x220/x2 0x80/y2, 7/color, 4/radius - 438 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x220/x1 0x100/y1, 0x220/x2 0xe8/y2, 7/color, 4/radius - 439 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x220/x1 0x100/y1, 0x220/x2 0x160/y2, 7/color, 4/radius - 440 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x2a8/xf 0x80/y1, 0x290/x2 0x80/y2, 7/color, 4/radius - 441 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x2a8/xf 0x160/y1, 0x290/x2 0x160/y2, 7/color, 4/radius - 442 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0x80/y2, 7/color, 4/radius - 443 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0xe8/y2, 7/color, 4/radius - 444 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0x160/y2, 7/color, 4/radius - 445 } - 446 # cell 2: conveyors from neighboring inputs to sum node - 447 draw-monotonic-bezier screen, 0xc0/x0 0x160/y0, 0x100/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 4/color - 448 draw-monotonic-bezier screen, 0xc0/x0 0x208/y0, 0xc0/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 4/color - 449 draw-monotonic-bezier screen, 0xc0/x0 0x2c0/y0, 0xe0/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 4/color - 450 draw-monotonic-bezier screen, 0x170/x0 0x160/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0x1f0/ys, 4/color - 451 draw-monotonic-bezier screen, 0x170/x0 0x2c0/y0, 0x150/x1 0x2c0/y1, 0x150/xs 0x1f0/ys, 4/color - 452 draw-monotonic-bezier screen, 0x220/x0 0x160/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0x1f0/ys, 4/color - 453 draw-monotonic-bezier screen, 0x220/x0 0x208/y0, 0x220/x1 0x1f0/y1, 0x150/xs 0x1f0/ys, 4/color - 454 draw-monotonic-bezier screen, 0x220/x0 0x2c0/y0, 0x180/x1 0x2c0/y1, 0x150/xs 0x1f0/ys, 4/color - 455 # cell 2: conveyors from filter to outputs - 456 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x160/x1 0x1ac/y1, 0x100/x2 0x1a0/y2, 0x2a/color - 457 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x100/x1 0x220/y1, 0x100/x2 0x208/y2, 0x2a/color - 458 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x100/x1 0x220/y1, 0x100/x2 0x280/y2, 0x2a/color - 459 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x188/x1 0x1a0/y1, 0x170/x2 0x1a0/y2, 0x2a/color - 460 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x188/x1 0x280/y1, 0x170/x2 0x280/y2, 0x2a/color - 461 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x1a0/y2, 0x2a/color - 462 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1 0x1e0/x2 0x208/y2, 0x2a/color - 463 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x280/y2, 0x2a/color - 464 # cell 2: time-variant portion: 16 repeating steps - 465 $render1:cell2: { - 466 var tick-a/eax: (addr int) <- get self, tick - 467 var progress/eax: int <- copy *tick-a - 468 progress <- and 0xf - 469 # cell 2: 7 time steps for getting inputs to sum - 470 { - 471 compare progress, 7 - 472 break-if->= - 473 var u/xmm7: float <- convert progress - 474 var six/eax: int <- copy 6 - 475 var six-f/xmm0: float <- convert six - 476 u <- divide six-f - 477 # points on conveyors from neighboring cells - 478 draw-bezier-point screen, u, 0xc0/x0 0x160/y0, 0x100/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 7/color, 4/radius - 479 draw-bezier-point screen, u, 0xc0/x0 0x208/y0, 0xc0/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 7/color, 4/radius - 480 draw-bezier-point screen, u, 0xc0/x0 0x2c0/y0, 0xe0/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 7/color, 4/radius - 481 draw-bezier-point screen, u, 0x170/x0 0x160/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius - 482 draw-bezier-point screen, u, 0x170/x0 0x2c0/y0, 0x150/x1 0x2c0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius - 483 draw-bezier-point screen, u, 0x220/x0 0x160/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius - 484 draw-bezier-point screen, u, 0x220/x0 0x208/y0, 0x220/x1 0x1f0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius - 485 draw-bezier-point screen, u, 0x220/x0 0x2c0/y0, 0x180/x1 0x2c0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius - 486 break $render1:cell2 - 487 } - 488 # cell 2: two time steps for getting count to filter - 489 progress <- subtract 7 - 490 { - 491 compare progress, 2 - 492 break-if->= - 493 break $render1:cell2 - 494 } - 495 # cell 2: final 7 time steps for updating output - 496 progress <- subtract 2 - 497 # cell 2: points on conveyors to outputs - 498 var u/xmm7: float <- convert progress - 499 var six/eax: int <- copy 6 - 500 var six-f/xmm0: float <- convert six - 501 u <- divide six-f - 502 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x160/x1 0x1ac/y1, 0x100/x2 0x1a0/y2, 7/color, 4/radius - 503 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x100/x1 0x220/y1, 0x100/x2 0x208/y2, 7/color, 4/radius - 504 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x100/x1 0x220/y1, 0x100/x2 0x280/y2, 7/color, 4/radius - 505 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x188/xf 0x1a0/y1, 0x170/x2 0x1a0/y2, 7/color, 4/radius - 506 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x188/xf 0x280/y1, 0x170/x2 0x280/y2, 7/color, 4/radius - 507 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x1a0/y2, 7/color, 4/radius - 508 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x208/y2, 7/color, 4/radius - 509 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x280/y2, 7/color, 4/radius - 510 } - 511 # cell 3: conveyors from neighboring inputs to sum node - 512 draw-monotonic-bezier screen, 0x1e0/x0 0x160/y0, 0x220/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 4/color - 513 draw-monotonic-bezier screen, 0x1e0/x0 0x208/y0, 0x1e0/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 4/color - 514 draw-monotonic-bezier screen, 0x1e0/x0 0x2c0/y0, 0x200/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 4/color - 515 draw-monotonic-bezier screen, 0x290/x0 0x160/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0x1f0/ys, 4/color - 516 draw-monotonic-bezier screen, 0x290/x0 0x2c0/y0, 0x270/x1 0x2c0/y1, 0x270/xs 0x1f0/ys, 4/color - 517 draw-monotonic-bezier screen, 0x340/x0 0x160/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0x1f0/ys, 4/color - 518 draw-monotonic-bezier screen, 0x340/x0 0x208/y0, 0x340/x1 0x1f0/y1, 0x270/xs 0x1f0/ys, 4/color - 519 draw-monotonic-bezier screen, 0x340/x0 0x2c0/y0, 0x2a0/x1 0x2c0/y1, 0x270/xs 0x1f0/ys, 4/color - 520 # cell 3: conveyors from filter to outputs - 521 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x280/x1 0x1ac/y1, 0x220/x2 0x1a0/y2, 0x2a/color - 522 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x220/x1 0x220/y1, 0x220/x2 0x208/y2, 0x2a/color - 523 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x220/x1 0x220/y1, 0x220/x2 0x280/y2, 0x2a/color - 524 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x2a8/x1 0x1a0/y1, 0x290/x2 0x1a0/y2, 0x2a/color - 525 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x2a8/x1 0x280/y1, 0x290/x2 0x280/y2, 0x2a/color - 526 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x1a0/y2, 0x2a/color - 527 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1 0x300/x2 0x208/y2, 0x2a/color - 528 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x280/y2, 0x2a/color - 529 # cell 3: time-variant portion: 16 repeating steps - 530 $render1:cell3: { - 531 var tick-a/eax: (addr int) <- get self, tick - 532 var progress/eax: int <- copy *tick-a - 533 progress <- and 0xf - 534 # cell 3: 7 time steps for getting inputs to sum - 535 { - 536 compare progress, 7 - 537 break-if->= - 538 var u/xmm7: float <- convert progress - 539 var six/eax: int <- copy 6 - 540 var six-f/xmm0: float <- convert six - 541 u <- divide six-f - 542 # points on conveyors from neighboring cells - 543 draw-bezier-point screen, u, 0x1e0/x0 0x160/y0, 0x220/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 7/color, 4/radius - 544 draw-bezier-point screen, u, 0x1e0/x0 0x208/y0, 0x1e0/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 7/color, 4/radius - 545 draw-bezier-point screen, u, 0x1e0/x0 0x2c0/y0, 0x200/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 7/color, 4/radius - 546 draw-bezier-point screen, u, 0x290/x0 0x160/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius - 547 draw-bezier-point screen, u, 0x290/x0 0x2c0/y0, 0x270/x1 0x2c0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius - 548 draw-bezier-point screen, u, 0x340/x0 0x160/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius - 549 draw-bezier-point screen, u, 0x340/x0 0x208/y0, 0x340/x1 0x1f0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius - 550 draw-bezier-point screen, u, 0x340/x0 0x2c0/y0, 0x2a0/x1 0x2c0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius - 551 break $render1:cell3 - 552 } - 553 # cell 3: two time steps for getting count to filter - 554 progress <- subtract 7 - 555 { - 556 compare progress, 2 - 557 break-if->= - 558 break $render1:cell3 - 559 } - 560 # cell 3: final 7 time steps for updating output - 561 progress <- subtract 2 - 562 # cell 3: points on conveyors to outputs - 563 var u/xmm7: float <- convert progress - 564 var six/eax: int <- copy 6 - 565 var six-f/xmm0: float <- convert six - 566 u <- divide six-f - 567 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x280/x1 0x1ac/y1, 0x220/x2 0x1a0/y2, 7/color, 4/radius - 568 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x220/x1 0x220/y1, 0x220/x2 0x208/y2, 7/color, 4/radius - 569 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x220/x1 0x220/y1, 0x220/x2 0x280/y2, 7/color, 4/radius - 570 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x2a8/xf 0x1a0/y1, 0x290/x2 0x1a0/y2, 7/color, 4/radius - 571 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x2a8/xf 0x280/y1, 0x290/x2 0x280/y2, 7/color, 4/radius - 572 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x1a0/y2, 7/color, 4/radius - 573 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x208/y2, 7/color, 4/radius - 574 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x280/y2, 7/color, 4/radius - 575 } - 576 } - 577 - 578 fn draw-bezier-point screen: (addr screen), u: float, x0: int, y0: int, x1: int, y1: int, x2: int, y2: int, color: int, radius: int { - 579 var _cy/eax: int <- bezier-point u, y0, y1, y2 - 580 var cy/ecx: int <- copy _cy - 581 var cx/eax: int <- bezier-point u, x0, x1, x2 - 582 draw-disc screen, cx, cy, radius, color, 0xf/border-color=white - 583 } - 584 - 585 fn draw-linear-point screen: (addr screen), u: float, x0: int, y0: int, x1: int, y1: int, color: int, radius: int { - 586 var _cy/eax: int <- line-point u, y0, y1 - 587 var cy/ecx: int <- copy _cy - 588 var cx/eax: int <- line-point u, x0, x1 - 589 draw-disc screen, cx, cy, radius, color, 0xf/border-color=white - 590 } - 591 - 592 fn edit keyboard: (addr keyboard), _self: (addr environment) { - 593 var self/esi: (addr environment) <- copy _self - 594 var key/eax: byte <- read-key keyboard - 595 # space: play/pause - 596 { - 597 compare key, 0x20/space - 598 break-if-!= - 599 var play?/eax: (addr boolean) <- get self, play? - 600 compare *play?, 0/false - 601 { - 602 break-if-= - 603 copy-to *play?, 0/false - 604 return - 605 } - 606 copy-to *play?, 1/true - 607 return - 608 } - 609 # 0: back to start - 610 { - 611 compare key, 0x30/0 - 612 break-if-!= - 613 clear-environment self - 614 return - 615 } - 616 # l: loop from here to start - 617 { - 618 compare key, 0x6c/l - 619 break-if-!= - 620 var tick-a/eax: (addr int) <- get self, tick - 621 var tick/eax: int <- copy *tick-a - 622 var loop/ecx: (addr int) <- get self, loop - 623 copy-to *loop, tick - 624 return - 625 } - 626 # L: reset loop - 627 { - 628 compare key, 0x4c/L - 629 break-if-!= - 630 var loop/eax: (addr int) <- get self, loop - 631 copy-to *loop, 0 - 632 return - 633 } - 634 # -: zoom out - 635 { - 636 compare key, 0x2d/- - 637 break-if-!= - 638 var zoom/eax: (addr int) <- get self, zoom - 639 compare *zoom, 1 - 640 { - 641 break-if-!= - 642 copy-to *zoom, 4 - 643 } - 644 compare *zoom, 0 - 645 { - 646 break-if-!= - 647 copy-to *zoom, 1 - 648 } - 649 # set tick to a multiple of zoom - 650 var tick-a/edx: (addr int) <- get self, tick - 651 clear-lowest-bits tick-a, *zoom - 652 return - 653 } - 654 # +: zoom in - 655 { - 656 compare key, 0x2b/+ - 657 break-if-!= - 658 var zoom/eax: (addr int) <- get self, zoom - 659 compare *zoom, 1 - 660 { - 661 break-if-!= - 662 copy-to *zoom, 0 - 663 } - 664 compare *zoom, 4 - 665 { - 666 break-if-!= - 667 copy-to *zoom, 1 - 668 } - 669 # set tick to a multiple of zoom - 670 var tick-a/edx: (addr int) <- get self, tick - 671 clear-lowest-bits tick-a, *zoom - 672 return - 673 } - 674 } - 675 - 676 fn step _self: (addr environment) { - 677 var self/esi: (addr environment) <- copy _self - 678 var tick-a/ecx: (addr int) <- get self, tick - 679 var zoom/edx: (addr int) <- get self, zoom - 680 compare *zoom, 0 - 681 { - 682 break-if-!= - 683 increment *tick-a - 684 } - 685 compare *zoom, 1 - 686 { - 687 break-if-!= - 688 # I wanted to speed up time, but that doesn't seem very usable. - 689 #? add-to *tick-a, 2 - 690 increment *tick-a - 691 } - 692 compare *zoom, 4 - 693 { - 694 break-if-!= - 695 add-to *tick-a, 0x10 - 696 } - 697 var tick/eax: int <- copy *tick-a - 698 tick <- and 0xf - 699 compare tick, 0 - 700 { - 701 break-if-!= - 702 step4 self - 703 } - 704 var loop-a/eax: (addr int) <- get self, loop - 705 compare *loop-a, 0 - 706 { - 707 break-if-= - 708 var loop/eax: int <- copy *loop-a - 709 compare *tick-a, loop - 710 break-if-< - 711 clear-environment self - 712 } - 713 } - 714 - 715 fn initialize-environment _self: (addr environment) { - 716 var self/esi: (addr environment) <- copy _self - 717 var zoom/eax: (addr int) <- get self, zoom - 718 copy-to *zoom, 0 - 719 var play?/eax: (addr boolean) <- get self, play? - 720 copy-to *play?, 1/true - 721 var data-ah/eax: (addr handle array handle array cell) <- get self, data - 722 populate data-ah, 0x100 - 723 var data/eax: (addr array handle array cell) <- lookup *data-ah - 724 var y/ecx: int <- copy 0 - 725 { - 726 compare y, 0xc0 - 727 break-if->= - 728 var dest-ah/eax: (addr handle array cell) <- index data, y - 729 populate dest-ah, 0x100 - 730 y <- increment - 731 loop - 732 } - 733 set self, 0x80, 0x5f, 1/alive - 734 set self, 0x81, 0x5f, 1/alive - 735 set self, 0x7f, 0x60, 1/alive - 736 set self, 0x80, 0x60, 1/alive - 737 set self, 0x80, 0x61, 1/alive - 738 flush self - 739 } - 740 - 741 fn clear-environment _self: (addr environment) { - 742 var self/esi: (addr environment) <- copy _self - 743 var tick/eax: (addr int) <- get self, tick - 744 copy-to *tick, 0 - 745 # don't touch zoom or play settings - 746 var data-ah/eax: (addr handle array handle array cell) <- get self, data - 747 var data/eax: (addr array handle array cell) <- lookup *data-ah - 748 var y/ecx: int <- copy 0 - 749 { - 750 compare y, 0xc0 - 751 break-if->= - 752 var row-ah/eax: (addr handle array cell) <- index data, y - 753 var row/eax: (addr array cell) <- lookup *row-ah - 754 var x/edx: int <- copy 0 - 755 { - 756 compare x, 0x100 - 757 break-if->= - 758 var dest/eax: (addr cell) <- index row, x - 759 clear-object dest - 760 x <- increment - 761 loop - 762 } - 763 y <- increment - 764 loop - 765 } - 766 set self, 0x80, 0x5f, 1/alive - 767 set self, 0x81, 0x5f, 1/alive - 768 set self, 0x7f, 0x60, 1/alive - 769 set self, 0x80, 0x60, 1/alive - 770 set self, 0x80, 0x61, 1/alive - 771 flush self - 772 } - 773 - 774 fn set _self: (addr environment), _x: int, _y: int, _val: boolean { - 775 var self/esi: (addr environment) <- copy _self - 776 var data-ah/eax: (addr handle array handle array cell) <- get self, data - 777 var data/eax: (addr array handle array cell) <- lookup *data-ah - 778 var y/ecx: int <- copy _y - 779 var row-ah/eax: (addr handle array cell) <- index data, y - 780 var row/eax: (addr array cell) <- lookup *row-ah - 781 var x/ecx: int <- copy _x - 782 var cell/eax: (addr cell) <- index row, x - 783 var dest/eax: (addr boolean) <- get cell, next - 784 var val/ecx: boolean <- copy _val - 785 copy-to *dest, val - 786 } - 787 - 788 fn state _self: (addr environment), _x: int, _y: int -> _/eax: boolean { - 789 var self/esi: (addr environment) <- copy _self - 790 var x/ecx: int <- copy _x - 791 var y/edx: int <- copy _y - 792 # clip at the edge - 793 compare x, 0 - 794 { - 795 break-if->= - 796 return 0/false - 797 } - 798 compare y, 0 - 799 { - 800 break-if->= - 801 return 0/false - 802 } - 803 compare x, 0x100/width - 804 { - 805 break-if-< - 806 return 0/false - 807 } - 808 compare y, 0xc0/height - 809 { - 810 break-if-< - 811 return 0/false - 812 } - 813 var data-ah/eax: (addr handle array handle array cell) <- get self, data - 814 var data/eax: (addr array handle array cell) <- lookup *data-ah - 815 var row-ah/eax: (addr handle array cell) <- index data, y - 816 var row/eax: (addr array cell) <- lookup *row-ah - 817 var cell/eax: (addr cell) <- index row, x - 818 var src/eax: (addr boolean) <- get cell, curr - 819 return *src - 820 } - 821 - 822 fn state-color _self: (addr environment), x: int, y: int -> _/eax: int { - 823 var self/esi: (addr environment) <- copy _self - 824 var color/ecx: int <- copy 0x1a/dead - 825 { - 826 var state/eax: boolean <- state self, x, y - 827 compare state, 0/dead - 828 break-if-= - 829 color <- copy 0xf/alive - 830 } - 831 return color - 832 } - 833 - 834 fn flush _self: (addr environment) { - 835 var self/esi: (addr environment) <- copy _self - 836 var data-ah/eax: (addr handle array handle array cell) <- get self, data - 837 var _data/eax: (addr array handle array cell) <- lookup *data-ah - 838 var data/esi: (addr array handle array cell) <- copy _data - 839 var y/ecx: int <- copy 0 - 840 { - 841 compare y, 0xc0/height - 842 break-if->= - 843 var row-ah/eax: (addr handle array cell) <- index data, y - 844 var _row/eax: (addr array cell) <- lookup *row-ah - 845 var row/ebx: (addr array cell) <- copy _row - 846 var x/edx: int <- copy 0 - 847 { - 848 compare x, 0x100/width - 849 break-if->= - 850 var cell-a/eax: (addr cell) <- index row, x - 851 var curr-a/edi: (addr boolean) <- get cell-a, curr - 852 var next-a/esi: (addr boolean) <- get cell-a, next - 853 var val/eax: boolean <- copy *next-a - 854 copy-to *curr-a, val - 855 copy-to *next-a, 0/dead - 856 x <- increment - 857 loop - 858 } - 859 y <- increment - 860 loop - 861 } - 862 } - 863 - 864 fn render4 screen: (addr screen), _self: (addr environment) { - 865 var self/esi: (addr environment) <- copy _self - 866 var y/ecx: int <- copy 0 - 867 { - 868 compare y, 0xc0/height - 869 break-if->= - 870 var x/edx: int <- copy 0 - 871 { - 872 compare x, 0x100/width - 873 break-if->= - 874 var state/eax: boolean <- state self, x, y - 875 compare state, 0/false - 876 { - 877 break-if-= - 878 render4-cell screen, x, y, 0xf/alive - 879 } - 880 compare state, 0/false - 881 { - 882 break-if-!= - 883 render4-cell screen, x, y, 0x1a/dead - 884 } - 885 x <- increment - 886 loop - 887 } - 888 y <- increment - 889 loop - 890 } - 891 } - 892 - 893 fn render4-cell screen: (addr screen), x: int, y: int, color: int { - 894 var xmin/eax: int <- copy x - 895 xmin <- shift-left 2 - 896 var xmax/ecx: int <- copy xmin - 897 xmax <- add 4 - 898 var ymin/edx: int <- copy y - 899 ymin <- shift-left 2 - 900 var ymax/ebx: int <- copy ymin - 901 ymax <- add 4 - 902 draw-rect screen, xmin ymin, xmax ymax, color - 903 } - 904 - 905 fn step4 _self: (addr environment) { - 906 var self/esi: (addr environment) <- copy _self - 907 var y/ecx: int <- copy 0 - 908 { - 909 compare y, 0xc0/height - 910 break-if->= - 911 var x/edx: int <- copy 0 - 912 { - 913 compare x, 0x100/width - 914 break-if->= - 915 var n/eax: int <- num-live-neighbors self, x, y - 916 # if neighbors < 2, die of loneliness - 917 { - 918 compare n, 2 - 919 break-if->= - 920 set self, x, y, 0/dead - 921 } - 922 # if neighbors > 3, die of overcrowding - 923 { - 924 compare n, 3 - 925 break-if-<= - 926 set self, x, y, 0/dead - 927 } - 928 # if neighbors = 2, preserve state - 929 { - 930 compare n, 2 - 931 break-if-!= - 932 var old-state/eax: boolean <- state self, x, y - 933 set self, x, y, old-state - 934 } - 935 # if neighbors = 3, cell quickens to life - 936 { - 937 compare n, 3 - 938 break-if-!= - 939 set self, x, y, 1/live - 940 } - 941 x <- increment - 942 loop - 943 } - 944 y <- increment - 945 loop - 946 } - 947 flush self - 948 } - 949 - 950 fn num-live-neighbors _self: (addr environment), x: int, y: int -> _/eax: int { - 951 var self/esi: (addr environment) <- copy _self - 952 var result/edi: int <- copy 0 - 953 # row above: zig - 954 decrement y - 955 decrement x - 956 var s/eax: boolean <- state self, x, y - 957 { - 958 compare s, 0/false - 959 break-if-= - 960 result <- increment - 961 } - 962 increment x - 963 s <- state self, x, y - 964 { - 965 compare s, 0/false - 966 break-if-= - 967 result <- increment - 968 } - 969 increment x - 970 s <- state self, x, y - 971 { - 972 compare s, 0/false - 973 break-if-= - 974 result <- increment - 975 } - 976 # curr row: zag - 977 increment y - 978 s <- state self, x, y - 979 { - 980 compare s, 0/false - 981 break-if-= - 982 result <- increment - 983 } - 984 subtract-from x, 2 - 985 s <- state self, x, y - 986 { - 987 compare s, 0/false - 988 break-if-= - 989 result <- increment - 990 } - 991 # row below: zig - 992 increment y - 993 s <- state self, x, y - 994 { - 995 compare s, 0/false - 996 break-if-= - 997 result <- increment - 998 } - 999 increment x -1000 s <- state self, x, y -1001 { -1002 compare s, 0/false -1003 break-if-= -1004 result <- increment -1005 } -1006 increment x -1007 s <- state self, x, y -1008 { -1009 compare s, 0/false -1010 break-if-= -1011 result <- increment -1012 } -1013 return result -1014 } -1015 -1016 fn linger _self: (addr environment) { -1017 var self/esi: (addr environment) <- copy _self -1018 var i/ecx: int <- copy 0 -1019 { -1020 compare i, 0x10000000 # Kartik's Linux with -enable-kvm -1021 #? compare i, 0x8000000 # Kartik's Mac with -accel tcg -1022 break-if->= -1023 i <- increment -1024 loop -1025 } -1026 } + 316 var n/eax: int <- num-live-neighbors self, 0x81/curx, 0x61/cury + 317 set-cursor-position screen, 0x52, 0x20 + 318 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, n, 0xf/fg 0/bg + 319 # cell 0: conveyors from neighboring inputs to sum node + 320 draw-monotonic-bezier screen, 0xc0/x0 0x40/y0, 0x100/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color + 321 draw-monotonic-bezier screen, 0xc0/x0 0xe8/y0, 0xc0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color + 322 draw-monotonic-bezier screen, 0xc0/x0 0x1a0/y0, 0xe0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 4/color + 323 draw-monotonic-bezier screen, 0x170/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 4/color + 324 draw-monotonic-bezier screen, 0x170/x0 0x1a0/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 4/color + 325 draw-monotonic-bezier screen, 0x220/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 4/color + 326 draw-monotonic-bezier screen, 0x220/x0 0xe8/y0, 0x220/x1 0xd0/y1, 0x150/xs 0xd0/ys, 4/color + 327 draw-monotonic-bezier screen, 0x220/x0 0x1a0/y0, 0x180/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 4/color + 328 # cell 0: conveyors from filter to outputs + 329 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x160/x1 0x8c/y1, 0x100/x2 0x80/y2, 0x2a/color + 330 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0xe8/y2, 0x2a/color + 331 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0x160/y2, 0x2a/color + 332 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x188/x1 0x80/y1, 0x170/x2 0x80/y2, 0x2a/color + 333 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x188/x1 0x160/y1, 0x170/x2 0x160/y2, 0x2a/color + 334 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x80/y2, 0x2a/color + 335 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1 0x1e0/x2 0xe8/y2, 0x2a/color + 336 draw-monotonic-bezier screen, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x160/y2, 0x2a/color + 337 # cell 0: time-variant portion: 16 repeating steps + 338 $render1:cell0: { + 339 var tick-a/eax: (addr int) <- get self, tick + 340 var progress/eax: int <- copy *tick-a + 341 progress <- and 0xf + 342 # cell 0: 7 time steps for getting inputs to sum + 343 { + 344 compare progress, 7 + 345 break-if->= + 346 var u/xmm7: float <- convert progress + 347 var six/eax: int <- copy 6 + 348 var six-f/xmm0: float <- convert six + 349 u <- divide six-f + 350 # points on conveyors from neighboring cells + 351 draw-bezier-point screen, u, 0xc0/x0 0x40/y0, 0x100/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius + 352 draw-bezier-point screen, u, 0xc0/x0 0xe8/y0, 0xc0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius + 353 draw-bezier-point screen, u, 0xc0/x0 0x1a0/y0, 0xe0/x1 0xd0/ys, 0x150/xs 0xd0/ys, 7/color, 4/radius + 354 draw-bezier-point screen, u, 0x170/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius + 355 draw-bezier-point screen, u, 0x170/x0 0x1a0/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius + 356 draw-bezier-point screen, u, 0x220/x0 0x40/y0, 0x150/x1 0x80/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius + 357 draw-bezier-point screen, u, 0x220/x0 0xe8/y0, 0x220/x1 0xd0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius + 358 draw-bezier-point screen, u, 0x220/x0 0x1a0/y0, 0x180/x1 0x1a0/y1, 0x150/xs 0xd0/ys, 7/color, 4/radius + 359 break $render1:cell0 + 360 } + 361 # cell 0: two time steps for getting count to filter + 362 progress <- subtract 7 + 363 { + 364 compare progress, 2 + 365 break-if->= + 366 break $render1:cell0 + 367 } + 368 # cell 0: final 7 time steps for updating output + 369 progress <- subtract 2 + 370 # cell 0: points on conveyors to outputs + 371 var u/xmm7: float <- convert progress + 372 var six/eax: int <- copy 6 + 373 var six-f/xmm0: float <- convert six + 374 u <- divide six-f + 375 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x160/x1 0x8c/y1, 0x100/x2 0x80/y2, 7/color, 4/radius + 376 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0xe8/y2, 7/color, 4/radius + 377 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x100/x1 0x100/y1, 0x100/x2 0x160/y2, 7/color, 4/radius + 378 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x188/xf 0x80/y1, 0x170/x2 0x80/y2, 7/color, 4/radius + 379 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x188/xf 0x160/y1, 0x170/x2 0x160/y2, 7/color, 4/radius + 380 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x80/y2, 7/color, 4/radius + 381 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0xe8/y2, 7/color, 4/radius + 382 draw-bezier-point screen, u, 0x188/xf 0x100/yf, 0x1e0/x1 0x100/y1, 0x1e0/x2 0x160/y2, 7/color, 4/radius + 383 } + 384 # cell 1: conveyors from neighboring inputs to sum node + 385 draw-monotonic-bezier screen, 0x1e0/x0 0x40/y0, 0x220/x1 0xd0/ys, 0x270/xs 0xd0/ys, 4/color + 386 draw-monotonic-bezier screen, 0x1e0/x0 0xe8/y0, 0x1e0/x1 0xd0/ys, 0x270/xs 0xd0/ys, 4/color + 387 draw-monotonic-bezier screen, 0x1e0/x0 0x1a0/y0, 0x200/x1 0xd0/ys, 0x270/xs 0xd0/ys, 4/color + 388 draw-monotonic-bezier screen, 0x290/x0 0x40/y0, 0x270/x1 0x80/y1, 0x270/xs 0xd0/ys, 4/color + 389 draw-monotonic-bezier screen, 0x290/x0 0x1a0/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0xd0/ys, 4/color + 390 draw-monotonic-bezier screen, 0x340/x0 0x40/y0, 0x270/x1 0x80/y1, 0x270/xs 0xd0/ys, 4/color + 391 draw-monotonic-bezier screen, 0x340/x0 0xe8/y0, 0x340/x1 0xd0/y1, 0x270/xs 0xd0/ys, 4/color + 392 draw-monotonic-bezier screen, 0x340/x0 0x1a0/y0, 0x2a0/x1 0x1a0/y1, 0x270/xs 0xd0/ys, 4/color + 393 # cell 1: conveyors from filter to outputs + 394 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x280/x1 0x8c/y1, 0x220/x2 0x80/y2, 0x2a/color + 395 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x220/x1 0x100/y1, 0x220/x2 0xe8/y2, 0x2a/color + 396 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x220/x1 0x100/y1, 0x220/x2 0x160/y2, 0x2a/color + 397 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x2a8/x1 0x80/y1, 0x290/x2 0x80/y2, 0x2a/color + 398 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x2a8/x1 0x160/y1, 0x290/x2 0x160/y2, 0x2a/color + 399 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0x80/y2, 0x2a/color + 400 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1 0x300/x2 0xe8/y2, 0x2a/color + 401 draw-monotonic-bezier screen, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0x160/y2, 0x2a/color + 402 # cell 1: time-variant portion: 16 repeating steps + 403 $render1:cell1: { + 404 var tick-a/eax: (addr int) <- get self, tick + 405 var progress/eax: int <- copy *tick-a + 406 progress <- and 0xf + 407 # cell 1: 7 time steps for getting inputs to sum + 408 { + 409 compare progress, 7 + 410 break-if->= + 411 var u/xmm7: float <- convert progress + 412 var six/eax: int <- copy 6 + 413 var six-f/xmm0: float <- convert six + 414 u <- divide six-f + 415 # points on conveyors from neighboring cells + 416 draw-bezier-point screen, u, 0x1e0/x0 0x40/y0, 0x220/x1 0xd0/ys, 0x270/xs 0xd0/ys, 7/color, 4/radius + 417 draw-bezier-point screen, u, 0x1e0/x0 0xe8/y0, 0x1e0/x1 0xd0/ys, 0x270/xs 0xd0/ys, 7/color, 4/radius + 418 draw-bezier-point screen, u, 0x1e0/x0 0x1a0/y0, 0x200/x1 0xd0/ys, 0x270/xs 0xd0/ys, 7/color, 4/radius + 419 draw-bezier-point screen, u, 0x290/x0 0x40/y0, 0x270/x1 0x80/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius + 420 draw-bezier-point screen, u, 0x290/x0 0x1a0/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius + 421 draw-bezier-point screen, u, 0x340/x0 0x40/y0, 0x270/x1 0x80/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius + 422 draw-bezier-point screen, u, 0x340/x0 0xe8/y0, 0x340/x1 0xd0/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius + 423 draw-bezier-point screen, u, 0x340/x0 0x1a0/y0, 0x2a0/x1 0x1a0/y1, 0x270/xs 0xd0/ys, 7/color, 4/radius + 424 break $render1:cell1 + 425 } + 426 # cell 1: two time steps for getting count to filter + 427 progress <- subtract 7 + 428 { + 429 compare progress, 2 + 430 break-if->= + 431 break $render1:cell1 + 432 } + 433 # cell 1: final 7 time steps for updating output + 434 progress <- subtract 2 + 435 # cell 1: points on conveyors to outputs + 436 var u/xmm7: float <- convert progress + 437 var six/eax: int <- copy 6 + 438 var six-f/xmm0: float <- convert six + 439 u <- divide six-f + 440 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x280/x1 0x8c/y1, 0x220/x2 0x80/y2, 7/color, 4/radius + 441 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x220/x1 0x100/y1, 0x220/x2 0xe8/y2, 7/color, 4/radius + 442 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x220/x1 0x100/y1, 0x220/x2 0x160/y2, 7/color, 4/radius + 443 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x2a8/xf 0x80/y1, 0x290/x2 0x80/y2, 7/color, 4/radius + 444 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x2a8/xf 0x160/y1, 0x290/x2 0x160/y2, 7/color, 4/radius + 445 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0x80/y2, 7/color, 4/radius + 446 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0xe8/y2, 7/color, 4/radius + 447 draw-bezier-point screen, u, 0x2a8/xf 0x100/yf, 0x300/x1 0x100/y1, 0x300/x2 0x160/y2, 7/color, 4/radius + 448 } + 449 # cell 2: conveyors from neighboring inputs to sum node + 450 draw-monotonic-bezier screen, 0xc0/x0 0x160/y0, 0x100/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 4/color + 451 draw-monotonic-bezier screen, 0xc0/x0 0x208/y0, 0xc0/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 4/color + 452 draw-monotonic-bezier screen, 0xc0/x0 0x2c0/y0, 0xe0/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 4/color + 453 draw-monotonic-bezier screen, 0x170/x0 0x160/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0x1f0/ys, 4/color + 454 draw-monotonic-bezier screen, 0x170/x0 0x2c0/y0, 0x150/x1 0x2c0/y1, 0x150/xs 0x1f0/ys, 4/color + 455 draw-monotonic-bezier screen, 0x220/x0 0x160/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0x1f0/ys, 4/color + 456 draw-monotonic-bezier screen, 0x220/x0 0x208/y0, 0x220/x1 0x1f0/y1, 0x150/xs 0x1f0/ys, 4/color + 457 draw-monotonic-bezier screen, 0x220/x0 0x2c0/y0, 0x180/x1 0x2c0/y1, 0x150/xs 0x1f0/ys, 4/color + 458 # cell 2: conveyors from filter to outputs + 459 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x160/x1 0x1ac/y1, 0x100/x2 0x1a0/y2, 0x2a/color + 460 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x100/x1 0x220/y1, 0x100/x2 0x208/y2, 0x2a/color + 461 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x100/x1 0x220/y1, 0x100/x2 0x280/y2, 0x2a/color + 462 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x188/x1 0x1a0/y1, 0x170/x2 0x1a0/y2, 0x2a/color + 463 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x188/x1 0x280/y1, 0x170/x2 0x280/y2, 0x2a/color + 464 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x1a0/y2, 0x2a/color + 465 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1 0x1e0/x2 0x208/y2, 0x2a/color + 466 draw-monotonic-bezier screen, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x280/y2, 0x2a/color + 467 # cell 2: time-variant portion: 16 repeating steps + 468 $render1:cell2: { + 469 var tick-a/eax: (addr int) <- get self, tick + 470 var progress/eax: int <- copy *tick-a + 471 progress <- and 0xf + 472 # cell 2: 7 time steps for getting inputs to sum + 473 { + 474 compare progress, 7 + 475 break-if->= + 476 var u/xmm7: float <- convert progress + 477 var six/eax: int <- copy 6 + 478 var six-f/xmm0: float <- convert six + 479 u <- divide six-f + 480 # points on conveyors from neighboring cells + 481 draw-bezier-point screen, u, 0xc0/x0 0x160/y0, 0x100/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 7/color, 4/radius + 482 draw-bezier-point screen, u, 0xc0/x0 0x208/y0, 0xc0/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 7/color, 4/radius + 483 draw-bezier-point screen, u, 0xc0/x0 0x2c0/y0, 0xe0/x1 0x1f0/ys, 0x150/xs 0x1f0/ys, 7/color, 4/radius + 484 draw-bezier-point screen, u, 0x170/x0 0x160/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius + 485 draw-bezier-point screen, u, 0x170/x0 0x2c0/y0, 0x150/x1 0x2c0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius + 486 draw-bezier-point screen, u, 0x220/x0 0x160/y0, 0x150/x1 0x1a0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius + 487 draw-bezier-point screen, u, 0x220/x0 0x208/y0, 0x220/x1 0x1f0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius + 488 draw-bezier-point screen, u, 0x220/x0 0x2c0/y0, 0x180/x1 0x2c0/y1, 0x150/xs 0x1f0/ys, 7/color, 4/radius + 489 break $render1:cell2 + 490 } + 491 # cell 2: two time steps for getting count to filter + 492 progress <- subtract 7 + 493 { + 494 compare progress, 2 + 495 break-if->= + 496 break $render1:cell2 + 497 } + 498 # cell 2: final 7 time steps for updating output + 499 progress <- subtract 2 + 500 # cell 2: points on conveyors to outputs + 501 var u/xmm7: float <- convert progress + 502 var six/eax: int <- copy 6 + 503 var six-f/xmm0: float <- convert six + 504 u <- divide six-f + 505 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x160/x1 0x1ac/y1, 0x100/x2 0x1a0/y2, 7/color, 4/radius + 506 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x100/x1 0x220/y1, 0x100/x2 0x208/y2, 7/color, 4/radius + 507 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x100/x1 0x220/y1, 0x100/x2 0x280/y2, 7/color, 4/radius + 508 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x188/xf 0x1a0/y1, 0x170/x2 0x1a0/y2, 7/color, 4/radius + 509 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x188/xf 0x280/y1, 0x170/x2 0x280/y2, 7/color, 4/radius + 510 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x1a0/y2, 7/color, 4/radius + 511 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x208/y2, 7/color, 4/radius + 512 draw-bezier-point screen, u, 0x188/xf 0x220/yf, 0x1e0/x1 0x220/y1, 0x1e0/x2 0x280/y2, 7/color, 4/radius + 513 } + 514 # cell 3: conveyors from neighboring inputs to sum node + 515 draw-monotonic-bezier screen, 0x1e0/x0 0x160/y0, 0x220/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 4/color + 516 draw-monotonic-bezier screen, 0x1e0/x0 0x208/y0, 0x1e0/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 4/color + 517 draw-monotonic-bezier screen, 0x1e0/x0 0x2c0/y0, 0x200/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 4/color + 518 draw-monotonic-bezier screen, 0x290/x0 0x160/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0x1f0/ys, 4/color + 519 draw-monotonic-bezier screen, 0x290/x0 0x2c0/y0, 0x270/x1 0x2c0/y1, 0x270/xs 0x1f0/ys, 4/color + 520 draw-monotonic-bezier screen, 0x340/x0 0x160/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0x1f0/ys, 4/color + 521 draw-monotonic-bezier screen, 0x340/x0 0x208/y0, 0x340/x1 0x1f0/y1, 0x270/xs 0x1f0/ys, 4/color + 522 draw-monotonic-bezier screen, 0x340/x0 0x2c0/y0, 0x2a0/x1 0x2c0/y1, 0x270/xs 0x1f0/ys, 4/color + 523 # cell 3: conveyors from filter to outputs + 524 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x280/x1 0x1ac/y1, 0x220/x2 0x1a0/y2, 0x2a/color + 525 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x220/x1 0x220/y1, 0x220/x2 0x208/y2, 0x2a/color + 526 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x220/x1 0x220/y1, 0x220/x2 0x280/y2, 0x2a/color + 527 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x2a8/x1 0x1a0/y1, 0x290/x2 0x1a0/y2, 0x2a/color + 528 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x2a8/x1 0x280/y1, 0x290/x2 0x280/y2, 0x2a/color + 529 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x1a0/y2, 0x2a/color + 530 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1 0x300/x2 0x208/y2, 0x2a/color + 531 draw-monotonic-bezier screen, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x280/y2, 0x2a/color + 532 # cell 3: time-variant portion: 16 repeating steps + 533 $render1:cell3: { + 534 var tick-a/eax: (addr int) <- get self, tick + 535 var progress/eax: int <- copy *tick-a + 536 progress <- and 0xf + 537 # cell 3: 7 time steps for getting inputs to sum + 538 { + 539 compare progress, 7 + 540 break-if->= + 541 var u/xmm7: float <- convert progress + 542 var six/eax: int <- copy 6 + 543 var six-f/xmm0: float <- convert six + 544 u <- divide six-f + 545 # points on conveyors from neighboring cells + 546 draw-bezier-point screen, u, 0x1e0/x0 0x160/y0, 0x220/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 7/color, 4/radius + 547 draw-bezier-point screen, u, 0x1e0/x0 0x208/y0, 0x1e0/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 7/color, 4/radius + 548 draw-bezier-point screen, u, 0x1e0/x0 0x2c0/y0, 0x200/x1 0x1f0/ys, 0x270/xs 0x1f0/ys, 7/color, 4/radius + 549 draw-bezier-point screen, u, 0x290/x0 0x160/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius + 550 draw-bezier-point screen, u, 0x290/x0 0x2c0/y0, 0x270/x1 0x2c0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius + 551 draw-bezier-point screen, u, 0x340/x0 0x160/y0, 0x270/x1 0x1a0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius + 552 draw-bezier-point screen, u, 0x340/x0 0x208/y0, 0x340/x1 0x1f0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius + 553 draw-bezier-point screen, u, 0x340/x0 0x2c0/y0, 0x2a0/x1 0x2c0/y1, 0x270/xs 0x1f0/ys, 7/color, 4/radius + 554 break $render1:cell3 + 555 } + 556 # cell 3: two time steps for getting count to filter + 557 progress <- subtract 7 + 558 { + 559 compare progress, 2 + 560 break-if->= + 561 break $render1:cell3 + 562 } + 563 # cell 3: final 7 time steps for updating output + 564 progress <- subtract 2 + 565 # cell 3: points on conveyors to outputs + 566 var u/xmm7: float <- convert progress + 567 var six/eax: int <- copy 6 + 568 var six-f/xmm0: float <- convert six + 569 u <- divide six-f + 570 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x280/x1 0x1ac/y1, 0x220/x2 0x1a0/y2, 7/color, 4/radius + 571 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x220/x1 0x220/y1, 0x220/x2 0x208/y2, 7/color, 4/radius + 572 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x220/x1 0x220/y1, 0x220/x2 0x280/y2, 7/color, 4/radius + 573 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x2a8/xf 0x1a0/y1, 0x290/x2 0x1a0/y2, 7/color, 4/radius + 574 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x2a8/xf 0x280/y1, 0x290/x2 0x280/y2, 7/color, 4/radius + 575 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x1a0/y2, 7/color, 4/radius + 576 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x208/y2, 7/color, 4/radius + 577 draw-bezier-point screen, u, 0x2a8/xf 0x220/yf, 0x300/x1 0x220/y1, 0x300/x2 0x280/y2, 7/color, 4/radius + 578 } + 579 } + 580 + 581 fn draw-bezier-point screen: (addr screen), u: float, x0: int, y0: int, x1: int, y1: int, x2: int, y2: int, color: int, radius: int { + 582 var _cy/eax: int <- bezier-point u, y0, y1, y2 + 583 var cy/ecx: int <- copy _cy + 584 var cx/eax: int <- bezier-point u, x0, x1, x2 + 585 draw-disc screen, cx, cy, radius, color, 0xf/border-color=white + 586 } + 587 + 588 fn draw-linear-point screen: (addr screen), u: float, x0: int, y0: int, x1: int, y1: int, color: int, radius: int { + 589 var _cy/eax: int <- line-point u, y0, y1 + 590 var cy/ecx: int <- copy _cy + 591 var cx/eax: int <- line-point u, x0, x1 + 592 draw-disc screen, cx, cy, radius, color, 0xf/border-color=white + 593 } + 594 + 595 fn edit keyboard: (addr keyboard), _self: (addr environment) { + 596 var self/esi: (addr environment) <- copy _self + 597 var key/eax: byte <- read-key keyboard + 598 # space: play/pause + 599 { + 600 compare key, 0x20/space + 601 break-if-!= + 602 var play?/eax: (addr boolean) <- get self, play? + 603 compare *play?, 0/false + 604 { + 605 break-if-= + 606 copy-to *play?, 0/false + 607 return + 608 } + 609 copy-to *play?, 1/true + 610 return + 611 } + 612 # 0: back to start + 613 { + 614 compare key, 0x30/0 + 615 break-if-!= + 616 clear-environment self + 617 return + 618 } + 619 # l: loop from here to start + 620 { + 621 compare key, 0x6c/l + 622 break-if-!= + 623 var tick-a/eax: (addr int) <- get self, tick + 624 var tick/eax: int <- copy *tick-a + 625 var loop/ecx: (addr int) <- get self, loop + 626 copy-to *loop, tick + 627 return + 628 } + 629 # L: reset loop + 630 { + 631 compare key, 0x4c/L + 632 break-if-!= + 633 var loop/eax: (addr int) <- get self, loop + 634 copy-to *loop, 0 + 635 return + 636 } + 637 # -: zoom out + 638 { + 639 compare key, 0x2d/- + 640 break-if-!= + 641 var zoom/eax: (addr int) <- get self, zoom + 642 compare *zoom, 1 + 643 { + 644 break-if-!= + 645 copy-to *zoom, 4 + 646 } + 647 compare *zoom, 0 + 648 { + 649 break-if-!= + 650 copy-to *zoom, 1 + 651 } + 652 # set tick to a multiple of zoom + 653 var tick-a/edx: (addr int) <- get self, tick + 654 clear-lowest-bits tick-a, *zoom + 655 return + 656 } + 657 # +: zoom in + 658 { + 659 compare key, 0x2b/+ + 660 break-if-!= + 661 var zoom/eax: (addr int) <- get self, zoom + 662 compare *zoom, 1 + 663 { + 664 break-if-!= + 665 copy-to *zoom, 0 + 666 } + 667 compare *zoom, 4 + 668 { + 669 break-if-!= + 670 copy-to *zoom, 1 + 671 } + 672 # set tick to a multiple of zoom + 673 var tick-a/edx: (addr int) <- get self, tick + 674 clear-lowest-bits tick-a, *zoom + 675 return + 676 } + 677 } + 678 + 679 fn step _self: (addr environment) { + 680 var self/esi: (addr environment) <- copy _self + 681 var tick-a/ecx: (addr int) <- get self, tick + 682 var zoom/edx: (addr int) <- get self, zoom + 683 compare *zoom, 0 + 684 { + 685 break-if-!= + 686 increment *tick-a + 687 } + 688 compare *zoom, 1 + 689 { + 690 break-if-!= + 691 # I wanted to speed up time, but that doesn't seem very usable. + 692 #? add-to *tick-a, 2 + 693 increment *tick-a + 694 } + 695 compare *zoom, 4 + 696 { + 697 break-if-!= + 698 add-to *tick-a, 0x10 + 699 } + 700 var tick/eax: int <- copy *tick-a + 701 tick <- and 0xf + 702 compare tick, 0 + 703 { + 704 break-if-!= + 705 step4 self + 706 } + 707 var loop-a/eax: (addr int) <- get self, loop + 708 compare *loop-a, 0 + 709 { + 710 break-if-= + 711 var loop/eax: int <- copy *loop-a + 712 compare *tick-a, loop + 713 break-if-< + 714 clear-environment self + 715 } + 716 } + 717 + 718 fn initialize-environment _self: (addr environment) { + 719 var self/esi: (addr environment) <- copy _self + 720 var zoom/eax: (addr int) <- get self, zoom + 721 copy-to *zoom, 0 + 722 var play?/eax: (addr boolean) <- get self, play? + 723 copy-to *play?, 1/true + 724 var data-ah/eax: (addr handle array handle array cell) <- get self, data + 725 populate data-ah, 0x100 + 726 var data/eax: (addr array handle array cell) <- lookup *data-ah + 727 var y/ecx: int <- copy 0 + 728 { + 729 compare y, 0xc0 + 730 break-if->= + 731 var dest-ah/eax: (addr handle array cell) <- index data, y + 732 populate dest-ah, 0x100 + 733 y <- increment + 734 loop + 735 } + 736 set self, 0x80, 0x5f, 1/alive + 737 set self, 0x81, 0x5f, 1/alive + 738 set self, 0x7f, 0x60, 1/alive + 739 set self, 0x80, 0x60, 1/alive + 740 set self, 0x80, 0x61, 1/alive + 741 flush self + 742 } + 743 + 744 fn clear-environment _self: (addr environment) { + 745 var self/esi: (addr environment) <- copy _self + 746 var tick/eax: (addr int) <- get self, tick + 747 copy-to *tick, 0 + 748 # don't touch zoom or play settings + 749 var data-ah/eax: (addr handle array handle array cell) <- get self, data + 750 var data/eax: (addr array handle array cell) <- lookup *data-ah + 751 var y/ecx: int <- copy 0 + 752 { + 753 compare y, 0xc0 + 754 break-if->= + 755 var row-ah/eax: (addr handle array cell) <- index data, y + 756 var row/eax: (addr array cell) <- lookup *row-ah + 757 var x/edx: int <- copy 0 + 758 { + 759 compare x, 0x100 + 760 break-if->= + 761 var dest/eax: (addr cell) <- index row, x + 762 clear-object dest + 763 x <- increment + 764 loop + 765 } + 766 y <- increment + 767 loop + 768 } + 769 set self, 0x80, 0x5f, 1/alive + 770 set self, 0x81, 0x5f, 1/alive + 771 set self, 0x7f, 0x60, 1/alive + 772 set self, 0x80, 0x60, 1/alive + 773 set self, 0x80, 0x61, 1/alive + 774 flush self + 775 } + 776 + 777 fn set _self: (addr environment), _x: int, _y: int, _val: boolean { + 778 var self/esi: (addr environment) <- copy _self + 779 var data-ah/eax: (addr handle array handle array cell) <- get self, data + 780 var data/eax: (addr array handle array cell) <- lookup *data-ah + 781 var y/ecx: int <- copy _y + 782 var row-ah/eax: (addr handle array cell) <- index data, y + 783 var row/eax: (addr array cell) <- lookup *row-ah + 784 var x/ecx: int <- copy _x + 785 var cell/eax: (addr cell) <- index row, x + 786 var dest/eax: (addr boolean) <- get cell, next + 787 var val/ecx: boolean <- copy _val + 788 copy-to *dest, val + 789 } + 790 + 791 fn state _self: (addr environment), _x: int, _y: int -> _/eax: boolean { + 792 var self/esi: (addr environment) <- copy _self + 793 var x/ecx: int <- copy _x + 794 var y/edx: int <- copy _y + 795 # clip at the edge + 796 compare x, 0 + 797 { + 798 break-if->= + 799 return 0/false + 800 } + 801 compare y, 0 + 802 { + 803 break-if->= + 804 return 0/false + 805 } + 806 compare x, 0x100/width + 807 { + 808 break-if-< + 809 return 0/false + 810 } + 811 compare y, 0xc0/height + 812 { + 813 break-if-< + 814 return 0/false + 815 } + 816 var data-ah/eax: (addr handle array handle array cell) <- get self, data + 817 var data/eax: (addr array handle array cell) <- lookup *data-ah + 818 var row-ah/eax: (addr handle array cell) <- index data, y + 819 var row/eax: (addr array cell) <- lookup *row-ah + 820 var cell/eax: (addr cell) <- index row, x + 821 var src/eax: (addr boolean) <- get cell, curr + 822 return *src + 823 } + 824 + 825 fn state-color _self: (addr environment), x: int, y: int -> _/eax: int { + 826 var self/esi: (addr environment) <- copy _self + 827 var color/ecx: int <- copy 0x1a/dead + 828 { + 829 var state/eax: boolean <- state self, x, y + 830 compare state, 0/dead + 831 break-if-= + 832 color <- copy 0xf/alive + 833 } + 834 return color + 835 } + 836 + 837 fn flush _self: (addr environment) { + 838 var self/esi: (addr environment) <- copy _self + 839 var data-ah/eax: (addr handle array handle array cell) <- get self, data + 840 var _data/eax: (addr array handle array cell) <- lookup *data-ah + 841 var data/esi: (addr array handle array cell) <- copy _data + 842 var y/ecx: int <- copy 0 + 843 { + 844 compare y, 0xc0/height + 845 break-if->= + 846 var row-ah/eax: (addr handle array cell) <- index data, y + 847 var _row/eax: (addr array cell) <- lookup *row-ah + 848 var row/ebx: (addr array cell) <- copy _row + 849 var x/edx: int <- copy 0 + 850 { + 851 compare x, 0x100/width + 852 break-if->= + 853 var cell-a/eax: (addr cell) <- index row, x + 854 var curr-a/edi: (addr boolean) <- get cell-a, curr + 855 var next-a/esi: (addr boolean) <- get cell-a, next + 856 var val/eax: boolean <- copy *next-a + 857 copy-to *curr-a, val + 858 copy-to *next-a, 0/dead + 859 x <- increment + 860 loop + 861 } + 862 y <- increment + 863 loop + 864 } + 865 } + 866 + 867 fn render4 screen: (addr screen), _self: (addr environment) { + 868 var self/esi: (addr environment) <- copy _self + 869 var y/ecx: int <- copy 0 + 870 { + 871 compare y, 0xc0/height + 872 break-if->= + 873 var x/edx: int <- copy 0 + 874 { + 875 compare x, 0x100/width + 876 break-if->= + 877 var state/eax: boolean <- state self, x, y + 878 compare state, 0/false + 879 { + 880 break-if-= + 881 render4-cell screen, x, y, 0xf/alive + 882 } + 883 compare state, 0/false + 884 { + 885 break-if-!= + 886 render4-cell screen, x, y, 0x1a/dead + 887 } + 888 x <- increment + 889 loop + 890 } + 891 y <- increment + 892 loop + 893 } + 894 } + 895 + 896 fn render4-cell screen: (addr screen), x: int, y: int, color: int { + 897 var xmin/eax: int <- copy x + 898 xmin <- shift-left 2 + 899 var xmax/ecx: int <- copy xmin + 900 xmax <- add 4 + 901 var ymin/edx: int <- copy y + 902 ymin <- shift-left 2 + 903 var ymax/ebx: int <- copy ymin + 904 ymax <- add 4 + 905 draw-rect screen, xmin ymin, xmax ymax, color + 906 } + 907 + 908 fn step4 _self: (addr environment) { + 909 var self/esi: (addr environment) <- copy _self + 910 var y/ecx: int <- copy 0 + 911 { + 912 compare y, 0xc0/height + 913 break-if->= + 914 var x/edx: int <- copy 0 + 915 { + 916 compare x, 0x100/width + 917 break-if->= + 918 var n/eax: int <- num-live-neighbors self, x, y + 919 # if neighbors < 2, die of loneliness + 920 { + 921 compare n, 2 + 922 break-if->= + 923 set self, x, y, 0/dead + 924 } + 925 # if neighbors > 3, die of overcrowding + 926 { + 927 compare n, 3 + 928 break-if-<= + 929 set self, x, y, 0/dead + 930 } + 931 # if neighbors = 2, preserve state + 932 { + 933 compare n, 2 + 934 break-if-!= + 935 var old-state/eax: boolean <- state self, x, y + 936 set self, x, y, old-state + 937 } + 938 # if neighbors = 3, cell quickens to life + 939 { + 940 compare n, 3 + 941 break-if-!= + 942 set self, x, y, 1/live + 943 } + 944 x <- increment + 945 loop + 946 } + 947 y <- increment + 948 loop + 949 } + 950 flush self + 951 } + 952 + 953 fn num-live-neighbors _self: (addr environment), x: int, y: int -> _/eax: int { + 954 var self/esi: (addr environment) <- copy _self + 955 var result/edi: int <- copy 0 + 956 # row above: zig + 957 decrement y + 958 decrement x + 959 var s/eax: boolean <- state self, x, y + 960 { + 961 compare s, 0/false + 962 break-if-= + 963 result <- increment + 964 } + 965 increment x + 966 s <- state self, x, y + 967 { + 968 compare s, 0/false + 969 break-if-= + 970 result <- increment + 971 } + 972 increment x + 973 s <- state self, x, y + 974 { + 975 compare s, 0/false + 976 break-if-= + 977 result <- increment + 978 } + 979 # curr row: zag + 980 increment y + 981 s <- state self, x, y + 982 { + 983 compare s, 0/false + 984 break-if-= + 985 result <- increment + 986 } + 987 subtract-from x, 2 + 988 s <- state self, x, y + 989 { + 990 compare s, 0/false + 991 break-if-= + 992 result <- increment + 993 } + 994 # row below: zig + 995 increment y + 996 s <- state self, x, y + 997 { + 998 compare s, 0/false + 999 break-if-= +1000 result <- increment +1001 } +1002 increment x +1003 s <- state self, x, y +1004 { +1005 compare s, 0/false +1006 break-if-= +1007 result <- increment +1008 } +1009 increment x +1010 s <- state self, x, y +1011 { +1012 compare s, 0/false +1013 break-if-= +1014 result <- increment +1015 } +1016 return result +1017 } +1018 +1019 fn linger _self: (addr environment) { +1020 var self/esi: (addr environment) <- copy _self +1021 var i/ecx: int <- copy 0 +1022 { +1023 compare i, 0x10000000 # Kartik's Linux with -enable-kvm +1024 #? compare i, 0x8000000 # Kartik's Mac with -accel tcg +1025 break-if->= +1026 i <- increment +1027 loop +1028 } +1029 } diff --git a/html/life.mu.html b/html/life.mu.html index c2bf5faf..7b4494b7 100644 --- a/html/life.mu.html +++ b/html/life.mu.html @@ -14,14 +14,20 @@ pre { white-space: pre-wrap; font-family: monospace; color: #000000; background- body { font-size:12pt; font-family: monospace; color: #000000; background-color: #a8a8a8; } a { color:inherit; } * { font-size:12pt; font-size: 1em; } -.PreProc { color: #c000c0; } -.Special { color: #ff6060; } .LineNr { } .Delimiter { color: #c000c0; } .CommentedCode { color: #8a8a8a; } +.muRegEdx { color: #878700; } +.muRegEbx { color: #8787af; } +.muRegEsi { color: #87d787; } +.muRegEdi { color: #87ffd7; } .Constant { color: #008787; } +.Special { color: #ff6060; } +.PreProc { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } +.muRegEax { color: #875f00; } +.muRegEcx { color: #af875f; } --> @@ -64,7 +70,7 @@ if ('onhashchange' in window) { 5 # To run: 6 # $ qemu-system-i386 code.img 7 - 8 fn state _grid: (addr array boolean), x: int, y: int -> _/eax: boolean { + 8 fn state _grid: (addr array boolean), x: int, y: int -> _/eax: boolean { 9 # clip at the edge 10 compare x, 0 11 { @@ -86,31 +92,31 @@ if ('onhashchange' in window) { 27 break-if-< 28 return 0/false 29 } - 30 var idx/eax: int <- copy y + 30 var idx/eax: int <- copy y 31 idx <- shift-left 8/log2width 32 idx <- add x - 33 var grid/esi: (addr array boolean) <- copy _grid - 34 var result/eax: (addr boolean) <- index grid, idx + 33 var grid/esi: (addr array boolean) <- copy _grid + 34 var result/eax: (addr boolean) <- index grid, idx 35 return *result 36 } 37 38 fn set-state _grid: (addr array boolean), x: int, y: int, val: boolean { 39 # don't bother checking bounds - 40 var idx/eax: int <- copy y + 40 var idx/eax: int <- copy y 41 idx <- shift-left 8/log2width 42 idx <- add x - 43 var grid/esi: (addr array boolean) <- copy _grid - 44 var result/eax: (addr boolean) <- index grid, idx - 45 var src/ecx: boolean <- copy val + 43 var grid/esi: (addr array boolean) <- copy _grid + 44 var result/eax: (addr boolean) <- index grid, idx + 45 var src/ecx: boolean <- copy val 46 copy-to *result, src 47 } 48 - 49 fn num-live-neighbors grid: (addr array boolean), x: int, y: int -> _/eax: int { - 50 var result/edi: int <- copy 0 + 49 fn num-live-neighbors grid: (addr array boolean), x: int, y: int -> _/eax: int { + 50 var result/edi: int <- copy 0 51 # row above: zig 52 decrement y 53 decrement x - 54 var s/eax: boolean <- state grid, x, y + 54 var s/eax: boolean <- state grid, x, y 55 { 56 compare s, 0/false 57 break-if-= @@ -171,15 +177,15 @@ if ('onhashchange' in window) { 112 } 113 114 fn step old-grid: (addr array boolean), new-grid: (addr array boolean) { -115 var y/ecx: int <- copy 0 +115 var y/ecx: int <- copy 0 116 { 117 compare y, 0xc0/height 118 break-if->= -119 var x/edx: int <- copy 0 +119 var x/edx: int <- copy 0 120 { 121 compare x, 0x100/width 122 break-if->= -123 var n/eax: int <- num-live-neighbors old-grid, x, y +123 var n/eax: int <- num-live-neighbors old-grid, x, y 124 # if neighbors < 2, die of loneliness 125 { 126 compare n, 2 @@ -196,7 +202,7 @@ if ('onhashchange' in window) { 137 { 138 compare n, 2 139 break-if-!= -140 var old-state/eax: boolean <- state old-grid, x, y +140 var old-state/eax: boolean <- state old-grid, x, y 141 set-state new-grid, x, y, old-state 142 } 143 # if neighbors = 3, cell quickens to life @@ -215,19 +221,19 @@ if ('onhashchange' in window) { 156 157 # color a square of size 'side' starting at x*side, y*side 158 fn render-square _x: int, _y: int, color: int { -159 var y/edx: int <- copy _y +159 var y/edx: int <- copy _y 160 y <- shift-left 2/log2side -161 var side/ebx: int <- copy 1 +161 var side/ebx: int <- copy 1 162 side <- shift-left 2/log2side -163 var ymax/ecx: int <- copy y +163 var ymax/ecx: int <- copy y 164 ymax <- add side 165 { 166 compare y, ymax 167 break-if->= 168 { -169 var x/eax: int <- copy _x +169 var x/eax: int <- copy _x 170 x <- shift-left 2/log2side -171 var xmax/ecx: int <- copy x +171 var xmax/ecx: int <- copy x 172 xmax <- add side 173 { 174 compare x, xmax @@ -243,15 +249,15 @@ if ('onhashchange' in window) { 184 } 185 186 fn render grid: (addr array boolean) { -187 var y/ecx: int <- copy 0 +187 var y/ecx: int <- copy 0 188 { 189 compare y, 0xc0/height 190 break-if->= -191 var x/edx: int <- copy 0 +191 var x/edx: int <- copy 0 192 { 193 compare x, 0x100/width 194 break-if->= -195 var state/eax: boolean <- state grid, x, y +195 var state/eax: boolean <- state grid, x, y 196 compare state, 0/false 197 { 198 break-if-= @@ -278,15 +284,15 @@ if ('onhashchange' in window) { 219 #? var grid2/edi: (addr array boolean) <- address grid2-storage 220 # allocate on the heap 221 var grid1-storage: (handle array boolean) -222 var grid1-ah/eax: (addr handle array boolean) <- address grid1-storage +222 var grid1-ah/eax: (addr handle array boolean) <- address grid1-storage 223 populate grid1-ah, 0xc000 # width * height -224 var _grid1/eax: (addr array boolean) <- lookup *grid1-ah -225 var grid1/esi: (addr array boolean) <- copy _grid1 +224 var _grid1/eax: (addr array boolean) <- lookup *grid1-ah +225 var grid1/esi: (addr array boolean) <- copy _grid1 226 var grid2-storage: (handle array boolean) -227 var grid2-ah/eax: (addr handle array boolean) <- address grid2-storage +227 var grid2-ah/eax: (addr handle array boolean) <- address grid2-storage 228 populate grid2-ah, 0xc000 # width * height -229 var _grid2/eax: (addr array boolean) <- lookup *grid2-ah -230 var grid2/edi: (addr array boolean) <- copy _grid2 +229 var _grid2/eax: (addr array boolean) <- lookup *grid2-ah +230 var grid2/edi: (addr array boolean) <- copy _grid2 231 # initialize grid1 232 set-state grid1, 0x80, 0x5f, 1/live 233 set-state grid1, 0x81, 0x5f, 1/live @@ -296,7 +302,7 @@ if ('onhashchange' in window) { 237 # render grid1 238 render grid1 239 { -240 var key/eax: byte <- read-key keyboard +240 var key/eax: byte <- read-key keyboard 241 compare key, 0 242 #? loop-if-= # press key to step 243 break-if-!= # press key to quit # comment this out to run under bochs; I'm not sure why there's a newline in the keyboard buffer diff --git a/html/linux/mu.subx.html b/html/linux/mu.subx.html index e9b68096..419ceebe 100644 --- a/html/linux/mu.subx.html +++ b/html/linux/mu.subx.html @@ -561,7 +561,7 @@ if ('onhashchange' in window) { 499 } 500 # otherwise convert Stdin 501 (write-buffered Stdout "== code\n") - 502 (convert-mu Stdin Stdout Stderr 0) + 502 (convert-mu Stdin Stdout Stderr 0) 503 (flush Stdout) 504 # syscall(exit, 0) 505 bb/copy-to-ebx 0/imm32 @@ -575,9 +575,9 @@ if ('onhashchange' in window) { 513 # . save registers 514 50/push-eax 515 # initialize global data structures - 516 c7 0/subop/copy *Next-block-index 1/imm32 - 517 8b/-> *Primitive-type-ids 0/r32/eax - 518 89/<- *Type-id 0/r32/eax # stream-write + 516 c7 0/subop/copy *Next-block-index 1/imm32 + 517 8b/-> *Primitive-type-ids 0/r32/eax + 518 89/<- *Type-id 0/r32/eax # stream-write 519 c7 0/subop/copy *_Program-functions 0/imm32 520 c7 0/subop/copy *_Program-functions->payload 0/imm32 521 c7 0/subop/copy *_Program-types 0/imm32 @@ -585,11 +585,11 @@ if ('onhashchange' in window) { 523 c7 0/subop/copy *_Program-signatures 0/imm32 524 c7 0/subop/copy *_Program-signatures->payload 0/imm32 525 # - 526 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14)) - 527 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14)) + 526 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14)) + 527 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14)) 528 #? (dump-typeinfos "=== typeinfos\n") - 529 (check-mu-types *(ebp+0x10) *(ebp+0x14)) - 530 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) + 529 (check-mu-types *(ebp+0x10) *(ebp+0x14)) + 530 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) 531 $convert-mu:end: 532 # . restore registers 533 58/pop-to-eax @@ -609,7 +609,7 @@ if ('onhashchange' in window) { 547 (clear-stream _test-output-stream) 548 (clear-stream $_test-output-buffered-file->buffer) 549 # - 550 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 550 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 551 (flush _test-output-buffered-file) 552 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input") 553 # . epilogue @@ -630,18 +630,18 @@ if ('onhashchange' in window) { 568 (write _test-input-stream "fn foo {\n") 569 (write _test-input-stream "}\n") 570 # convert - 571 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 571 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 572 (flush _test-output-buffered-file) 573 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 579 # check output - 580 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0") + 580 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0") 581 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-skeleton/1") - 582 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2") - 583 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3") + 582 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2") + 583 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3") 584 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-skeleton/4") - 585 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5") - 586 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6") - 587 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7") + 585 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5") + 586 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6") + 587 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7") 588 # . epilogue 589 89/<- %esp 5/r32/ebp 590 5d/pop-to-ebp @@ -662,27 +662,27 @@ if ('onhashchange' in window) { 605 (write _test-input-stream "fn bar {\n") 606 (write _test-input-stream "}\n") 607 # convert - 608 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 608 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 609 (flush _test-output-buffered-file) 610 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 616 # check first function - 617 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0") + 617 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0") 618 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/1") - 619 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2") - 620 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3") + 619 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2") + 620 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3") 621 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/4") - 622 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5") - 623 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6") - 624 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7") + 622 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5") + 623 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6") + 624 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7") 625 # check second function - 626 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10") + 626 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10") 627 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/11") - 628 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12") - 629 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13") + 628 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12") + 629 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13") 630 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/14") - 631 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15") - 632 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16") - 633 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17") + 631 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15") + 632 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16") + 633 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17") 634 # . epilogue 635 89/<- %esp 5/r32/ebp 636 5d/pop-to-ebp @@ -701,18 +701,18 @@ if ('onhashchange' in window) { 649 (write _test-input-stream "fn foo n: int {\n") 650 (write _test-input-stream "}\n") 651 # convert - 652 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 652 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 653 (flush _test-output-buffered-file) 654 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 660 # check output - 661 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0") + 661 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0") 662 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg/1") - 663 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2") - 664 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3") + 663 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2") + 664 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3") 665 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg/4") - 666 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5") - 667 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6") - 668 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7") + 666 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5") + 667 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6") + 668 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7") 669 # . epilogue 670 89/<- %esp 5/r32/ebp 671 5d/pop-to-ebp @@ -740,7 +740,7 @@ if ('onhashchange' in window) { 693 (write _test-input-stream "fn foo {\n") 694 (write _test-input-stream "}\n") 695 # convert - 696 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 696 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 697 # registers except esp clobbered at this point 698 # restore ed 699 89/<- %edx 4/r32/esp @@ -748,10 +748,10 @@ if ('onhashchange' in window) { 701 (flush _test-error-buffered-file) 702 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 708 # check output - 709 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name: output should be empty") - 710 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name: error message") + 709 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name: output should be empty") + 710 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name: error message") 711 # check that stop(1) was called - 712 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name: exit status") + 712 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name: exit status") 713 # don't restore from ebp 714 81 0/subop/add %esp 8/imm32 715 # . epilogue @@ -779,7 +779,7 @@ if ('onhashchange' in window) { 737 (write _test-input-stream "}\n") 738 (write _test-input-stream "sig foo\n") 739 # convert - 740 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 740 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 741 # registers except esp clobbered at this point 742 # restore ed 743 89/<- %edx 4/r32/esp @@ -787,10 +787,10 @@ if ('onhashchange' in window) { 745 (flush _test-error-buffered-file) 746 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 752 # check output - 753 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name-2: output should be empty") - 754 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name-2: error message") + 753 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name-2: output should be empty") + 754 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name-2: error message") 755 # check that stop(1) was called - 756 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name-2: exit status") + 756 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name-2: exit status") 757 # don't restore from ebp 758 81 0/subop/add %esp 8/imm32 759 # . epilogue @@ -818,7 +818,7 @@ if ('onhashchange' in window) { 781 (write _test-input-stream "fn foo {\n") 782 (write _test-input-stream "}\n") 783 # convert - 784 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 784 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 785 # registers except esp clobbered at this point 786 # restore ed 787 89/<- %edx 4/r32/esp @@ -826,10 +826,10 @@ if ('onhashchange' in window) { 789 (flush _test-error-buffered-file) 790 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 796 # check output - 797 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name-3: output should be empty") - 798 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name-3: error message") + 797 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name-3: output should be empty") + 798 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name-3: error message") 799 # check that stop(1) was called - 800 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name-3: exit status") + 800 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name-3: exit status") 801 # don't restore from ebp 802 81 0/subop/add %esp 8/imm32 803 # . epilogue @@ -856,7 +856,7 @@ if ('onhashchange' in window) { 824 (write _test-input-stream "fn foo x/eax: int {\n") 825 (write _test-input-stream "}\n") 826 # convert - 827 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 827 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 828 # registers except esp clobbered at this point 829 # restore ed 830 89/<- %edx 4/r32/esp @@ -864,10 +864,10 @@ if ('onhashchange' in window) { 832 (flush _test-error-buffered-file) 833 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 839 # check output - 840 (check-stream-equal _test-output-stream "" "F - test-function-with-inout-in-register: output should be empty") - 841 (check-next-stream-line-equal _test-error-stream "fn foo: function inout 'x' cannot be in a register" "F - test-function-with-inout-in-register: error message") + 840 (check-stream-equal _test-output-stream "" "F - test-function-with-inout-in-register: output should be empty") + 841 (check-next-stream-line-equal _test-error-stream "fn foo: function inout 'x' cannot be in a register" "F - test-function-with-inout-in-register: error message") 842 # check that stop(1) was called - 843 (check-ints-equal *(edx+4) 2 "F - test-function-with-inout-in-register: exit status") + 843 (check-ints-equal *(edx+4) 2 "F - test-function-with-inout-in-register: exit status") 844 # don't restore from ebp 845 81 0/subop/add %esp 8/imm32 846 # . epilogue @@ -894,7 +894,7 @@ if ('onhashchange' in window) { 867 (write _test-input-stream "fn foo -> _/eax: (addr int) {\n") 868 (write _test-input-stream "}\n") 869 # convert - 870 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 870 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 871 # registers except esp clobbered at this point 872 # restore ed 873 89/<- %edx 4/r32/esp @@ -902,10 +902,10 @@ if ('onhashchange' in window) { 875 (flush _test-error-buffered-file) 876 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 882 # check output - 883 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-output: output should be empty") - 884 (check-next-stream-line-equal _test-error-stream "fn foo: output cannot have an addr type; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-output: error message") + 883 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-output: output should be empty") + 884 (check-next-stream-line-equal _test-error-stream "fn foo: output cannot have an addr type; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-output: error message") 885 # check that stop(1) was called - 886 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-output: exit status") + 886 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-output: exit status") 887 # don't restore from ebp 888 81 0/subop/add %esp 8/imm32 889 # . epilogue @@ -932,7 +932,7 @@ if ('onhashchange' in window) { 910 (write _test-input-stream "fn foo a: (addr addr int) {\n") 911 (write _test-input-stream "}\n") 912 # convert - 913 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 913 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 914 # registers except esp clobbered at this point 915 # restore ed 916 89/<- %edx 4/r32/esp @@ -940,10 +940,10 @@ if ('onhashchange' in window) { 918 (flush _test-error-buffered-file) 919 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 925 # check output - 926 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout: output should be empty") - 927 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout: error message") + 926 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout: output should be empty") + 927 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout: error message") 928 # check that stop(1) was called - 929 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout: exit status") + 929 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout: exit status") 930 # don't restore from ebp 931 81 0/subop/add %esp 8/imm32 932 # . epilogue @@ -970,7 +970,7 @@ if ('onhashchange' in window) { 953 (write _test-input-stream "fn foo a: (addr array addr int) {\n") 954 (write _test-input-stream "}\n") 955 # convert - 956 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 956 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 957 # registers except esp clobbered at this point 958 # restore ed 959 89/<- %edx 4/r32/esp @@ -978,10 +978,10 @@ if ('onhashchange' in window) { 961 (flush _test-error-buffered-file) 962 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 968 # check output - 969 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-2: output should be empty") - 970 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-2: error message") + 969 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-2: output should be empty") + 970 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-2: error message") 971 # check that stop(1) was called - 972 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-2: exit status") + 972 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-2: exit status") 973 # don't restore from ebp 974 81 0/subop/add %esp 8/imm32 975 # . epilogue @@ -1008,7 +1008,7 @@ if ('onhashchange' in window) { 996 (write _test-input-stream "fn foo a: (addr array (addr int) 3) {\n") 997 (write _test-input-stream "}\n") 998 # convert - 999 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 999 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1000 # registers except esp clobbered at this point 1001 # restore ed 1002 89/<- %edx 4/r32/esp @@ -1016,10 +1016,10 @@ if ('onhashchange' in window) { 1004 (flush _test-error-buffered-file) 1005 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1011 # check output - 1012 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-3: output should be empty") - 1013 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-3: error message") + 1012 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-3: output should be empty") + 1013 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-3: error message") 1014 # check that stop(1) was called - 1015 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-3: exit status") + 1015 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-3: exit status") 1016 # don't restore from ebp 1017 81 0/subop/add %esp 8/imm32 1018 # . epilogue @@ -1046,7 +1046,7 @@ if ('onhashchange' in window) { 1039 (write _test-input-stream "fn foo a: (array (addr int) 3) {\n") 1040 (write _test-input-stream "}\n") 1041 # convert - 1042 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1042 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1043 # registers except esp clobbered at this point 1044 # restore ed 1045 89/<- %edx 4/r32/esp @@ -1054,10 +1054,10 @@ if ('onhashchange' in window) { 1047 (flush _test-error-buffered-file) 1048 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1054 # check output - 1055 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-4: output should be empty") - 1056 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-4: error message") + 1055 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-4: output should be empty") + 1056 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-4: error message") 1057 # check that stop(1) was called - 1058 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-4: exit status") + 1058 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-4: exit status") 1059 # don't restore from ebp 1060 81 0/subop/add %esp 8/imm32 1061 # . epilogue @@ -1078,7 +1078,7 @@ if ('onhashchange' in window) { 1076 (write _test-input-stream "fn main a: (addr addr int) {\n") 1077 (write _test-input-stream "}\n") 1078 # convert - 1079 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1079 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1080 (flush _test-output-buffered-file) 1081 # no errors 1082 # . epilogue @@ -1099,7 +1099,7 @@ if ('onhashchange' in window) { 1097 # 1098 (write _test-input-stream "sig lookup h: (handle _T) -> _/eax: (addr _T)\n") 1099 # convert - 1100 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1100 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1101 (flush _test-output-buffered-file) 1102 # no errors 1103 # . epilogue @@ -1121,23 +1121,23 @@ if ('onhashchange' in window) { 1119 (write _test-input-stream " increment n\n") 1120 (write _test-input-stream "}\n") 1121 # convert - 1122 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1122 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1123 (flush _test-output-buffered-file) 1124 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 1130 # check output - 1131 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0") + 1131 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0") 1132 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg-and-body/1") - 1133 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2") - 1134 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3") - 1135 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4") - 1136 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5") - 1137 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6") - 1138 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7") - 1139 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8") + 1133 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2") + 1134 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3") + 1135 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4") + 1136 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5") + 1137 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6") + 1138 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7") + 1139 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8") 1140 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg-and-body/9") - 1141 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10") - 1142 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11") - 1143 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12") + 1141 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10") + 1142 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11") + 1143 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12") 1144 # . epilogue 1145 89/<- %esp 5/r32/ebp 1146 5d/pop-to-ebp @@ -1157,23 +1157,23 @@ if ('onhashchange' in window) { 1160 (write _test-input-stream " increment b\n") 1161 (write _test-input-stream "}\n") 1162 # convert - 1163 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1163 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1164 (flush _test-output-buffered-file) 1165 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 1171 # check output - 1172 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0") + 1172 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0") 1173 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-distinguishes-args/1") - 1174 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2") - 1175 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3") - 1176 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4") - 1177 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5") - 1178 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6") - 1179 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7") - 1180 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8") + 1174 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2") + 1175 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3") + 1176 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4") + 1177 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5") + 1178 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6") + 1179 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7") + 1180 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8") 1181 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-distinguishes-args/9") - 1182 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10") - 1183 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11") - 1184 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12") + 1182 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10") + 1183 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11") + 1184 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12") 1185 # . epilogue 1186 89/<- %esp 5/r32/ebp 1187 5d/pop-to-ebp @@ -1193,24 +1193,24 @@ if ('onhashchange' in window) { 1201 (write _test-input-stream " return 0\n") 1202 (write _test-input-stream "}\n") 1203 # convert - 1204 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1204 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1205 (flush _test-output-buffered-file) 1206 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 1212 # check output - 1213 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-literal/0") + 1213 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-literal/0") 1214 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-literal/1") - 1215 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-literal/2") - 1216 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-literal/3") - 1217 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-literal/4") - 1218 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-literal/5") - 1219 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy %eax 0/imm32" "F - test-convert-function-with-return-literal/6") - 1220 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-literal/7") - 1221 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-literal/8") - 1222 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-literal/9") + 1215 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-literal/2") + 1216 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-literal/3") + 1217 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-literal/4") + 1218 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-literal/5") + 1219 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy %eax 0/imm32" "F - test-convert-function-with-return-literal/6") + 1220 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-literal/7") + 1221 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-literal/8") + 1222 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-literal/9") 1223 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-literal/10") - 1224 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-literal/11") - 1225 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-literal/12") - 1226 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-literal/13") + 1224 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-literal/11") + 1225 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-literal/12") + 1226 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-literal/13") 1227 # . epilogue 1228 89/<- %esp 5/r32/ebp 1229 5d/pop-to-ebp @@ -1231,26 +1231,26 @@ if ('onhashchange' in window) { 1244 (write _test-input-stream " return y\n") 1245 (write _test-input-stream "}\n") 1246 # convert - 1247 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1247 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1248 (flush _test-output-buffered-file) 1249 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 1255 # check output - 1256 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return/0") + 1256 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return/0") 1257 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return/1") - 1258 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return/2") - 1259 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return/3") - 1260 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return/4") - 1261 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return/5") - 1262 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return/6") # y - 1263 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-function-with-return/7") - 1264 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return/8") - 1265 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return/9") - 1266 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return/10") - 1267 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return/11") + 1258 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return/2") + 1259 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return/3") + 1260 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return/4") + 1261 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return/5") + 1262 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return/6") # y + 1263 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-function-with-return/7") + 1264 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return/8") + 1265 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return/9") + 1266 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return/10") + 1267 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return/11") 1268 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return/12") - 1269 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return/13") - 1270 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return/14") - 1271 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return/15") + 1269 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return/13") + 1270 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return/14") + 1271 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return/15") 1272 # . epilogue 1273 89/<- %esp 5/r32/ebp 1274 5d/pop-to-ebp @@ -1271,26 +1271,26 @@ if ('onhashchange' in window) { 1289 (write _test-input-stream " return y\n") 1290 (write _test-input-stream "}\n") 1291 # convert - 1292 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1292 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1293 (flush _test-output-buffered-file) 1294 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 1300 # check output - 1301 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return/0") + 1301 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return/0") 1302 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return/1") - 1303 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return/2") - 1304 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return/3") - 1305 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return/4") - 1306 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return/5") - 1307 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return/6") # y - 1308 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *(ebp+0xfffffffc) 0x00000000/x32" "F - test-convert-function-with-return/7") - 1309 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return/8") - 1310 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return/9") - 1311 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return/10") - 1312 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return/11") + 1303 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return/2") + 1304 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return/3") + 1305 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return/4") + 1306 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return/5") + 1307 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return/6") # y + 1308 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *(ebp+0xfffffffc) 0x00000000/x32" "F - test-convert-function-with-return/7") + 1309 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return/8") + 1310 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return/9") + 1311 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return/10") + 1312 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return/11") 1313 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return/12") - 1314 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return/13") - 1315 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return/14") - 1316 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return/15") + 1314 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return/13") + 1315 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return/14") + 1316 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return/15") 1317 # . epilogue 1318 89/<- %esp 5/r32/ebp 1319 5d/pop-to-ebp @@ -1311,27 +1311,27 @@ if ('onhashchange' in window) { 1334 (write _test-input-stream " return y\n") 1335 (write _test-input-stream "}\n") 1336 # convert - 1337 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1337 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1338 (flush _test-output-buffered-file) 1339 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 1345 # check output - 1346 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register/0") + 1346 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register/0") 1347 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-register/1") - 1348 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register/2") - 1349 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register/3") - 1350 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register/4") - 1351 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register/5") - 1352 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register/6") - 1353 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register/7") - 1354 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-return-register/8") - 1355 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register/9") - 1356 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register/10") - 1357 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register/11") - 1358 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register/12") + 1348 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register/2") + 1349 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register/3") + 1350 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register/4") + 1351 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register/5") + 1352 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register/6") + 1353 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register/7") + 1354 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-return-register/8") + 1355 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register/9") + 1356 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register/10") + 1357 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register/11") + 1358 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register/12") 1359 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-register/13") - 1360 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register/14") - 1361 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register/15") - 1362 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register/16") + 1360 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register/14") + 1361 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register/15") + 1362 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register/16") 1363 # . epilogue 1364 89/<- %esp 5/r32/ebp 1365 5d/pop-to-ebp @@ -1357,7 +1357,7 @@ if ('onhashchange' in window) { 1385 (write _test-input-stream "fn foo -> _: int {\n") 1386 (write _test-input-stream "}\n") 1387 # convert - 1388 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1388 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1389 # registers except esp clobbered at this point 1390 # restore ed 1391 89/<- %edx 4/r32/esp @@ -1365,10 +1365,10 @@ if ('onhashchange' in window) { 1393 (flush _test-error-buffered-file) 1394 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1400 # check output - 1401 (check-stream-equal _test-output-stream "" "F - test-function-with-output-without-register: output should be empty") + 1401 (check-stream-equal _test-output-stream "" "F - test-function-with-output-without-register: output should be empty") 1402 (check-next-stream-line-equal _test-error-stream "fn foo: function output '_' must be in a register, in instruction 'fn foo -> _: int {" "F - test-function-with-output-without-register: error message") 1403 # check that stop(1) was called - 1404 (check-ints-equal *(edx+4) 2 "F - test-function-with-output-without-register: exit status") + 1404 (check-ints-equal *(edx+4) 2 "F - test-function-with-output-without-register: exit status") 1405 # don't restore from ebp 1406 81 0/subop/add %esp 8/imm32 1407 # . epilogue @@ -1395,7 +1395,7 @@ if ('onhashchange' in window) { 1428 (write _test-input-stream "fn foo -> _/eax: int, _/eax: int {\n") 1429 (write _test-input-stream "}\n") 1430 # convert - 1431 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1431 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1432 # registers except esp clobbered at this point 1433 # restore ed 1434 89/<- %edx 4/r32/esp @@ -1403,10 +1403,10 @@ if ('onhashchange' in window) { 1436 (flush _test-error-buffered-file) 1437 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1443 # check output - 1444 (check-stream-equal _test-output-stream "" "F - test-function-with-outputs-in-conflicting-registers: output should be empty") - 1445 (check-next-stream-line-equal _test-error-stream "fn foo: outputs must be in unique registers" "F - test-function-with-outputs-in-conflicting-registers: error message") + 1444 (check-stream-equal _test-output-stream "" "F - test-function-with-outputs-in-conflicting-registers: output should be empty") + 1445 (check-next-stream-line-equal _test-error-stream "fn foo: outputs must be in unique registers" "F - test-function-with-outputs-in-conflicting-registers: error message") 1446 # check that stop(1) was called - 1447 (check-ints-equal *(edx+4) 2 "F - test-function-with-outputs-in-conflicting-registers: exit status") + 1447 (check-ints-equal *(edx+4) 2 "F - test-function-with-outputs-in-conflicting-registers: exit status") 1448 # don't restore from ebp 1449 81 0/subop/add %esp 8/imm32 1450 # . epilogue @@ -1434,7 +1434,7 @@ if ('onhashchange' in window) { 1472 (write _test-input-stream " return 0\n") 1473 (write _test-input-stream "}\n") 1474 # convert - 1475 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1475 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1476 # registers except esp clobbered at this point 1477 # restore ed 1478 89/<- %edx 4/r32/esp @@ -1442,10 +1442,10 @@ if ('onhashchange' in window) { 1480 (flush _test-error-buffered-file) 1481 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1487 # check output - 1488 (check-stream-equal _test-output-stream "" "F - test-function-with-named-output: output should be empty") - 1489 (check-next-stream-line-equal _test-error-stream "fn foo: function outputs cannot be named; rename 'x' in the header to '_'" "F - test-function-with-named-output: error message") + 1488 (check-stream-equal _test-output-stream "" "F - test-function-with-named-output: output should be empty") + 1489 (check-next-stream-line-equal _test-error-stream "fn foo: function outputs cannot be named; rename 'x' in the header to '_'" "F - test-function-with-named-output: error message") 1490 # check that stop(1) was called - 1491 (check-ints-equal *(edx+4) 2 "F - test-function-with-named-output: exit status") + 1491 (check-ints-equal *(edx+4) 2 "F - test-function-with-named-output: exit status") 1492 # don't restore from ebp 1493 81 0/subop/add %esp 8/imm32 1494 # . epilogue @@ -1474,7 +1474,7 @@ if ('onhashchange' in window) { 1517 (write _test-input-stream " return x\n") 1518 (write _test-input-stream "}\n") 1519 # convert - 1520 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1520 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1521 # registers except esp clobbered at this point 1522 # restore ed 1523 89/<- %edx 4/r32/esp @@ -1482,10 +1482,10 @@ if ('onhashchange' in window) { 1525 (flush _test-error-buffered-file) 1526 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1532 # check output - 1533 (check-stream-equal _test-output-stream "" "F - test-return-with-wrong-type: output should be empty") - 1534 (check-next-stream-line-equal _test-error-stream "fn foo: return: 'x' has the wrong type" "F - test-return-with-wrong-type: error message") + 1533 (check-stream-equal _test-output-stream "" "F - test-return-with-wrong-type: output should be empty") + 1534 (check-next-stream-line-equal _test-error-stream "fn foo: return: 'x' has the wrong type" "F - test-return-with-wrong-type: error message") 1535 # check that stop(1) was called - 1536 (check-ints-equal *(edx+4) 2 "F - test-return-with-wrong-type: exit status") + 1536 (check-ints-equal *(edx+4) 2 "F - test-return-with-wrong-type: exit status") 1537 # don't restore from ebp 1538 81 0/subop/add %esp 8/imm32 1539 # . epilogue @@ -1513,7 +1513,7 @@ if ('onhashchange' in window) { 1561 (write _test-input-stream " var x/eax: boolean <- copy 0\n") 1562 (write _test-input-stream "}\n") 1563 # convert - 1564 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1564 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1565 # registers except esp clobbered at this point 1566 # restore ed 1567 89/<- %edx 4/r32/esp @@ -1521,10 +1521,10 @@ if ('onhashchange' in window) { 1569 (flush _test-error-buffered-file) 1570 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1576 # check output - 1577 (check-stream-equal _test-output-stream "" "F - test-missing-return: output should be empty") - 1578 (check-next-stream-line-equal _test-error-stream "fn foo: final statement should be a 'return'" "F - test-missing-return: error message") + 1577 (check-stream-equal _test-output-stream "" "F - test-missing-return: output should be empty") + 1578 (check-next-stream-line-equal _test-error-stream "fn foo: final statement should be a 'return'" "F - test-missing-return: error message") 1579 # check that stop(1) was called - 1580 (check-ints-equal *(edx+4) 2 "F - test-missing-return: exit status") + 1580 (check-ints-equal *(edx+4) 2 "F - test-missing-return: exit status") 1581 # don't restore from ebp 1582 81 0/subop/add %esp 8/imm32 1583 # . epilogue @@ -1551,7 +1551,7 @@ if ('onhashchange' in window) { 1604 (write _test-input-stream "fn foo -> _/eax: int {\n") 1605 (write _test-input-stream "}\n") 1606 # convert - 1607 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1607 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1608 # registers except esp clobbered at this point 1609 # restore ed 1610 89/<- %edx 4/r32/esp @@ -1559,10 +1559,10 @@ if ('onhashchange' in window) { 1612 (flush _test-error-buffered-file) 1613 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1619 # check output - 1620 (check-stream-equal _test-output-stream "" "F - test-missing-return-2: output should be empty") - 1621 (check-next-stream-line-equal _test-error-stream "fn foo: final statement should be a 'return'" "F - test-missing-return-2: error message") + 1620 (check-stream-equal _test-output-stream "" "F - test-missing-return-2: output should be empty") + 1621 (check-next-stream-line-equal _test-error-stream "fn foo: final statement should be a 'return'" "F - test-missing-return-2: error message") 1622 # check that stop(1) was called - 1623 (check-ints-equal *(edx+4) 2 "F - test-missing-return-2: exit status") + 1623 (check-ints-equal *(edx+4) 2 "F - test-missing-return-2: exit status") 1624 # don't restore from ebp 1625 81 0/subop/add %esp 8/imm32 1626 # . epilogue @@ -1591,7 +1591,7 @@ if ('onhashchange' in window) { 1649 (write _test-input-stream " return 0\n") 1650 (write _test-input-stream "}\n") 1651 # convert - 1652 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1652 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1653 # registers except esp clobbered at this point 1654 # restore ed 1655 89/<- %edx 4/r32/esp @@ -1599,10 +1599,10 @@ if ('onhashchange' in window) { 1657 (flush _test-error-buffered-file) 1658 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1664 # check output - 1665 (check-stream-equal _test-output-stream "" "F - test-early-exit-without-return: output should be empty") - 1666 (check-next-stream-line-equal _test-error-stream "fn foo has outputs, so you cannot 'break' out of the outermost block. Use 'return'." "F - test-early-exit-without-return: error message") + 1665 (check-stream-equal _test-output-stream "" "F - test-early-exit-without-return: output should be empty") + 1666 (check-next-stream-line-equal _test-error-stream "fn foo has outputs, so you cannot 'break' out of the outermost block. Use 'return'." "F - test-early-exit-without-return: error message") 1667 # check that stop(1) was called - 1668 (check-ints-equal *(edx+4) 2 "F - test-early-exit-without-return: exit status") + 1668 (check-ints-equal *(edx+4) 2 "F - test-early-exit-without-return: exit status") 1669 # don't restore from ebp 1670 81 0/subop/add %esp 8/imm32 1671 # . epilogue @@ -1630,7 +1630,7 @@ if ('onhashchange' in window) { 1693 (write _test-input-stream " return\n") 1694 (write _test-input-stream "}\n") 1695 # convert - 1696 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1696 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1697 # registers except esp clobbered at this point 1698 # restore ed 1699 89/<- %edx 4/r32/esp @@ -1638,10 +1638,10 @@ if ('onhashchange' in window) { 1701 (flush _test-error-buffered-file) 1702 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1708 # check output - 1709 (check-stream-equal _test-output-stream "" "F - test-return-with-too-few-inouts: output should be empty") - 1710 (check-next-stream-line-equal _test-error-stream "fn foo: return: too few inouts" "F - test-return-with-too-few-inouts: error message") + 1709 (check-stream-equal _test-output-stream "" "F - test-return-with-too-few-inouts: output should be empty") + 1710 (check-next-stream-line-equal _test-error-stream "fn foo: return: too few inouts" "F - test-return-with-too-few-inouts: error message") 1711 # check that stop(1) was called - 1712 (check-ints-equal *(edx+4) 2 "F - test-return-with-too-few-inouts: exit status") + 1712 (check-ints-equal *(edx+4) 2 "F - test-return-with-too-few-inouts: exit status") 1713 # don't restore from ebp 1714 81 0/subop/add %esp 8/imm32 1715 # . epilogue @@ -1669,7 +1669,7 @@ if ('onhashchange' in window) { 1737 (write _test-input-stream " return 0, 0\n") 1738 (write _test-input-stream "}\n") 1739 # convert - 1740 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1740 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1741 # registers except esp clobbered at this point 1742 # restore ed 1743 89/<- %edx 4/r32/esp @@ -1677,10 +1677,10 @@ if ('onhashchange' in window) { 1745 (flush _test-error-buffered-file) 1746 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1752 # check output - 1753 (check-stream-equal _test-output-stream "" "F - test-return-with-too-many-inouts: output should be empty") - 1754 (check-next-stream-line-equal _test-error-stream "fn foo: return: too many inouts" "F - test-return-with-too-many-inouts: error message") + 1753 (check-stream-equal _test-output-stream "" "F - test-return-with-too-many-inouts: output should be empty") + 1754 (check-next-stream-line-equal _test-error-stream "fn foo: return: too many inouts" "F - test-return-with-too-many-inouts: error message") 1755 # check that stop(1) was called - 1756 (check-ints-equal *(edx+4) 2 "F - test-return-with-too-many-inouts: exit status") + 1756 (check-ints-equal *(edx+4) 2 "F - test-return-with-too-many-inouts: exit status") 1757 # don't restore from ebp 1758 81 0/subop/add %esp 8/imm32 1759 # . epilogue @@ -1710,7 +1710,7 @@ if ('onhashchange' in window) { 1783 (write _test-input-stream " return y, x\n") 1784 (write _test-input-stream "}\n") 1785 # convert - 1786 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1786 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1787 # registers except esp clobbered at this point 1788 # restore ed 1789 89/<- %edx 4/r32/esp @@ -1718,10 +1718,10 @@ if ('onhashchange' in window) { 1791 (flush _test-error-buffered-file) 1792 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1798 # check output - 1799 (check-stream-equal _test-output-stream "" "F - test-return-unavailable-value: output should be empty") - 1800 (check-next-stream-line-equal _test-error-stream "fn foo: return: 'x' is no longer available" "F - test-return-unavailable-value: error message") + 1799 (check-stream-equal _test-output-stream "" "F - test-return-unavailable-value: output should be empty") + 1800 (check-next-stream-line-equal _test-error-stream "fn foo: return: 'x' is no longer available" "F - test-return-unavailable-value: error message") 1801 # check that stop(1) was called - 1802 (check-ints-equal *(edx+4) 2 "F - test-return-unavailable-value: exit status") + 1802 (check-ints-equal *(edx+4) 2 "F - test-return-unavailable-value: exit status") 1803 # don't restore from ebp 1804 81 0/subop/add %esp 8/imm32 1805 # . epilogue @@ -1749,7 +1749,7 @@ if ('onhashchange' in window) { 1827 (write _test-input-stream " return 0\n") 1828 (write _test-input-stream "}\n") 1829 # convert - 1830 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1830 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1831 # registers except esp clobbered at this point 1832 # restore ed 1833 89/<- %edx 4/r32/esp @@ -1757,10 +1757,10 @@ if ('onhashchange' in window) { 1835 (flush _test-error-buffered-file) 1836 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1842 # check output - 1843 (check-stream-equal _test-output-stream "" "F - test-return-literal-to-float: output should be empty") - 1844 (check-next-stream-line-equal _test-error-stream "fn foo: return: cannot copy literal '0' to float" "F - test-return-literal-to-float: error message") + 1843 (check-stream-equal _test-output-stream "" "F - test-return-literal-to-float: output should be empty") + 1844 (check-next-stream-line-equal _test-error-stream "fn foo: return: cannot copy literal '0' to float" "F - test-return-literal-to-float: error message") 1845 # check that stop(1) was called - 1846 (check-ints-equal *(edx+4) 2 "F - test-return-literal-to-float: exit status") + 1846 (check-ints-equal *(edx+4) 2 "F - test-return-literal-to-float: exit status") 1847 # don't restore from ebp 1848 81 0/subop/add %esp 8/imm32 1849 # . epilogue @@ -1782,28 +1782,28 @@ if ('onhashchange' in window) { 1865 (write _test-input-stream " return x, x\n") 1866 (write _test-input-stream "}\n") 1867 # convert - 1868 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1868 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1869 (flush _test-output-buffered-file) 1870 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 1876 # check output - 1877 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-return-with-duplicate-values/0") + 1877 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-return-with-duplicate-values/0") 1878 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-return-with-duplicate-values/1") - 1879 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-return-with-duplicate-values/2") - 1880 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-return-with-duplicate-values/3") - 1881 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-return-with-duplicate-values/4") - 1882 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-return-with-duplicate-values/5") - 1883 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-return-with-duplicate-values/6") - 1884 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0x34/imm32" "F - test-convert-return-with-duplicate-values/7") - 1885 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-return-with-duplicate-values/8") - 1886 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000001/r32" "F - test-convert-return-with-duplicate-values/9") - 1887 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-return-with-duplicate-values/10") - 1888 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-return-with-duplicate-values/11") - 1889 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-return-with-duplicate-values/12") - 1890 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-return-with-duplicate-values/13") + 1879 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-return-with-duplicate-values/2") + 1880 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-return-with-duplicate-values/3") + 1881 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-return-with-duplicate-values/4") + 1882 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-return-with-duplicate-values/5") + 1883 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-return-with-duplicate-values/6") + 1884 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0x34/imm32" "F - test-convert-return-with-duplicate-values/7") + 1885 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-return-with-duplicate-values/8") + 1886 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000001/r32" "F - test-convert-return-with-duplicate-values/9") + 1887 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-return-with-duplicate-values/10") + 1888 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-return-with-duplicate-values/11") + 1889 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-return-with-duplicate-values/12") + 1890 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-return-with-duplicate-values/13") 1891 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-return-with-duplicate-values/14") - 1892 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-return-with-duplicate-values/15") - 1893 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-return-with-duplicate-values/16") - 1894 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-return-with-duplicate-values/17") + 1892 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-return-with-duplicate-values/15") + 1893 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-return-with-duplicate-values/16") + 1894 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-return-with-duplicate-values/17") 1895 # . epilogue 1896 89/<- %esp 5/r32/ebp 1897 5d/pop-to-ebp @@ -1824,28 +1824,28 @@ if ('onhashchange' in window) { 1912 (write _test-input-stream " return x, x\n") 1913 (write _test-input-stream "}\n") 1914 # convert - 1915 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1915 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 1916 (flush _test-output-buffered-file) 1917 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 1923 # check output - 1924 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-return-with-duplicate-values-2/0") + 1924 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-return-with-duplicate-values-2/0") 1925 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-return-with-duplicate-values-2/1") - 1926 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-return-with-duplicate-values-2/2") - 1927 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-return-with-duplicate-values-2/3") - 1928 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-return-with-duplicate-values-2/4") - 1929 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-return-with-duplicate-values-2/5") - 1930 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-return-with-duplicate-values-2/6") - 1931 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x34/imm32" "F - test-convert-return-with-duplicate-values-2/7") - 1932 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000000/r32" "F - test-convert-return-with-duplicate-values-2/8") - 1933 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000001/r32" "F - test-convert-return-with-duplicate-values-2/9") - 1934 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-return-with-duplicate-values-2/10") - 1935 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-return-with-duplicate-values-2/11") - 1936 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-return-with-duplicate-values-2/12") - 1937 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-return-with-duplicate-values-2/13") + 1926 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-return-with-duplicate-values-2/2") + 1927 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-return-with-duplicate-values-2/3") + 1928 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-return-with-duplicate-values-2/4") + 1929 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-return-with-duplicate-values-2/5") + 1930 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-return-with-duplicate-values-2/6") + 1931 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x34/imm32" "F - test-convert-return-with-duplicate-values-2/7") + 1932 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000000/r32" "F - test-convert-return-with-duplicate-values-2/8") + 1933 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000001/r32" "F - test-convert-return-with-duplicate-values-2/9") + 1934 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-return-with-duplicate-values-2/10") + 1935 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-return-with-duplicate-values-2/11") + 1936 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-return-with-duplicate-values-2/12") + 1937 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-return-with-duplicate-values-2/13") 1938 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-return-with-duplicate-values-2/14") - 1939 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-return-with-duplicate-values-2/15") - 1940 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-return-with-duplicate-values-2/16") - 1941 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-return-with-duplicate-values-2/17") + 1939 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-return-with-duplicate-values-2/15") + 1940 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-return-with-duplicate-values-2/16") + 1941 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-return-with-duplicate-values-2/17") 1942 # . epilogue 1943 89/<- %esp 5/r32/ebp 1944 5d/pop-to-ebp @@ -1872,7 +1872,7 @@ if ('onhashchange' in window) { 1965 (write _test-input-stream " x <- copy 0x34\n") 1966 (write _test-input-stream "}\n") 1967 # convert - 1968 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1968 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 1969 # registers except esp clobbered at this point 1970 # restore ed 1971 89/<- %edx 4/r32/esp @@ -1880,10 +1880,10 @@ if ('onhashchange' in window) { 1973 (flush _test-error-buffered-file) 1974 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 1980 # check output - 1981 (check-stream-equal _test-output-stream "" "F - test-stmt-with-unknown-var: output should be empty") - 1982 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-stmt-with-unknown-var: error message") + 1981 (check-stream-equal _test-output-stream "" "F - test-stmt-with-unknown-var: output should be empty") + 1982 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-stmt-with-unknown-var: error message") 1983 # check that stop(1) was called - 1984 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-unknown-var: exit status") + 1984 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-unknown-var: exit status") 1985 # don't restore from ebp 1986 81 0/subop/add %esp 8/imm32 1987 # . epilogue @@ -1911,7 +1911,7 @@ if ('onhashchange' in window) { 2009 (write _test-input-stream " 1 <- copy 0x34\n") 2010 (write _test-input-stream "}\n") 2011 # convert - 2012 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2012 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 2013 # registers except esp clobbered at this point 2014 # restore ed 2015 89/<- %edx 4/r32/esp @@ -1919,10 +1919,10 @@ if ('onhashchange' in window) { 2017 (flush _test-error-buffered-file) 2018 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 2024 # check output - 2025 (check-stream-equal _test-output-stream "" "F - test-stmt-with-invalid-identifier: output should be empty") - 2026 (check-next-stream-line-equal _test-error-stream "fn foo: invalid identifier '1'" "F - test-stmt-with-invalid-identifier: error message") + 2025 (check-stream-equal _test-output-stream "" "F - test-stmt-with-invalid-identifier: output should be empty") + 2026 (check-next-stream-line-equal _test-error-stream "fn foo: invalid identifier '1'" "F - test-stmt-with-invalid-identifier: error message") 2027 # check that stop(1) was called - 2028 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-invalid-identifier: exit status") + 2028 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-invalid-identifier: exit status") 2029 # don't restore from ebp 2030 81 0/subop/add %esp 8/imm32 2031 # . epilogue @@ -1950,7 +1950,7 @@ if ('onhashchange' in window) { 2053 (write _test-input-stream " *x <- copy 0x34\n") 2054 (write _test-input-stream "}\n") 2055 # convert - 2056 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2056 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) 2057 # registers except esp clobbered at this point 2058 # restore ed 2059 89/<- %edx 4/r32/esp @@ -1958,10 +1958,10 @@ if ('onhashchange' in window) { 2061 (flush _test-error-buffered-file) 2062 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ 2068 # check output - 2069 (check-stream-equal _test-output-stream "" "F - test-stmt-with-deref-var: output should be empty") - 2070 (check-next-stream-line-equal _test-error-stream "fn foo: output '*x' should write to a register, and therefore cannot be dereferenced" "F - test-stmt-with-deref-var: error message") + 2069 (check-stream-equal _test-output-stream "" "F - test-stmt-with-deref-var: output should be empty") + 2070 (check-next-stream-line-equal _test-error-stream "fn foo: output '*x' should write to a register, and therefore cannot be dereferenced" "F - test-stmt-with-deref-var: error message") 2071 # check that stop(1) was called - 2072 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-deref-var: exit status") + 2072 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-deref-var: exit status") 2073 # don't restore from ebp 2074 81 0/subop/add %esp 8/imm32 2075 # . epilogue @@ -1984,28 +1984,28 @@ if ('onhashchange' in window) { 2092 (write _test-input-stream " return result\n") 2093 (write _test-input-stream "}\n") 2094 # convert - 2095 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2095 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 2096 (flush _test-output-buffered-file) 2097 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 2103 # check output - 2104 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0") + 2104 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0") 2105 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg/1") - 2106 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2") - 2107 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3") - 2108 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4") - 2109 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5") - 2110 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-literal-arg/6") - 2111 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/7") - 2112 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/8") - 2113 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-literal-arg/9") - 2114 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-literal-arg/10") - 2115 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-literal-arg/11") - 2116 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/12") - 2117 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/13") + 2106 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2") + 2107 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3") + 2108 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4") + 2109 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5") + 2110 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-literal-arg/6") + 2111 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/7") + 2112 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/8") + 2113 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-literal-arg/9") + 2114 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-literal-arg/10") + 2115 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-literal-arg/11") + 2116 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/12") + 2117 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/13") 2118 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg/14") - 2119 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/15") - 2120 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/16") - 2121 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/17") + 2119 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/15") + 2120 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/16") + 2121 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/17") 2122 # . epilogue 2123 89/<- %esp 5/r32/ebp 2124 5d/pop-to-ebp @@ -2027,28 +2027,28 @@ if ('onhashchange' in window) { 2140 (write _test-input-stream " return result\n") 2141 (write _test-input-stream "}\n") 2142 # convert - 2143 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2143 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 2144 (flush _test-output-buffered-file) 2145 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 2151 # check output - 2152 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0") + 2152 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0") 2153 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg-2/1") - 2154 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2") - 2155 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3") - 2156 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4") - 2157 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5") - 2158 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-with-literal-arg-2/6") - 2159 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/7") - 2160 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/8") - 2161 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/9") - 2162 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-literal-arg-2/10") - 2163 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-literal-arg-2/11") - 2164 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/12") - 2165 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/13") + 2154 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2") + 2155 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3") + 2156 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4") + 2157 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5") + 2158 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-with-literal-arg-2/6") + 2159 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/7") + 2160 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/8") + 2161 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/9") + 2162 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-literal-arg-2/10") + 2163 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-literal-arg-2/11") + 2164 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/12") + 2165 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/13") 2166 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg-2/14") - 2167 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/15") - 2168 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/16") - 2169 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/17") + 2167 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/15") + 2168 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/16") + 2169 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/17") 2170 # . epilogue 2171 89/<- %esp 5/r32/ebp 2172 5d/pop-to-ebp @@ -2074,45 +2074,45 @@ if ('onhashchange' in window) { 2192 (write _test-input-stream " return result\n") 2193 (write _test-input-stream "}\n") 2194 # convert - 2195 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2195 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 2196 (flush _test-output-buffered-file) 2197 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 2203 # check output - 2204 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0") + 2204 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0") 2205 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/1") - 2206 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2") - 2207 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3") - 2208 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4") - 2209 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5") - 2210 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/6") - 2211 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/7") - 2212 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8") - 2213 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-local-var-in-reg/9") - 2214 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10") - 2215 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/11") - 2216 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/12") + 2206 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2") + 2207 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3") + 2208 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4") + 2209 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5") + 2210 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/6") + 2211 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/7") + 2212 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8") + 2213 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-local-var-in-reg/9") + 2214 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10") + 2215 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/11") + 2216 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/12") 2217 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/13") - 2218 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/14") - 2219 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/15") - 2220 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/16") - 2221 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/17") + 2218 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/14") + 2219 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/15") + 2220 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/16") + 2221 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/17") 2222 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/18") - 2223 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/19") - 2224 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/20") - 2225 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/21") - 2226 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/22") - 2227 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/23") - 2228 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/24") - 2229 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/25") - 2230 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/26") - 2231 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27") - 2232 (check-next-stream-line-equal _test-output-stream " e9/jump $do-add:0x00000002:break/disp32" "F - test-convert-function-call-with-literal-arg/28") - 2233 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/29") - 2234 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/30") + 2223 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/19") + 2224 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/20") + 2225 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/21") + 2226 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/22") + 2227 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/23") + 2228 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/24") + 2229 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/25") + 2230 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/26") + 2231 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27") + 2232 (check-next-stream-line-equal _test-output-stream " e9/jump $do-add:0x00000002:break/disp32" "F - test-convert-function-call-with-literal-arg/28") + 2233 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/29") + 2234 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/30") 2235 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/31") - 2236 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/32") - 2237 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/33") - 2238 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/34") + 2236 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/32") + 2237 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/33") + 2238 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/34") 2239 # . epilogue 2240 89/<- %esp 5/r32/ebp 2241 5d/pop-to-ebp @@ -2133,7 +2133,7 @@ if ('onhashchange' in window) { 2256 (write _test-input-stream "}\n") 2257 (write _test-input-stream "sig string-func in: (addr array byte)\n") 2258 # convert - 2259 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2259 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 2260 # no errors 2261 # not bothering checking output 2262 # . epilogue @@ -2141,7 +2141,7 @@ if ('onhashchange' in window) { 2264 5d/pop-to-ebp 2265 c3/return 2266 - 2267 test-convert-function-call-with-null-addr: + 2267 test-convert-function-call-with-literal-string-arg-and-type-parameter-in-signature: 2268 # . prologue 2269 55/push-ebp 2270 89/<- %ebp 4/r32/esp @@ -2152,11 +2152,11 @@ if ('onhashchange' in window) { 2275 (clear-stream $_test-output-buffered-file->buffer) 2276 # 2277 (write _test-input-stream "fn foo {\n") - 2278 (write _test-input-stream " bar 0\n") + 2278 (write _test-input-stream " string-func \"abc\"\n") 2279 (write _test-input-stream "}\n") - 2280 (write _test-input-stream "sig bar in: (addr int)\n") + 2280 (write _test-input-stream "sig string-func in: (addr array _)\n") 2281 # convert - 2282 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2282 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 2283 # no errors 2284 # not bothering checking output 2285 # . epilogue @@ -2164,7 +2164,7 @@ if ('onhashchange' in window) { 2287 5d/pop-to-ebp 2288 c3/return 2289 - 2290 test-convert-function-call-with-signature: + 2290 test-convert-function-call-with-null-addr: 2291 # . prologue 2292 55/push-ebp 2293 89/<- %ebp 4/r32/esp @@ -2174,4834 +2174,4834 @@ if ('onhashchange' in window) { 2297 (clear-stream _test-output-stream) 2298 (clear-stream $_test-output-buffered-file->buffer) 2299 # - 2300 (write _test-input-stream "fn main -> _/ebx: int {\n") - 2301 (write _test-input-stream " var result/eax: int <- do-add 3 4\n") - 2302 (write _test-input-stream " return result\n") - 2303 (write _test-input-stream "}\n") - 2304 (write _test-input-stream "sig do-add a: int, b: int -> _/eax: int\n") - 2305 # convert - 2306 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2307 (flush _test-output-buffered-file) - 2308 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2314 # check output - 2315 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-signature/0") - 2316 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-signature/1") - 2317 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-signature/2") - 2318 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-signature/3") - 2319 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-signature/4") - 2320 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-signature/5") - 2321 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/6") - 2322 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-signature/6") - 2323 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8") - 2324 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-local-var-in-reg/9") - 2325 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10") - 2326 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-signature/7") - 2327 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-signature/8") - 2328 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-signature/9") - 2329 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-signature/10") - 2330 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-signature/11") - 2331 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-signature/12") - 2332 # . epilogue - 2333 89/<- %esp 5/r32/ebp - 2334 5d/pop-to-ebp - 2335 c3/return - 2336 - 2337 test-convert-function-with-local-var-in-mem: - 2338 # . prologue - 2339 55/push-ebp - 2340 89/<- %ebp 4/r32/esp - 2341 # setup - 2342 (clear-stream _test-input-stream) - 2343 (clear-stream $_test-input-buffered-file->buffer) - 2344 (clear-stream _test-output-stream) - 2345 (clear-stream $_test-output-buffered-file->buffer) - 2346 # - 2347 (write _test-input-stream "fn foo {\n") - 2348 (write _test-input-stream " var x: int\n") - 2349 (write _test-input-stream " increment x\n") - 2350 (write _test-input-stream "}\n") - 2351 # convert - 2352 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2353 (flush _test-output-buffered-file) - 2354 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2360 # check output - 2361 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0") - 2362 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1") - 2363 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2") - 2364 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3") - 2365 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4") - 2366 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5") - 2367 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6") - 2368 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7") - 2369 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem/8") - 2370 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9") - 2371 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10") - 2372 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11") - 2373 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12") - 2374 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13") - 2375 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14") - 2376 # . epilogue - 2377 89/<- %esp 5/r32/ebp - 2378 5d/pop-to-ebp - 2379 c3/return - 2380 - 2381 test-convert-invalid-literal: - 2382 # . prologue - 2383 55/push-ebp - 2384 89/<- %ebp 4/r32/esp - 2385 # setup - 2386 (clear-stream _test-input-stream) - 2387 (clear-stream $_test-input-buffered-file->buffer) - 2388 (clear-stream _test-output-stream) - 2389 (clear-stream $_test-output-buffered-file->buffer) - 2390 (clear-stream _test-error-stream) - 2391 (clear-stream $_test-error-buffered-file->buffer) - 2392 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 2393 68/push 0/imm32 - 2394 68/push 0/imm32 - 2395 89/<- %edx 4/r32/esp - 2396 (tailor-exit-descriptor %edx 0x10) - 2397 # - 2398 (write _test-input-stream "fn foo {\n") - 2399 (write _test-input-stream " increment 1n\n") - 2400 (write _test-input-stream "}\n") - 2401 # convert - 2402 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2403 # registers except esp clobbered at this point - 2404 # restore ed - 2405 89/<- %edx 4/r32/esp - 2406 (flush _test-output-buffered-file) - 2407 (flush _test-error-buffered-file) - 2408 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 2414 # check output - 2415 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-literal: output should be empty") - 2416 (check-next-stream-line-equal _test-error-stream "fn foo: variable '1n' cannot begin with a digit (or do you have a typo in a number?)" "F - test-convert-invalid-literal: error message") - 2417 # check that stop(1) was called - 2418 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-literal: exit status") - 2419 # don't restore from ebp - 2420 81 0/subop/add %esp 8/imm32 - 2421 # . epilogue - 2422 5d/pop-to-ebp - 2423 c3/return - 2424 - 2425 test-convert-valid-literal-with-metadata: - 2426 # . prologue - 2427 55/push-ebp - 2428 89/<- %ebp 4/r32/esp - 2429 # setup - 2430 (clear-stream _test-input-stream) - 2431 (clear-stream $_test-input-buffered-file->buffer) - 2432 (clear-stream _test-output-stream) - 2433 (clear-stream $_test-output-buffered-file->buffer) - 2434 # - 2435 (write _test-input-stream "fn foo {\n") - 2436 (write _test-input-stream " var x/eax: int <- copy 1/abc\n") - 2437 (write _test-input-stream "}\n") - 2438 # convert - 2439 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2440 (flush _test-output-buffered-file) - 2441 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2447 # no errors - 2448 # . epilogue - 2449 89/<- %esp 5/r32/ebp - 2450 5d/pop-to-ebp - 2451 c3/return - 2452 - 2453 test-local-var-in-mem-has-no-initializer: - 2454 # . prologue - 2455 55/push-ebp - 2456 89/<- %ebp 4/r32/esp - 2457 # setup - 2458 (clear-stream _test-input-stream) - 2459 (clear-stream $_test-input-buffered-file->buffer) - 2460 (clear-stream _test-output-stream) - 2461 (clear-stream $_test-output-buffered-file->buffer) - 2462 (clear-stream _test-error-stream) - 2463 (clear-stream $_test-error-buffered-file->buffer) - 2464 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 2465 68/push 0/imm32 - 2466 68/push 0/imm32 - 2467 89/<- %edx 4/r32/esp - 2468 (tailor-exit-descriptor %edx 0x10) - 2469 # - 2470 (write _test-input-stream "fn foo {\n") - 2471 (write _test-input-stream " var x: int <- copy 0\n") - 2472 (write _test-input-stream " increment x\n") - 2473 (write _test-input-stream "}\n") - 2474 # convert - 2475 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2476 # registers except esp clobbered at this point - 2477 # restore ed - 2478 89/<- %edx 4/r32/esp - 2479 (flush _test-output-buffered-file) - 2480 (flush _test-error-buffered-file) - 2481 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 2487 # check output - 2488 (check-stream-equal _test-output-stream "" "F - test-var-in-mem-has-no-initializer: output should be empty") - 2489 (check-next-stream-line-equal _test-error-stream "fn foo: var x: variables on the stack can't take an initializer" "F - test-var-in-mem-has-no-initializer: error message") - 2490 # check that stop(1) was called - 2491 (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status") - 2492 # don't restore from ebp - 2493 81 0/subop/add %esp 8/imm32 - 2494 # . epilogue - 2495 5d/pop-to-ebp - 2496 c3/return - 2497 - 2498 test-convert-function-with-local-var-with-compound-type-in-mem: - 2499 # . prologue - 2500 55/push-ebp - 2501 89/<- %ebp 4/r32/esp - 2502 # setup - 2503 (clear-stream _test-input-stream) - 2504 (clear-stream $_test-input-buffered-file->buffer) - 2505 (clear-stream _test-output-stream) - 2506 (clear-stream $_test-output-buffered-file->buffer) - 2507 # - 2508 (write _test-input-stream "fn foo {\n") - 2509 (write _test-input-stream " var x: (addr int)\n") - 2510 (write _test-input-stream " copy-to x, 0\n") - 2511 (write _test-input-stream "}\n") - 2512 # convert - 2513 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2514 (flush _test-output-buffered-file) - 2515 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2521 # check output - 2522 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0") - 2523 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1") - 2524 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2") - 2525 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/3") - 2526 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4") - 2527 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5") - 2528 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/6") - 2529 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy *(ebp+0xfffffffc) 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/7") - 2530 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/8") - 2531 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9") - 2532 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10") - 2533 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11") - 2534 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/12") - 2535 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/13") - 2536 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14") - 2537 # . epilogue - 2538 89/<- %esp 5/r32/ebp - 2539 5d/pop-to-ebp - 2540 c3/return - 2541 - 2542 test-convert-function-with-local-var-in-reg: - 2543 # . prologue - 2544 55/push-ebp - 2545 89/<- %ebp 4/r32/esp - 2546 # setup - 2547 (clear-stream _test-input-stream) - 2548 (clear-stream $_test-input-buffered-file->buffer) - 2549 (clear-stream _test-output-stream) - 2550 (clear-stream $_test-output-buffered-file->buffer) - 2551 # - 2552 (write _test-input-stream "fn foo {\n") - 2553 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2554 (write _test-input-stream " x <- increment\n") - 2555 (write _test-input-stream "}\n") - 2556 # convert - 2557 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2558 (flush _test-output-buffered-file) - 2559 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2565 # check output - 2566 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0") - 2567 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1") - 2568 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2") - 2569 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3") - 2570 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4") - 2571 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5") - 2572 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6") - 2573 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7") - 2574 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8") - 2575 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9") - 2576 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10") - 2577 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11") - 2578 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12") - 2579 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13") - 2580 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14") - 2581 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15") - 2582 # . epilogue - 2583 89/<- %esp 5/r32/ebp - 2584 5d/pop-to-ebp - 2585 c3/return - 2586 - 2587 test-convert-function-with-local-var-in-same-reg: - 2588 # . prologue - 2589 55/push-ebp - 2590 89/<- %ebp 4/r32/esp - 2591 # setup - 2592 (clear-stream _test-input-stream) - 2593 (clear-stream $_test-input-buffered-file->buffer) - 2594 (clear-stream _test-output-stream) - 2595 (clear-stream $_test-output-buffered-file->buffer) - 2596 # - 2597 (write _test-input-stream "fn foo {\n") - 2598 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2599 (write _test-input-stream " var y/ecx: int <- copy x\n") - 2600 (write _test-input-stream "}\n") - 2601 # convert - 2602 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2603 (flush _test-output-buffered-file) - 2604 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2610 # check output - 2611 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-same-reg/0") - 2612 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-same-reg/1") - 2613 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-same-reg/2") - 2614 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-same-reg/3") - 2615 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-same-reg/4") - 2616 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-same-reg/5") - 2617 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-same-reg/6") - 2618 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-same-reg/7") - 2619 # optimization: skip the second copy - 2620 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-same-reg/8") - 2621 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-same-reg/9") - 2622 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-same-reg/10") - 2623 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-same-reg/11") - 2624 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-same-reg/12") - 2625 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-same-reg/13") - 2626 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-same-reg/14") - 2627 # . epilogue - 2628 89/<- %esp 5/r32/ebp - 2629 5d/pop-to-ebp - 2630 c3/return - 2631 - 2632 test-convert-function-with-local-var-in-same-reg-dereferenced: - 2633 # . prologue - 2634 55/push-ebp - 2635 89/<- %ebp 4/r32/esp - 2636 # setup - 2637 (clear-stream _test-input-stream) - 2638 (clear-stream $_test-input-buffered-file->buffer) - 2639 (clear-stream _test-output-stream) - 2640 (clear-stream $_test-output-buffered-file->buffer) - 2641 # - 2642 (write _test-input-stream "fn foo {\n") - 2643 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") - 2644 (write _test-input-stream " var y/ecx: int <- copy *x\n") - 2645 (write _test-input-stream "}\n") - 2646 # convert - 2647 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2648 (flush _test-output-buffered-file) - 2649 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2655 # check output - 2656 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/0") - 2657 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/1") - 2658 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/2") - 2659 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/3") - 2660 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/4") - 2661 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/5") - 2662 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/6") - 2663 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/7") - 2664 (check-next-stream-line-equal _test-output-stream " 8b/-> *ecx 0x00000001/r32" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/8") # don't optimize this away - 2665 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/9") - 2666 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/10") - 2667 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/11") - 2668 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/12") - 2669 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/13") - 2670 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/14") - 2671 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/15") - 2672 # . epilogue - 2673 89/<- %esp 5/r32/ebp - 2674 5d/pop-to-ebp - 2675 c3/return - 2676 - 2677 test-float-var-in-wrong-register: - 2678 # . prologue - 2679 55/push-ebp - 2680 89/<- %ebp 4/r32/esp - 2681 # setup - 2682 (clear-stream _test-input-stream) - 2683 (clear-stream $_test-input-buffered-file->buffer) - 2684 (clear-stream _test-output-stream) - 2685 (clear-stream $_test-output-buffered-file->buffer) - 2686 (clear-stream _test-error-stream) - 2687 (clear-stream $_test-error-buffered-file->buffer) - 2688 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 2689 68/push 0/imm32 - 2690 68/push 0/imm32 - 2691 89/<- %edx 4/r32/esp - 2692 (tailor-exit-descriptor %edx 0x10) - 2693 # - 2694 (write _test-input-stream "fn foo {\n") - 2695 (write _test-input-stream " var x/eax: int <- copy 0\n") - 2696 (write _test-input-stream " var y/eax: float <- convert x\n") - 2697 (write _test-input-stream "}\n") - 2698 # convert - 2699 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2700 # registers except esp clobbered at this point - 2701 # restore ed - 2702 89/<- %edx 4/r32/esp - 2703 (flush _test-output-buffered-file) - 2704 (flush _test-error-buffered-file) - 2705 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 2711 # check output - 2712 (check-stream-equal _test-output-stream "" "F - test-float-var-in-wrong-register: output should be empty") - 2713 (check-next-stream-line-equal _test-error-stream "fn foo: float var 'y' should be in a floating-point register" "F - test-float-var-in-wrong-register: error message") - 2714 # check that stop(1) was called - 2715 (check-ints-equal *(edx+4) 2 "F - test-float-var-in-wrong-register: exit status") - 2716 # don't restore from ebp - 2717 81 0/subop/add %esp 8/imm32 - 2718 # . epilogue - 2719 5d/pop-to-ebp - 2720 c3/return - 2721 - 2722 test-non-float-var-in-wrong-register: - 2723 # . prologue - 2724 55/push-ebp - 2725 89/<- %ebp 4/r32/esp - 2726 # setup - 2727 (clear-stream _test-input-stream) - 2728 (clear-stream $_test-input-buffered-file->buffer) - 2729 (clear-stream _test-output-stream) - 2730 (clear-stream $_test-output-buffered-file->buffer) - 2731 (clear-stream _test-error-stream) - 2732 (clear-stream $_test-error-buffered-file->buffer) - 2733 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 2734 68/push 0/imm32 - 2735 68/push 0/imm32 - 2736 89/<- %edx 4/r32/esp - 2737 (tailor-exit-descriptor %edx 0x10) - 2738 # - 2739 (write _test-input-stream "fn foo {\n") - 2740 (write _test-input-stream " var x/xmm5: int <- copy 0\n") - 2741 (write _test-input-stream "}\n") - 2742 # convert - 2743 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2744 # registers except esp clobbered at this point - 2745 # restore ed - 2746 89/<- %edx 4/r32/esp - 2747 (flush _test-output-buffered-file) - 2748 (flush _test-error-buffered-file) - 2749 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 2755 # check output - 2756 (check-stream-equal _test-output-stream "" "F - test-non-float-var-in-wrong-register: output should be empty") - 2757 (check-next-stream-line-equal _test-error-stream "fn foo: non-float var 'x' should be in an integer register" "F - test-non-float-var-in-wrong-register: error message") - 2758 # check that stop(1) was called - 2759 (check-ints-equal *(edx+4) 2 "F - test-non-float-var-in-wrong-register: exit status") - 2760 # don't restore from ebp - 2761 81 0/subop/add %esp 8/imm32 - 2762 # . epilogue - 2763 5d/pop-to-ebp - 2764 c3/return - 2765 - 2766 test-convert-function-with-allocate: - 2767 # . prologue - 2768 55/push-ebp - 2769 89/<- %ebp 4/r32/esp - 2770 # setup - 2771 (clear-stream _test-input-stream) - 2772 (clear-stream $_test-input-buffered-file->buffer) - 2773 (clear-stream _test-output-stream) - 2774 (clear-stream $_test-output-buffered-file->buffer) - 2775 # - 2776 (write _test-input-stream "fn foo {\n") - 2777 (write _test-input-stream " var x/ecx: (addr handle int) <- copy 0\n") - 2778 (write _test-input-stream " allocate x\n") - 2779 (write _test-input-stream "}\n") - 2780 # convert - 2781 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2782 (flush _test-output-buffered-file) - 2783 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2789 # check output - 2790 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-allocate/0") - 2791 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-allocate/1") - 2792 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-allocate/2") - 2793 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-allocate/3") - 2794 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-allocate/4") - 2795 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-allocate/5") - 2796 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-allocate/6") - 2797 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-allocate/7") - 2798 (check-next-stream-line-equal _test-output-stream " (allocate Heap 0x00000004 %ecx)" "F - test-convert-function-with-allocate/8") # 4 = size-of(int) - 2799 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-allocate/9") - 2800 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-allocate/10") - 2801 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-allocate/11") - 2802 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-allocate/12") - 2803 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-allocate/13") - 2804 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-allocate/14") - 2805 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-allocate/15") - 2806 # . epilogue - 2807 89/<- %esp 5/r32/ebp - 2808 5d/pop-to-ebp - 2809 c3/return - 2810 - 2811 test-initializer-in-hex: - 2812 # . prologue - 2813 55/push-ebp - 2814 89/<- %ebp 4/r32/esp - 2815 # setup - 2816 (clear-stream _test-input-stream) - 2817 (clear-stream $_test-input-buffered-file->buffer) - 2818 (clear-stream _test-output-stream) - 2819 (clear-stream $_test-output-buffered-file->buffer) - 2820 (clear-stream _test-error-stream) - 2821 (clear-stream $_test-error-buffered-file->buffer) - 2822 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 2823 68/push 0/imm32 - 2824 68/push 0/imm32 - 2825 89/<- %edx 4/r32/esp - 2826 (tailor-exit-descriptor %edx 0x10) - 2827 # - 2828 (write _test-input-stream "fn foo {\n") - 2829 (write _test-input-stream " var x/ecx: int <- copy 10\n") - 2830 (write _test-input-stream "}\n") - 2831 # convert - 2832 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2833 # registers except esp clobbered at this point - 2834 # restore ed - 2835 89/<- %edx 4/r32/esp - 2836 (flush _test-output-buffered-file) - 2837 (flush _test-error-buffered-file) - 2838 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 2844 # check output - 2845 (check-stream-equal _test-output-stream "" "F - test-initializer-in-hex: output should be empty") - 2846 (check-next-stream-line-equal _test-error-stream "literal integers are always hex in Mu; start '10' with a '0x' to be unambiguous, converting it to hexadecimal as necessary." "F - test-initializer-in-hex: error message") - 2847 # check that stop(1) was called - 2848 (check-ints-equal *(edx+4) 2 "F - test-initializer-in-hex: exit status") - 2849 # don't restore from ebp - 2850 81 0/subop/add %esp 8/imm32 - 2851 # . epilogue - 2852 5d/pop-to-ebp - 2853 c3/return - 2854 - 2855 test-convert-function-with-second-local-var-in-same-reg: - 2856 # . prologue - 2857 55/push-ebp - 2858 89/<- %ebp 4/r32/esp - 2859 # setup - 2860 (clear-stream _test-input-stream) - 2861 (clear-stream $_test-input-buffered-file->buffer) - 2862 (clear-stream _test-output-stream) - 2863 (clear-stream $_test-output-buffered-file->buffer) - 2864 # - 2865 (write _test-input-stream "fn foo {\n") - 2866 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2867 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2868 (write _test-input-stream " y <- increment\n") - 2869 (write _test-input-stream "}\n") - 2870 # convert - 2871 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2872 (flush _test-output-buffered-file) - 2873 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2879 # check output - 2880 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0") - 2881 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1") - 2882 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2") - 2883 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-second-local-var-in-same-reg/3") - 2884 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4") - 2885 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5") - 2886 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/6") - 2887 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/7") - 2888 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/8") - 2889 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9") - 2890 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/10") - 2891 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11") - 2892 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12") - 2893 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13") - 2894 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-second-local-var-in-same-reg/14") - 2895 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15") - 2896 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16") - 2897 # . epilogue - 2898 89/<- %esp 5/r32/ebp - 2899 5d/pop-to-ebp - 2900 c3/return - 2901 - 2902 test-read-clobbered-reg-var: - 2903 # . prologue - 2904 55/push-ebp - 2905 89/<- %ebp 4/r32/esp - 2906 # setup - 2907 (clear-stream _test-input-stream) - 2908 (clear-stream $_test-input-buffered-file->buffer) - 2909 (clear-stream _test-output-stream) - 2910 (clear-stream $_test-output-buffered-file->buffer) - 2911 (clear-stream _test-error-stream) - 2912 (clear-stream $_test-error-buffered-file->buffer) - 2913 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu - 2914 68/push 0/imm32 - 2915 68/push 0/imm32 - 2916 89/<- %edx 4/r32/esp - 2917 (tailor-exit-descriptor %edx 0x10) - 2918 # - 2919 (write _test-input-stream "fn foo {\n") - 2920 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2921 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2922 (write _test-input-stream " x <- increment\n") - 2923 (write _test-input-stream "}\n") - 2924 # convert - 2925 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2926 # registers except esp clobbered at this point - 2927 # restore ed - 2928 89/<- %edx 4/r32/esp - 2929 (flush _test-output-buffered-file) - 2930 (flush _test-error-buffered-file) - 2931 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 2937 # check output - 2938 (check-stream-equal _test-output-stream "" "F - test-read-clobbered-reg-var: output should be empty") - 2939 (check-next-stream-line-equal _test-error-stream "fn foo: register ecx reads var 'x' after writing var 'y'" "F - test-read-clobbered-reg-var: error message") - 2940 # check that stop(1) was called - 2941 (check-ints-equal *(edx+4) 2 "F - test-read-clobbered-reg-var: exit status") - 2942 # don't restore from ebp - 2943 81 0/subop/add %esp 8/imm32 - 2944 # . epilogue - 2945 5d/pop-to-ebp - 2946 c3/return - 2947 - 2948 test-overlapping-int-fp-registers: - 2949 # . prologue - 2950 55/push-ebp - 2951 89/<- %ebp 4/r32/esp - 2952 # setup - 2953 (clear-stream _test-input-stream) - 2954 (clear-stream $_test-input-buffered-file->buffer) - 2955 (clear-stream _test-output-stream) - 2956 (clear-stream $_test-output-buffered-file->buffer) - 2957 (clear-stream _test-error-stream) - 2958 (clear-stream $_test-error-buffered-file->buffer) - 2959 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu - 2960 68/push 0/imm32 - 2961 68/push 0/imm32 - 2962 89/<- %edx 4/r32/esp - 2963 (tailor-exit-descriptor %edx 0x10) - 2964 # - 2965 (write _test-input-stream "fn foo {\n") - 2966 (write _test-input-stream " var x/eax: int <- copy 3\n") - 2967 (write _test-input-stream " var y/xmm0: float <- convert x\n") - 2968 (write _test-input-stream " x <- increment\n") - 2969 (write _test-input-stream "}\n") - 2970 # convert - 2971 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2972 # registers except esp clobbered at this point - 2973 # restore ed - 2974 89/<- %edx 4/r32/esp - 2975 (flush _test-output-buffered-file) - 2976 (flush _test-error-buffered-file) - 2977 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 2983 # no errors - 2984 (check-next-stream-line-equal _test-error-stream "" "F - test-overlapping-int-fp-registers: error message") - 2985 # don't bother checking the generated code - 2986 # don't restore from ebp - 2987 81 0/subop/add %esp 8/imm32 - 2988 # . epilogue - 2989 5d/pop-to-ebp - 2990 c3/return - 2991 - 2992 test-convert-function-call: - 2993 # . prologue - 2994 55/push-ebp - 2995 89/<- %ebp 4/r32/esp - 2996 # setup - 2997 (clear-stream _test-input-stream) - 2998 (clear-stream $_test-input-buffered-file->buffer) - 2999 (clear-stream _test-output-stream) - 3000 (clear-stream $_test-output-buffered-file->buffer) - 3001 # - 3002 (write _test-input-stream "fn main -> _/ebx: int {\n") - 3003 (write _test-input-stream " var result/ebx: int <- foo\n") - 3004 (write _test-input-stream " return result\n") - 3005 (write _test-input-stream "}\n") - 3006 (write _test-input-stream "fn foo -> _/ebx: int {\n") - 3007 (write _test-input-stream " var result/ebx: int <- copy 3\n") - 3008 (write _test-input-stream " return result\n") - 3009 (write _test-input-stream "}\n") - 3010 # convert - 3011 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3012 (flush _test-output-buffered-file) - 3013 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3019 # check output - 3020 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call/0") - 3021 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/1") - 3022 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/2") - 3023 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/3") - 3024 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/4") - 3025 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call/5") - 3026 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-call-with-literal-arg/6") - 3027 (check-next-stream-line-equal _test-output-stream " (foo)" "F - test-convert-function-call/6") - 3028 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8") - 3029 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27") - 3030 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10") - 3031 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/7") - 3032 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call/8") - 3033 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/9") - 3034 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/10") - 3035 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/11") - 3036 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/12") - 3037 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call/13") - 3038 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/14") - 3039 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/15") - 3040 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/16") - 3041 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/17") - 3042 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call/18") - 3043 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-call-with-literal-arg/6") - 3044 (check-next-stream-line-equal _test-output-stream " bb/copy-to-ebx 3/imm32" "F - test-convert-function-call/19") - 3045 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8") - 3046 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27") - 3047 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-call-with-literal-arg/10") - 3048 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/20") - 3049 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call/21") - 3050 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/22") - 3051 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/23") - 3052 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/24") - 3053 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/25") - 3054 # . epilogue - 3055 89/<- %esp 5/r32/ebp - 3056 5d/pop-to-ebp - 3057 c3/return - 3058 - 3059 test-convert-function-call-with-inout-with-compound-type: - 3060 # . prologue - 3061 55/push-ebp - 3062 89/<- %ebp 4/r32/esp - 3063 # setup - 3064 (clear-stream _test-input-stream) - 3065 (clear-stream $_test-input-buffered-file->buffer) - 3066 (clear-stream _test-output-stream) - 3067 (clear-stream $_test-output-buffered-file->buffer) - 3068 # - 3069 (write _test-input-stream "fn f {\n") - 3070 (write _test-input-stream " var x: (addr int)\n") - 3071 (write _test-input-stream " g x\n") - 3072 (write _test-input-stream "}\n") - 3073 (write _test-input-stream "fn g a: (addr int) {\n") - 3074 (write _test-input-stream "}\n") - 3075 # convert - 3076 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3077 (flush _test-output-buffered-file) - 3078 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3084 # check output - 3085 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-inout-with-compound-type/0") - 3086 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-inout-with-compound-type/1") - 3087 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-inout-with-compound-type/2") - 3088 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-inout-with-compound-type/3") - 3089 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-inout-with-compound-type/4") - 3090 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-inout-with-compound-type/5") - 3091 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-inout-with-compound-type/6") - 3092 (check-next-stream-line-equal _test-output-stream " (g *(ebp+0xfffffffc))" "F - test-convert-function-call-with-inout-with-compound-type/7") - 3093 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-call-with-inout-with-compound-type/8") - 3094 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-inout-with-compound-type/9") - 3095 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-inout-with-compound-type/10") - 3096 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-inout-with-compound-type/11") - 3097 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-inout-with-compound-type/12") - 3098 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-inout-with-compound-type/13") - 3099 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-inout-with-compound-type/14") - 3100 (check-next-stream-line-equal _test-output-stream "g:" "F - test-convert-function-call-with-inout-with-compound-type/15") - 3101 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-inout-with-compound-type/16") - 3102 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-inout-with-compound-type/17") - 3103 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-inout-with-compound-type/18") - 3104 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-inout-with-compound-type/19") - 3105 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-inout-with-compound-type/20") - 3106 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-inout-with-compound-type/21") - 3107 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-inout-with-compound-type/22") - 3108 # . epilogue - 3109 89/<- %esp 5/r32/ebp - 3110 5d/pop-to-ebp - 3111 c3/return - 3112 - 3113 test-convert-function-call-with-inout-with-type-parameter: - 3114 # . prologue - 3115 55/push-ebp - 3116 89/<- %ebp 4/r32/esp - 3117 # setup - 3118 (clear-stream _test-input-stream) - 3119 (clear-stream $_test-input-buffered-file->buffer) - 3120 (clear-stream _test-output-stream) - 3121 (clear-stream $_test-output-buffered-file->buffer) - 3122 (clear-stream _test-error-stream) - 3123 (clear-stream $_test-error-buffered-file->buffer) - 3124 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3125 68/push 0/imm32 - 3126 68/push 0/imm32 - 3127 89/<- %edx 4/r32/esp - 3128 (tailor-exit-descriptor %edx 0x10) - 3129 # - 3130 (write _test-input-stream "fn f {\n") - 3131 (write _test-input-stream " var x: (addr int)\n") - 3132 (write _test-input-stream " g x\n") - 3133 (write _test-input-stream "}\n") - 3134 (write _test-input-stream "fn g a: (addr _) {\n") - 3135 (write _test-input-stream "}\n") - 3136 # convert - 3137 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3138 # registers except esp clobbered at this point - 3139 # restore ed - 3140 89/<- %edx 4/r32/esp - 3141 (flush _test-output-buffered-file) - 3142 (flush _test-error-buffered-file) - 3143 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3149 # no error; types matched - 3150 (check-stream-equal _test-error-stream "" "F - test-convert-function-call-with-inout-with-type-parameter: error stream should be empty") - 3151 # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below - 3152 # don't restore from ebp - 3153 81 0/subop/add %esp 8/imm32 - 3154 # . epilogue - 3155 5d/pop-to-ebp - 3156 c3/return - 3157 - 3158 test-convert-function-call-with-incorrect-inout-type: - 3159 # . prologue - 3160 55/push-ebp - 3161 89/<- %ebp 4/r32/esp - 3162 # setup - 3163 (clear-stream _test-input-stream) - 3164 (clear-stream $_test-input-buffered-file->buffer) - 3165 (clear-stream _test-output-stream) - 3166 (clear-stream $_test-output-buffered-file->buffer) - 3167 (clear-stream _test-error-stream) - 3168 (clear-stream $_test-error-buffered-file->buffer) - 3169 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3170 68/push 0/imm32 - 3171 68/push 0/imm32 - 3172 89/<- %edx 4/r32/esp - 3173 (tailor-exit-descriptor %edx 0x10) - 3174 # - 3175 (write _test-input-stream "fn f {\n") - 3176 (write _test-input-stream " var x: int\n") - 3177 (write _test-input-stream " g x\n") - 3178 (write _test-input-stream "}\n") - 3179 (write _test-input-stream "fn g a: foo {\n") - 3180 (write _test-input-stream "}\n") - 3181 # convert - 3182 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3183 # registers except esp clobbered at this point - 3184 # restore ed - 3185 89/<- %edx 4/r32/esp - 3186 (flush _test-output-buffered-file) - 3187 (flush _test-error-buffered-file) - 3188 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3194 # check output - 3195 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-inout-type: output should be empty") - 3196 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'x' is not right" "F - test-convert-function-call-with-incorrect-inout-type: error message") - 3197 # check that stop(1) was called - 3198 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-inout-type: exit status") - 3199 # don't restore from ebp - 3200 81 0/subop/add %esp 8/imm32 - 3201 5d/pop-to-ebp - 3202 c3/return - 3203 - 3204 test-convert-function-call-with-inout-with-incorrect-compound-type: - 3205 # . prologue - 3206 55/push-ebp - 3207 89/<- %ebp 4/r32/esp - 3208 # setup - 3209 (clear-stream _test-input-stream) - 3210 (clear-stream $_test-input-buffered-file->buffer) - 3211 (clear-stream _test-output-stream) - 3212 (clear-stream $_test-output-buffered-file->buffer) - 3213 (clear-stream _test-error-stream) - 3214 (clear-stream $_test-error-buffered-file->buffer) - 3215 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3216 68/push 0/imm32 - 3217 68/push 0/imm32 - 3218 89/<- %edx 4/r32/esp - 3219 (tailor-exit-descriptor %edx 0x10) - 3220 # - 3221 (write _test-input-stream "fn f {\n") - 3222 (write _test-input-stream " var x: (addr int)\n") - 3223 (write _test-input-stream " g x\n") - 3224 (write _test-input-stream "}\n") - 3225 (write _test-input-stream "fn g a: (addr bool) {\n") - 3226 (write _test-input-stream "}\n") - 3227 # convert - 3228 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3229 # registers except esp clobbered at this point - 3230 # restore ed - 3231 89/<- %edx 4/r32/esp - 3232 (flush _test-output-buffered-file) - 3233 (flush _test-error-buffered-file) - 3234 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3240 # check output - 3241 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-inout-with-incorrect-compound-type: output should be empty") - 3242 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'x' is not right" "F - test-convert-function-call-with-inout-with-incorrect-compound-type: error message") - 3243 # don't restore from ebp - 3244 81 0/subop/add %esp 8/imm32 - 3245 # . epilogue - 3246 5d/pop-to-ebp - 3247 c3/return - 3248 - 3249 test-convert-function-call-with-inout-with-multiple-type-parameters: - 3250 # . prologue - 3251 55/push-ebp - 3252 89/<- %ebp 4/r32/esp - 3253 # setup - 3254 (clear-stream _test-input-stream) - 3255 (clear-stream $_test-input-buffered-file->buffer) - 3256 (clear-stream _test-output-stream) - 3257 (clear-stream $_test-output-buffered-file->buffer) - 3258 (clear-stream _test-error-stream) - 3259 (clear-stream $_test-error-buffered-file->buffer) - 3260 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3261 68/push 0/imm32 - 3262 68/push 0/imm32 - 3263 89/<- %edx 4/r32/esp - 3264 (tailor-exit-descriptor %edx 0x10) - 3265 # - 3266 (write _test-input-stream "fn f {\n") - 3267 (write _test-input-stream " var x: (addr int)\n") - 3268 (write _test-input-stream " var y: (addr int)\n") - 3269 (write _test-input-stream " g x, y\n") - 3270 (write _test-input-stream "}\n") - 3271 (write _test-input-stream "fn g a: (addr _), b: (addr _) {\n") - 3272 (write _test-input-stream "}\n") - 3273 # convert - 3274 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3275 # registers except esp clobbered at this point - 3276 # restore ed - 3277 89/<- %edx 4/r32/esp - 3278 (flush _test-output-buffered-file) - 3279 (flush _test-error-buffered-file) - 3280 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3286 # no errors - 3287 (check-stream-equal _test-error-stream "" "F - test-convert-function-call-with-inout-with-multiple-type-parameters: error stream should be empty") - 3288 # don't bother checking the generated code - 3289 # don't restore from ebp - 3290 81 0/subop/add %esp 8/imm32 - 3291 # . epilogue - 3292 5d/pop-to-ebp - 3293 c3/return - 3294 - 3295 test-type-parameter-matches-rest-of-type: - 3296 # . prologue - 3297 55/push-ebp - 3298 89/<- %ebp 4/r32/esp - 3299 # setup - 3300 (clear-stream _test-input-stream) - 3301 (clear-stream $_test-input-buffered-file->buffer) - 3302 (clear-stream _test-output-stream) - 3303 (clear-stream $_test-output-buffered-file->buffer) - 3304 (clear-stream _test-error-stream) - 3305 (clear-stream $_test-error-buffered-file->buffer) - 3306 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3307 68/push 0/imm32 - 3308 68/push 0/imm32 - 3309 89/<- %edx 4/r32/esp - 3310 (tailor-exit-descriptor %edx 0x10) - 3311 # - 3312 (write _test-input-stream "fn f {\n") - 3313 (write _test-input-stream " var x: (addr array int)\n") - 3314 (write _test-input-stream " g x\n") - 3315 (write _test-input-stream "}\n") - 3316 (write _test-input-stream "fn g a: (addr _) {\n") - 3317 (write _test-input-stream "}\n") - 3318 # convert - 3319 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3320 # registers except esp clobbered at this point - 3321 # restore ed - 3322 89/<- %edx 4/r32/esp - 3323 (flush _test-output-buffered-file) - 3324 (flush _test-error-buffered-file) - 3325 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3331 # no errors - 3332 (check-stream-equal _test-error-stream "" "F - test-type-parameter-matches-rest-of-type: error stream should be empty") - 3333 # don't bother checking the generated code - 3334 # don't restore from ebp - 3335 81 0/subop/add %esp 8/imm32 - 3336 # . epilogue - 3337 5d/pop-to-ebp - 3338 c3/return - 3339 - 3340 test-convert-function-call-with-inout-with-incompatible-type-parameters: - 3341 # . prologue - 3342 55/push-ebp - 3343 89/<- %ebp 4/r32/esp - 3344 # setup - 3345 (clear-stream _test-input-stream) - 3346 (clear-stream $_test-input-buffered-file->buffer) - 3347 (clear-stream _test-output-stream) - 3348 (clear-stream $_test-output-buffered-file->buffer) - 3349 (clear-stream _test-error-stream) - 3350 (clear-stream $_test-error-buffered-file->buffer) - 3351 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3352 68/push 0/imm32 - 3353 68/push 0/imm32 - 3354 89/<- %edx 4/r32/esp - 3355 (tailor-exit-descriptor %edx 0x10) - 3356 # - 3357 (write _test-input-stream "fn f {\n") - 3358 (write _test-input-stream " var x: (addr int)\n") - 3359 (write _test-input-stream " var y: (addr boolean)\n") - 3360 (write _test-input-stream " g x, y\n") - 3361 (write _test-input-stream "}\n") - 3362 (write _test-input-stream "fn g a: (addr _T), b: (addr _T) {\n") - 3363 (write _test-input-stream "}\n") - 3364 # convert - 3365 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3366 # registers except esp clobbered at this point - 3367 # restore ed - 3368 89/<- %edx 4/r32/esp - 3369 (flush _test-output-buffered-file) - 3370 (flush _test-error-buffered-file) - 3371 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3377 # check output - 3378 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-inout-with-incompatible-type-parameters: output should be empty") - 3379 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'y' is not right" "F - test-convert-function-call-with-inout-with-incompatible-type-parameters: error message") - 3380 # don't restore from ebp - 3381 81 0/subop/add %esp 8/imm32 - 3382 # . epilogue - 3383 5d/pop-to-ebp - 3384 c3/return - 3385 - 3386 test-convert-function-call-with-too-few-inouts: - 3387 # . prologue - 3388 55/push-ebp - 3389 89/<- %ebp 4/r32/esp - 3390 # setup - 3391 (clear-stream _test-input-stream) - 3392 (clear-stream $_test-input-buffered-file->buffer) - 3393 (clear-stream _test-output-stream) - 3394 (clear-stream $_test-output-buffered-file->buffer) - 3395 (clear-stream _test-error-stream) - 3396 (clear-stream $_test-error-buffered-file->buffer) - 3397 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3398 68/push 0/imm32 - 3399 68/push 0/imm32 - 3400 89/<- %edx 4/r32/esp - 3401 (tailor-exit-descriptor %edx 0x10) - 3402 # - 3403 (write _test-input-stream "fn f {\n") - 3404 (write _test-input-stream " g\n") - 3405 (write _test-input-stream "}\n") - 3406 (write _test-input-stream "fn g a: int {\n") - 3407 (write _test-input-stream "}\n") - 3408 # convert - 3409 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3410 # registers except esp clobbered at this point - 3411 # restore ed - 3412 89/<- %edx 4/r32/esp - 3413 (flush _test-output-buffered-file) - 3414 (flush _test-error-buffered-file) - 3415 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3421 # check output - 3422 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-inouts: output should be empty") - 3423 (check-next-stream-line-equal _test-error-stream "fn f: call g: too few inouts" "F - test-convert-function-call-with-too-few-inouts: error message") - 3424 # check that stop(1) was called - 3425 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-inouts: exit status") - 3426 # don't restore from ebp - 3427 81 0/subop/add %esp 8/imm32 - 3428 5d/pop-to-ebp - 3429 c3/return - 3430 - 3431 test-convert-function-call-with-too-many-inouts: - 3432 # . prologue - 3433 55/push-ebp - 3434 89/<- %ebp 4/r32/esp - 3435 # setup - 3436 (clear-stream _test-input-stream) - 3437 (clear-stream $_test-input-buffered-file->buffer) - 3438 (clear-stream _test-output-stream) - 3439 (clear-stream $_test-output-buffered-file->buffer) - 3440 (clear-stream _test-error-stream) - 3441 (clear-stream $_test-error-buffered-file->buffer) - 3442 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3443 68/push 0/imm32 - 3444 68/push 0/imm32 - 3445 89/<- %edx 4/r32/esp - 3446 (tailor-exit-descriptor %edx 0x10) - 3447 # - 3448 (write _test-input-stream "fn f {\n") - 3449 (write _test-input-stream " var x: int\n") - 3450 (write _test-input-stream " g x\n") - 3451 (write _test-input-stream "}\n") - 3452 (write _test-input-stream "fn g {\n") - 3453 (write _test-input-stream "}\n") - 3454 # convert - 3455 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3456 # registers except esp clobbered at this point - 3457 # restore ed - 3458 89/<- %edx 4/r32/esp - 3459 (flush _test-output-buffered-file) - 3460 (flush _test-error-buffered-file) - 3461 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3467 # check output - 3468 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-inouts: output should be empty") - 3469 (check-next-stream-line-equal _test-error-stream "fn f: call g: too many inouts" "F - test-convert-function-call-with-too-many-inouts: error message") - 3470 # check that stop(1) was called - 3471 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-inouts: exit status") - 3472 # don't restore from ebp - 3473 81 0/subop/add %esp 8/imm32 - 3474 5d/pop-to-ebp - 3475 c3/return - 3476 - 3477 test-convert-function-call-with-incorrect-output-type: - 3478 # . prologue - 3479 55/push-ebp - 3480 89/<- %ebp 4/r32/esp - 3481 # setup - 3482 (clear-stream _test-input-stream) - 3483 (clear-stream $_test-input-buffered-file->buffer) - 3484 (clear-stream _test-output-stream) - 3485 (clear-stream $_test-output-buffered-file->buffer) - 3486 (clear-stream _test-error-stream) - 3487 (clear-stream $_test-error-buffered-file->buffer) - 3488 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3489 68/push 0/imm32 - 3490 68/push 0/imm32 - 3491 89/<- %edx 4/r32/esp - 3492 (tailor-exit-descriptor %edx 0x10) - 3493 # - 3494 (write _test-input-stream "fn f {\n") - 3495 (write _test-input-stream " var x/eax: int <- g\n") - 3496 (write _test-input-stream "}\n") - 3497 (write _test-input-stream "fn g -> _/eax: foo {\n") - 3498 (write _test-input-stream "}\n") - 3499 # convert - 3500 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3501 # registers except esp clobbered at this point - 3502 # restore ed - 3503 89/<- %edx 4/r32/esp - 3504 (flush _test-output-buffered-file) - 3505 (flush _test-error-buffered-file) - 3506 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3512 # check output - 3513 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-type: output should be empty") - 3514 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for output 'x' is not right" "F - test-convert-function-call-with-incorrect-output-type: error message") - 3515 # check that stop(1) was called - 3516 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-type: exit status") - 3517 # don't restore from ebp - 3518 81 0/subop/add %esp 8/imm32 - 3519 5d/pop-to-ebp - 3520 c3/return - 3521 - 3522 test-convert-function-call-with-too-few-outputs: - 3523 # . prologue - 3524 55/push-ebp - 3525 89/<- %ebp 4/r32/esp - 3526 # setup - 3527 (clear-stream _test-input-stream) - 3528 (clear-stream $_test-input-buffered-file->buffer) - 3529 (clear-stream _test-output-stream) - 3530 (clear-stream $_test-output-buffered-file->buffer) - 3531 (clear-stream _test-error-stream) - 3532 (clear-stream $_test-error-buffered-file->buffer) - 3533 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3534 68/push 0/imm32 - 3535 68/push 0/imm32 - 3536 89/<- %edx 4/r32/esp - 3537 (tailor-exit-descriptor %edx 0x10) - 3538 # - 3539 (write _test-input-stream "fn f {\n") - 3540 (write _test-input-stream " g\n") - 3541 (write _test-input-stream "}\n") - 3542 (write _test-input-stream "fn g -> _/eax: int {\n") - 3543 (write _test-input-stream "}\n") - 3544 # convert - 3545 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3546 # registers except esp clobbered at this point - 3547 # restore ed - 3548 89/<- %edx 4/r32/esp - 3549 (flush _test-output-buffered-file) - 3550 (flush _test-error-buffered-file) - 3551 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3557 # check output - 3558 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-outputs: output should be empty") - 3559 (check-next-stream-line-equal _test-error-stream "fn f: call g: too few outputs" "F - test-convert-function-call-with-too-few-outputs: error message") - 3560 # check that stop(1) was called - 3561 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-outputs: exit status") - 3562 # don't restore from ebp - 3563 81 0/subop/add %esp 8/imm32 - 3564 5d/pop-to-ebp - 3565 c3/return - 3566 - 3567 test-convert-function-call-with-too-many-outputs: - 3568 # . prologue - 3569 55/push-ebp - 3570 89/<- %ebp 4/r32/esp - 3571 # setup - 3572 (clear-stream _test-input-stream) - 3573 (clear-stream $_test-input-buffered-file->buffer) - 3574 (clear-stream _test-output-stream) - 3575 (clear-stream $_test-output-buffered-file->buffer) - 3576 (clear-stream _test-error-stream) - 3577 (clear-stream $_test-error-buffered-file->buffer) - 3578 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3579 68/push 0/imm32 - 3580 68/push 0/imm32 - 3581 89/<- %edx 4/r32/esp - 3582 (tailor-exit-descriptor %edx 0x10) - 3583 # - 3584 (write _test-input-stream "fn f {\n") - 3585 (write _test-input-stream " var x/eax: int <- g\n") - 3586 (write _test-input-stream "}\n") - 3587 (write _test-input-stream "fn g {\n") - 3588 (write _test-input-stream "}\n") - 3589 # convert - 3590 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3591 # registers except esp clobbered at this point - 3592 # restore ed - 3593 89/<- %edx 4/r32/esp - 3594 (flush _test-output-buffered-file) - 3595 (flush _test-error-buffered-file) - 3596 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3602 # check output - 3603 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-outputs: output should be empty") - 3604 (check-next-stream-line-equal _test-error-stream "fn f: call g: too many outputs" "F - test-convert-function-call-with-too-many-outputs: error message") - 3605 # check that stop(1) was called - 3606 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-outputs: exit status") - 3607 # don't restore from ebp - 3608 81 0/subop/add %esp 8/imm32 - 3609 5d/pop-to-ebp - 3610 c3/return - 3611 - 3612 test-convert-function-call-with-missing-output-register: - 3613 # . prologue - 3614 55/push-ebp - 3615 89/<- %ebp 4/r32/esp - 3616 # setup - 3617 (clear-stream _test-input-stream) - 3618 (clear-stream $_test-input-buffered-file->buffer) - 3619 (clear-stream _test-output-stream) - 3620 (clear-stream $_test-output-buffered-file->buffer) - 3621 (clear-stream _test-error-stream) - 3622 (clear-stream $_test-error-buffered-file->buffer) - 3623 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3624 68/push 0/imm32 - 3625 68/push 0/imm32 - 3626 89/<- %edx 4/r32/esp - 3627 (tailor-exit-descriptor %edx 0x10) - 3628 # - 3629 (write _test-input-stream "fn f {\n") - 3630 (write _test-input-stream " var x: int\n") - 3631 (write _test-input-stream " x <- g\n") - 3632 (write _test-input-stream "}\n") - 3633 (write _test-input-stream "fn g -> _/eax: int {\n") - 3634 (write _test-input-stream "}\n") - 3635 # convert - 3636 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3637 # registers except esp clobbered at this point - 3638 # restore ed - 3639 89/<- %edx 4/r32/esp - 3640 (flush _test-output-buffered-file) - 3641 (flush _test-error-buffered-file) - 3642 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3648 # check output - 3649 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-missing-output-register: output should be empty") - 3650 (check-next-stream-line-equal _test-error-stream "fn f: call g: output 'x' is not in a register" "F - test-convert-function-call-with-missing-output-register: error message") - 3651 # check that stop(1) was called - 3652 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-missing-output-register: exit status") - 3653 # don't restore from ebp - 3654 81 0/subop/add %esp 8/imm32 - 3655 5d/pop-to-ebp - 3656 c3/return - 3657 - 3658 test-convert-function-call-with-incorrect-output-register: - 3659 # . prologue - 3660 55/push-ebp - 3661 89/<- %ebp 4/r32/esp - 3662 # setup - 3663 (clear-stream _test-input-stream) - 3664 (clear-stream $_test-input-buffered-file->buffer) - 3665 (clear-stream _test-output-stream) - 3666 (clear-stream $_test-output-buffered-file->buffer) - 3667 (clear-stream _test-error-stream) - 3668 (clear-stream $_test-error-buffered-file->buffer) - 3669 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3670 68/push 0/imm32 - 3671 68/push 0/imm32 - 3672 89/<- %edx 4/r32/esp - 3673 (tailor-exit-descriptor %edx 0x10) - 3674 # - 3675 (write _test-input-stream "fn f {\n") - 3676 (write _test-input-stream " var x/ecx: int <- g\n") - 3677 (write _test-input-stream "}\n") - 3678 (write _test-input-stream "fn g -> _/eax: int {\n") - 3679 (write _test-input-stream "}\n") - 3680 # convert - 3681 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3682 # registers except esp clobbered at this point - 3683 # restore ed - 3684 89/<- %edx 4/r32/esp - 3685 (flush _test-output-buffered-file) - 3686 (flush _test-error-buffered-file) - 3687 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3693 # check output - 3694 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-register: output should be empty") - 3695 (check-next-stream-line-equal _test-error-stream "fn f: call g: register for output 'x' is not right" "F - test-convert-function-call-with-incorrect-output-register: error message") - 3696 # check that stop(1) was called - 3697 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-register: exit status") - 3698 # don't restore from ebp - 3699 81 0/subop/add %esp 8/imm32 - 3700 5d/pop-to-ebp - 3701 c3/return - 3702 - 3703 test-convert-function-with-local-var-dereferenced: - 3704 # . prologue - 3705 55/push-ebp - 3706 89/<- %ebp 4/r32/esp - 3707 # setup - 3708 (clear-stream _test-input-stream) - 3709 (clear-stream $_test-input-buffered-file->buffer) - 3710 (clear-stream _test-output-stream) - 3711 (clear-stream $_test-output-buffered-file->buffer) - 3712 # - 3713 (write _test-input-stream "fn foo {\n") - 3714 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") - 3715 (write _test-input-stream " increment *x\n") - 3716 (write _test-input-stream "}\n") - 3717 # convert - 3718 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3719 (flush _test-output-buffered-file) - 3720 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3726 # check output - 3727 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0") - 3728 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1") - 3729 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2") - 3730 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3") - 3731 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4") - 3732 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5") - 3733 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6") - 3734 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7") - 3735 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8") - 3736 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9") - 3737 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10") - 3738 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11") - 3739 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12") - 3740 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13") - 3741 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14") - 3742 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15") - 3743 # . epilogue - 3744 89/<- %esp 5/r32/ebp - 3745 5d/pop-to-ebp - 3746 c3/return - 3747 - 3748 test-dereference-of-var-on-stack: - 3749 # . prologue - 3750 55/push-ebp - 3751 89/<- %ebp 4/r32/esp - 3752 # setup - 3753 (clear-stream _test-input-stream) - 3754 (clear-stream $_test-input-buffered-file->buffer) - 3755 (clear-stream _test-output-stream) - 3756 (clear-stream $_test-output-buffered-file->buffer) - 3757 (clear-stream _test-error-stream) - 3758 (clear-stream $_test-error-buffered-file->buffer) - 3759 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3760 68/push 0/imm32 - 3761 68/push 0/imm32 - 3762 89/<- %edx 4/r32/esp - 3763 (tailor-exit-descriptor %edx 0x10) - 3764 # - 3765 (write _test-input-stream "fn foo {\n") - 3766 (write _test-input-stream " var x: (addr int)\n") - 3767 (write _test-input-stream " increment *x\n") - 3768 (write _test-input-stream "}\n") - 3769 # convert - 3770 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3771 # registers except esp clobbered at this point - 3772 # restore ed - 3773 89/<- %edx 4/r32/esp - 3774 (flush _test-output-buffered-file) - 3775 (flush _test-error-buffered-file) - 3776 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3782 # check output - 3783 (check-stream-equal _test-output-stream "" "F - test-dereference-of-var-on-stack: output should be empty") - 3784 (check-next-stream-line-equal _test-error-stream "fn foo: cannot dereference var 'x' on stack" "F - test-dereference-of-var-on-stack: error message") - 3785 # check that stop(1) was called - 3786 (check-ints-equal *(edx+4) 2 "F - test-dereference-of-var-on-stack: exit status") - 3787 # don't restore from ebp - 3788 81 0/subop/add %esp 8/imm32 - 3789 # . epilogue - 3790 5d/pop-to-ebp - 3791 c3/return - 3792 - 3793 test-convert-function-with-byte-operations: - 3794 # . prologue - 3795 55/push-ebp - 3796 89/<- %ebp 4/r32/esp - 3797 # setup - 3798 (clear-stream _test-input-stream) - 3799 (clear-stream $_test-input-buffered-file->buffer) - 3800 (clear-stream _test-output-stream) - 3801 (clear-stream $_test-output-buffered-file->buffer) - 3802 # - 3803 (write _test-input-stream "fn foo {\n") - 3804 (write _test-input-stream " var x/eax: byte <- copy 0\n") - 3805 (write _test-input-stream " var y/ecx: byte <- copy 0\n") - 3806 (write _test-input-stream " y <- copy-byte x\n") - 3807 (write _test-input-stream " var z/edx: (addr byte) <- copy 0\n") - 3808 (write _test-input-stream " y <- copy-byte *z\n") - 3809 (write _test-input-stream " copy-byte-to *z, x\n") - 3810 (write _test-input-stream "}\n") - 3811 # convert - 3812 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3813 (flush _test-output-buffered-file) - 3814 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3820 # check output - 3821 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-byte-operations/0") - 3822 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-byte-operations/1") - 3823 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-byte-operations/2") - 3824 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-byte-operations/3") - 3825 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-byte-operations/4") - 3826 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-byte-operations/5") - 3827 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-byte-operations/6") - 3828 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-byte-operations/7") - 3829 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-byte-operations/8") - 3830 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-byte-operations/9") - 3831 (check-next-stream-line-equal _test-output-stream " 8a/byte-> %eax 0x00000001/r32" "F - test-convert-function-with-byte-operations/10") - 3832 (check-next-stream-line-equal _test-output-stream " 81 4/subop/and %ecx 0xff/imm32" "F - test-convert-function-with-byte-operations/11") - 3833 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/12") - 3834 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/13") - 3835 (check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/14") - 3836 (check-next-stream-line-equal _test-output-stream " 81 4/subop/and %ecx 0xff/imm32" "F - test-convert-function-with-byte-operations/15") - 3837 (check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/16") - 3838 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/17") - 3839 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/18") - 3840 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/19") - 3841 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/20") - 3842 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/21") - 3843 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/22") - 3844 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/23") - 3845 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/24") - 3846 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/25") - 3847 # . epilogue - 3848 89/<- %esp 5/r32/ebp - 3849 5d/pop-to-ebp - 3850 c3/return - 3851 - 3852 # variables of type 'byte' are not allowed on the stack - 3853 test-byte-values-on-stack: - 3854 # . prologue - 3855 55/push-ebp - 3856 89/<- %ebp 4/r32/esp - 3857 # setup - 3858 (clear-stream _test-input-stream) - 3859 (clear-stream $_test-input-buffered-file->buffer) - 3860 (clear-stream _test-output-stream) - 3861 (clear-stream $_test-output-buffered-file->buffer) - 3862 (clear-stream _test-error-stream) - 3863 (clear-stream $_test-error-buffered-file->buffer) - 3864 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3865 68/push 0/imm32 - 3866 68/push 0/imm32 - 3867 89/<- %edx 4/r32/esp - 3868 (tailor-exit-descriptor %edx 0x10) - 3869 # - 3870 (write _test-input-stream "fn foo {\n") - 3871 (write _test-input-stream " var x: byte\n") - 3872 (write _test-input-stream "}\n") - 3873 # convert - 3874 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3875 # registers except esp clobbered at this point - 3876 # restore ed - 3877 89/<- %edx 4/r32/esp - 3878 (flush _test-output-buffered-file) - 3879 (flush _test-error-buffered-file) - 3880 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3886 # check output - 3887 (check-stream-equal _test-output-stream "" "F - test-byte-values-on-stack: output should be empty") - 3888 (check-next-stream-line-equal _test-error-stream "fn foo: var 'x' of type 'byte' cannot be on the stack" "F - test-byte-values-on-stack: error message") - 3889 # check that stop(1) was called - 3890 (check-ints-equal *(edx+4) 2 "F - test-byte-values-on-stack: exit status") - 3891 # don't restore from ebp - 3892 81 0/subop/add %esp 8/imm32 - 3893 # . epilogue - 3894 5d/pop-to-ebp - 3895 c3/return - 3896 - 3897 # variables of type 'byte' are not allowed in esi or edi - 3898 test-byte-values-in-unsupported-registers: - 3899 # . prologue - 3900 55/push-ebp - 3901 89/<- %ebp 4/r32/esp - 3902 # setup - 3903 (clear-stream _test-input-stream) - 3904 (clear-stream $_test-input-buffered-file->buffer) - 3905 (clear-stream _test-output-stream) - 3906 (clear-stream $_test-output-buffered-file->buffer) - 3907 (clear-stream _test-error-stream) - 3908 (clear-stream $_test-error-buffered-file->buffer) - 3909 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 3910 68/push 0/imm32 - 3911 68/push 0/imm32 - 3912 89/<- %edx 4/r32/esp - 3913 (tailor-exit-descriptor %edx 0x10) - 3914 # - 3915 (write _test-input-stream "fn foo {\n") - 3916 (write _test-input-stream " var x/esi: byte <- copy 0\n") - 3917 (write _test-input-stream "}\n") - 3918 # convert - 3919 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3920 # registers except esp clobbered at this point - 3921 # restore ed - 3922 89/<- %edx 4/r32/esp - 3923 (flush _test-output-buffered-file) - 3924 (flush _test-error-buffered-file) - 3925 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 3931 # check output - 3932 (check-stream-equal _test-output-stream "" "F - test-byte-values-in-unsupported-registers: output should be empty") - 3933 (check-next-stream-line-equal _test-error-stream "fn foo: var 'x' of type 'byte' cannot be in esi or edi" "F - test-byte-values-in-unsupported-registers: error message") - 3934 # check that stop(1) was called - 3935 (check-ints-equal *(edx+4) 2 "F - test-byte-values-in-unsupported-registers: exit status") - 3936 # don't restore from ebp - 3937 81 0/subop/add %esp 8/imm32 - 3938 # . epilogue - 3939 5d/pop-to-ebp - 3940 c3/return - 3941 - 3942 # variables of type 'byte' _can_ be function args. They then occupy 4 bytes. - 3943 test-copy-byte-var-from-fn-arg: - 3944 # . prologue - 3945 55/push-ebp - 3946 89/<- %ebp 4/r32/esp - 3947 # setup - 3948 (clear-stream _test-input-stream) - 3949 (clear-stream $_test-input-buffered-file->buffer) - 3950 (clear-stream _test-output-stream) - 3951 (clear-stream $_test-output-buffered-file->buffer) - 3952 # - 3953 (write _test-input-stream "fn foo x: byte, y: int {\n") - 3954 (write _test-input-stream " var a/eax: byte <- copy x\n") - 3955 (write _test-input-stream " var b/eax: int <- copy y\n") - 3956 (write _test-input-stream "}\n") - 3957 # convert - 3958 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3959 (flush _test-output-buffered-file) - 3960 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3966 # check output - 3967 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-copy-byte-from-fn-arg/0") - 3968 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-copy-byte-from-fn-arg/1") - 3969 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-copy-byte-from-fn-arg/2") - 3970 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-copy-byte-from-fn-arg/3") - 3971 (check-next-stream-line-equal _test-output-stream " {" "F - test-copy-byte-from-fn-arg/4") - 3972 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-copy-byte-from-fn-arg/5") - 3973 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-copy-byte-from-fn-arg/6") - 3974 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/7") - 3975 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x0000000c) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/8") - 3976 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-copy-byte-from-fn-arg/9") - 3977 (check-next-stream-line-equal _test-output-stream " }" "F - test-copy-byte-from-fn-arg/10") - 3978 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-copy-byte-from-fn-arg/11") - 3979 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-copy-byte-from-fn-arg/12") - 3980 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-copy-byte-from-fn-arg/13") - 3981 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-copy-byte-from-fn-arg/14") - 3982 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-copy-byte-from-fn-arg/15") - 3983 # . epilogue - 3984 89/<- %esp 5/r32/ebp - 3985 5d/pop-to-ebp - 3986 c3/return - 3987 - 3988 test-convert-compare-register-with-literal: - 3989 # . prologue - 3990 55/push-ebp - 3991 89/<- %ebp 4/r32/esp - 3992 # setup - 3993 (clear-stream _test-input-stream) - 3994 (clear-stream $_test-input-buffered-file->buffer) - 3995 (clear-stream _test-output-stream) - 3996 (clear-stream $_test-output-buffered-file->buffer) - 3997 # - 3998 (write _test-input-stream "fn foo {\n") - 3999 (write _test-input-stream " var x/ecx: int <- copy 0\n") - 4000 (write _test-input-stream " compare x, 0\n") - 4001 (write _test-input-stream "}\n") - 4002 # convert - 4003 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4004 (flush _test-output-buffered-file) - 4005 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4011 # check output - 4012 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0") - 4013 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1") - 4014 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2") - 4015 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3") - 4016 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4") - 4017 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5") - 4018 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") - 4019 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7") - 4020 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8") - 4021 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") - 4022 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10") - 4023 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11") - 4024 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12") - 4025 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13") - 4026 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14") - 4027 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15") - 4028 # . epilogue - 4029 89/<- %esp 5/r32/ebp - 4030 5d/pop-to-ebp - 4031 c3/return - 4032 - 4033 test-convert-compare-byte-with-literal: - 4034 # . prologue - 4035 55/push-ebp - 4036 89/<- %ebp 4/r32/esp - 4037 # setup - 4038 (clear-stream _test-input-stream) - 4039 (clear-stream $_test-input-buffered-file->buffer) - 4040 (clear-stream _test-output-stream) - 4041 (clear-stream $_test-output-buffered-file->buffer) - 4042 # - 4043 (write _test-input-stream "fn foo {\n") - 4044 (write _test-input-stream " var x/ecx: byte <- copy 0\n") - 4045 (write _test-input-stream " compare x, 0\n") - 4046 (write _test-input-stream "}\n") - 4047 # convert - 4048 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4049 (flush _test-output-buffered-file) - 4050 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4056 # no errors; output is identical to test-convert-compare-register-with-literal - 4057 # . epilogue - 4058 89/<- %esp 5/r32/ebp - 4059 5d/pop-to-ebp - 4060 c3/return - 4061 - 4062 test-unknown-variable: - 4063 # . prologue - 4064 55/push-ebp - 4065 89/<- %ebp 4/r32/esp - 4066 # setup - 4067 (clear-stream _test-input-stream) - 4068 (clear-stream $_test-input-buffered-file->buffer) - 4069 (clear-stream _test-output-stream) - 4070 (clear-stream $_test-output-buffered-file->buffer) - 4071 (clear-stream _test-error-stream) - 4072 (clear-stream $_test-error-buffered-file->buffer) - 4073 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 4074 68/push 0/imm32 - 4075 68/push 0/imm32 - 4076 89/<- %edx 4/r32/esp - 4077 (tailor-exit-descriptor %edx 0x10) - 4078 # - 4079 (write _test-input-stream "fn foo {\n") - 4080 (write _test-input-stream " compare x, 0\n") - 4081 (write _test-input-stream "}\n") - 4082 # convert - 4083 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 4084 # registers except esp clobbered at this point - 4085 # restore ed - 4086 89/<- %edx 4/r32/esp - 4087 (flush _test-output-buffered-file) - 4088 (flush _test-error-buffered-file) - 4089 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 4095 # check output - 4096 (check-stream-equal _test-output-stream "" "F - test-unknown-variable: output should be empty") - 4097 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable: error message") - 4098 # check that stop(1) was called - 4099 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable: exit status") - 4100 # don't restore from ebp - 4101 81 0/subop/add %esp 8/imm32 - 4102 # . epilogue - 4103 5d/pop-to-ebp - 4104 c3/return - 4105 - 4106 test-convert-function-with-local-var-in-block: - 4107 # . prologue - 4108 55/push-ebp - 4109 89/<- %ebp 4/r32/esp - 4110 # setup - 4111 (clear-stream _test-input-stream) - 4112 (clear-stream $_test-input-buffered-file->buffer) - 4113 (clear-stream _test-output-stream) - 4114 (clear-stream $_test-output-buffered-file->buffer) - 4115 # - 4116 (write _test-input-stream "fn foo {\n") - 4117 (write _test-input-stream " {\n") - 4118 (write _test-input-stream " var x: int\n") - 4119 (write _test-input-stream " increment x\n") - 4120 (write _test-input-stream " }\n") - 4121 (write _test-input-stream "}\n") - 4122 # convert - 4123 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4124 (flush _test-output-buffered-file) - 4125 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4131 # check output - 4132 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0") - 4133 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1") - 4134 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2") - 4135 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3") - 4136 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4") - 4137 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5") - 4138 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6") - 4139 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7") - 4140 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8") - 4141 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9") - 4142 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-block/10") - 4143 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11") - 4144 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12") - 4145 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13") - 4146 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14") - 4147 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15") - 4148 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16") - 4149 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17") - 4150 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18") - 4151 # . epilogue - 4152 89/<- %esp 5/r32/ebp - 4153 5d/pop-to-ebp - 4154 c3/return - 4155 - 4156 test-convert-function-with-local-var-in-mem-after-block: - 4157 # . prologue - 4158 55/push-ebp - 4159 89/<- %ebp 4/r32/esp - 4160 # setup - 4161 (clear-stream _test-input-stream) - 4162 (clear-stream $_test-input-buffered-file->buffer) - 4163 (clear-stream _test-output-stream) - 4164 (clear-stream $_test-output-buffered-file->buffer) - 4165 # - 4166 (write _test-input-stream "fn foo {\n") - 4167 (write _test-input-stream " {\n") - 4168 (write _test-input-stream " var y: int\n") - 4169 (write _test-input-stream " }\n") - 4170 (write _test-input-stream " var x: int\n") - 4171 (write _test-input-stream " increment x\n") - 4172 (write _test-input-stream "}\n") - 4173 # convert - 4174 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4175 (flush _test-output-buffered-file) - 4176 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4182 # check output - 4183 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem-after-block/0") - 4184 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem-after-block/1") - 4185 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem-after-block/2") - 4186 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem-after-block/3") - 4187 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem-after-block/4") - 4188 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem-after-block/5") - 4189 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem-after-block/6") - 4190 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-mem-after-block/7") - 4191 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/8") - 4192 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/9") - 4193 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem-after-block/10") - 4194 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-mem-after-block/11") - 4195 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/12") - 4196 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem-after-block/13") - 4197 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/14") - 4198 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem-after-block/15") - 4199 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem-after-block/16") - 4200 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem-after-block/17") - 4201 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem-after-block/18") - 4202 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem-after-block/19") - 4203 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem-after-block/20") - 4204 # . epilogue - 4205 89/<- %esp 5/r32/ebp - 4206 5d/pop-to-ebp - 4207 c3/return - 4208 - 4209 test-convert-function-with-local-var-in-named-block: - 4210 # . prologue - 4211 55/push-ebp - 4212 89/<- %ebp 4/r32/esp - 4213 # setup - 4214 (clear-stream _test-input-stream) - 4215 (clear-stream $_test-input-buffered-file->buffer) - 4216 (clear-stream _test-output-stream) - 4217 (clear-stream $_test-output-buffered-file->buffer) - 4218 # - 4219 (write _test-input-stream "fn foo {\n") - 4220 (write _test-input-stream " $bar: {\n") - 4221 (write _test-input-stream " var x: int\n") - 4222 (write _test-input-stream " increment x\n") - 4223 (write _test-input-stream " }\n") - 4224 (write _test-input-stream "}\n") - 4225 # convert - 4226 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4227 (flush _test-output-buffered-file) - 4228 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4234 # check output - 4235 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0") - 4236 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1") - 4237 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2") - 4238 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3") - 4239 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4") - 4240 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5") - 4241 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6") - 4242 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7") - 4243 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8") - 4244 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-named-block/9") - 4245 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-named-block/10") - 4246 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11") - 4247 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12") - 4248 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13") - 4249 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14") - 4250 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15") - 4251 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16") - 4252 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17") - 4253 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18") - 4254 # . epilogue - 4255 89/<- %esp 5/r32/ebp - 4256 5d/pop-to-ebp - 4257 c3/return - 4258 - 4259 test-unknown-variable-in-named-block: - 4260 # . prologue - 4261 55/push-ebp - 4262 89/<- %ebp 4/r32/esp - 4263 # setup - 4264 (clear-stream _test-input-stream) - 4265 (clear-stream $_test-input-buffered-file->buffer) - 4266 (clear-stream _test-output-stream) - 4267 (clear-stream $_test-output-buffered-file->buffer) - 4268 (clear-stream _test-error-stream) - 4269 (clear-stream $_test-error-buffered-file->buffer) - 4270 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 4271 68/push 0/imm32 - 4272 68/push 0/imm32 - 4273 89/<- %edx 4/r32/esp - 4274 (tailor-exit-descriptor %edx 0x10) - 4275 # - 4276 (write _test-input-stream "fn foo {\n") - 4277 (write _test-input-stream " $a: {\n") - 4278 (write _test-input-stream " compare x, 0\n") - 4279 (write _test-input-stream " }\n") - 4280 (write _test-input-stream "}\n") - 4281 # convert - 4282 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 4283 # registers except esp clobbered at this point - 4284 # restore ed - 4285 89/<- %edx 4/r32/esp - 4286 (flush _test-output-buffered-file) - 4287 (flush _test-error-buffered-file) - 4288 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 4294 # check output - 4295 (check-stream-equal _test-output-stream "" "F - test-unknown-variable-in-named-block: output should be empty") - 4296 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable-in-named-block: error message") - 4297 # check that stop(1) was called - 4298 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable-in-named-block: exit status") - 4299 # don't restore from ebp - 4300 81 0/subop/add %esp 8/imm32 - 4301 # . epilogue - 4302 5d/pop-to-ebp - 4303 c3/return - 4304 - 4305 test-always-shadow-outermost-reg-vars-in-function: - 4306 # . prologue - 4307 55/push-ebp - 4308 89/<- %ebp 4/r32/esp - 4309 # setup - 4310 (clear-stream _test-input-stream) - 4311 (clear-stream $_test-input-buffered-file->buffer) - 4312 (clear-stream _test-output-stream) - 4313 (clear-stream $_test-output-buffered-file->buffer) - 4314 # - 4315 (write _test-input-stream "fn foo {\n") - 4316 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 4317 (write _test-input-stream "}\n") - 4318 # convert - 4319 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4320 (flush _test-output-buffered-file) - 4321 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4327 # check output - 4328 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0") - 4329 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1") - 4330 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2") - 4331 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3") - 4332 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4") - 4333 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5") - 4334 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") - 4335 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8") - 4336 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") - 4337 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12") - 4338 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13") - 4339 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14") - 4340 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15") - 4341 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16") - 4342 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17") - 4343 # . epilogue - 4344 89/<- %esp 5/r32/ebp - 4345 5d/pop-to-ebp - 4346 c3/return - 4347 - 4348 test-shadow-local: - 4349 # . prologue - 4350 55/push-ebp - 4351 89/<- %ebp 4/r32/esp - 4352 # setup - 4353 (clear-stream _test-input-stream) - 4354 (clear-stream $_test-input-buffered-file->buffer) - 4355 (clear-stream _test-output-stream) - 4356 (clear-stream $_test-output-buffered-file->buffer) - 4357 # - 4358 (write _test-input-stream "fn foo {\n") - 4359 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 4360 (write _test-input-stream " {\n") - 4361 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 4362 (write _test-input-stream " }\n") - 4363 (write _test-input-stream " x <- increment\n") - 4364 (write _test-input-stream "}\n") - 4365 # convert - 4366 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4367 (flush _test-output-buffered-file) - 4368 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4374 # check output - 4375 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-local/0") - 4376 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-local/1") - 4377 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-local/2") - 4378 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-local/3") - 4379 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-local/4") - 4380 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-local/5") - 4381 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-local/6") - 4382 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-local/7") - 4383 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-local/8") - 4384 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-local/9") - 4385 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-local/10") - 4386 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-local/11") - 4387 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-local/12") - 4388 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-local/13") - 4389 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-local/14") - 4390 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-local/15") - 4391 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-local/16") - 4392 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-local/17") - 4393 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-local/18") - 4394 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-local/19") - 4395 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-local/20") - 4396 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-local/21") - 4397 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-local/22") - 4398 # . epilogue - 4399 89/<- %esp 5/r32/ebp - 4400 5d/pop-to-ebp - 4401 c3/return - 4402 - 4403 test-shadow-name: - 4404 # . prologue - 4405 55/push-ebp - 4406 89/<- %ebp 4/r32/esp - 4407 # setup - 4408 (clear-stream _test-input-stream) - 4409 (clear-stream $_test-input-buffered-file->buffer) - 4410 (clear-stream _test-output-stream) - 4411 (clear-stream $_test-output-buffered-file->buffer) - 4412 # - 4413 (write _test-input-stream "fn foo {\n") - 4414 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 4415 (write _test-input-stream " {\n") - 4416 (write _test-input-stream " var x/edx: int <- copy 4\n") - 4417 (write _test-input-stream " }\n") - 4418 (write _test-input-stream " x <- increment\n") - 4419 (write _test-input-stream "}\n") - 4420 # convert - 4421 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4422 (flush _test-output-buffered-file) - 4423 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4429 # check output - 4430 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name/0") - 4431 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name/1") - 4432 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name/2") - 4433 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name/3") - 4434 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/4") - 4435 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name/5") - 4436 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name/6") - 4437 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name/7") - 4438 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/8") - 4439 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name/9") - 4440 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name/10") - 4441 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name/11") - 4442 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name/12") - 4443 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/13") - 4444 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name/14") - 4445 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name/15") - 4446 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name/16") - 4447 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/17") - 4448 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name/18") - 4449 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name/19") - 4450 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name/20") - 4451 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name/21") - 4452 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name/22") - 4453 # . epilogue - 4454 89/<- %esp 5/r32/ebp - 4455 5d/pop-to-ebp - 4456 c3/return - 4457 - 4458 test-shadow-name-2: - 4459 # . prologue - 4460 55/push-ebp - 4461 89/<- %ebp 4/r32/esp - 4462 # setup - 4463 (clear-stream _test-input-stream) - 4464 (clear-stream $_test-input-buffered-file->buffer) - 4465 (clear-stream _test-output-stream) - 4466 (clear-stream $_test-output-buffered-file->buffer) - 4467 # - 4468 (write _test-input-stream "fn foo {\n") - 4469 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 4470 (write _test-input-stream " {\n") - 4471 (write _test-input-stream " var x/edx: int <- copy 4\n") - 4472 (write _test-input-stream " var y/ecx: int <- copy 5\n") - 4473 (write _test-input-stream " }\n") - 4474 (write _test-input-stream " x <- increment\n") - 4475 (write _test-input-stream "}\n") - 4476 # convert - 4477 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4478 (flush _test-output-buffered-file) - 4479 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4485 # check output - 4486 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name-2/0") - 4487 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name-2/1") - 4488 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name-2/2") - 4489 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name-2/3") - 4490 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/4") - 4491 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name-2/5") - 4492 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/6") - 4493 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name-2/7") - 4494 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/8") - 4495 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name-2/9") - 4496 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name-2/10") - 4497 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name-2/11") - 4498 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/12") - 4499 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 5/imm32" "F - test-shadow-name-2/13") - 4500 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/14") - 4501 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name-2/15") - 4502 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/16") - 4503 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name-2/17") - 4504 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name-2/18") - 4505 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/19") - 4506 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/20") - 4507 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name-2/21") - 4508 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name-2/22") - 4509 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name-2/23") - 4510 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name-2/24") - 4511 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name-2/25") - 4512 # . epilogue - 4513 89/<- %esp 5/r32/ebp - 4514 5d/pop-to-ebp - 4515 c3/return - 4516 - 4517 test-do-not-spill-same-register-in-block: - 4518 # . prologue - 4519 55/push-ebp - 4520 89/<- %ebp 4/r32/esp - 4521 # setup - 4522 (clear-stream _test-input-stream) - 4523 (clear-stream $_test-input-buffered-file->buffer) - 4524 (clear-stream _test-output-stream) - 4525 (clear-stream $_test-output-buffered-file->buffer) - 4526 # - 4527 (write _test-input-stream "fn foo {\n") - 4528 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 4529 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 4530 (write _test-input-stream " y <- increment\n") - 4531 (write _test-input-stream "}\n") - 4532 # convert - 4533 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4534 (flush _test-output-buffered-file) - 4535 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4541 # check output - 4542 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0") - 4543 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1") - 4544 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2") - 4545 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3") - 4546 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4") - 4547 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5") - 4548 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6") - 4549 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7") - 4550 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8") - 4551 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9") - 4552 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10") - 4553 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11") - 4554 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12") - 4555 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13") - 4556 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14") - 4557 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15") - 4558 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16") - 4559 # . epilogue - 4560 89/<- %esp 5/r32/ebp - 4561 5d/pop-to-ebp - 4562 c3/return - 4563 - 4564 test-spill-different-register-in-block: - 4565 # . prologue - 4566 55/push-ebp - 4567 89/<- %ebp 4/r32/esp - 4568 # setup - 4569 (clear-stream _test-input-stream) - 4570 (clear-stream $_test-input-buffered-file->buffer) - 4571 (clear-stream _test-output-stream) - 4572 (clear-stream $_test-output-buffered-file->buffer) - 4573 # - 4574 (write _test-input-stream "fn foo {\n") - 4575 (write _test-input-stream " var x/eax: int <- copy 3\n") - 4576 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 4577 (write _test-input-stream " y <- increment\n") - 4578 (write _test-input-stream "}\n") - 4579 # convert - 4580 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4581 (flush _test-output-buffered-file) - 4582 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4588 # check output - 4589 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0") - 4590 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1") - 4591 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2") - 4592 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3") - 4593 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4") - 4594 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5") - 4595 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6") - 4596 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7") - 4597 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8") - 4598 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9") - 4599 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10") - 4600 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11") - 4601 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12") - 4602 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13") - 4603 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14") - 4604 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15") - 4605 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16") - 4606 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17") - 4607 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18") - 4608 # . epilogue - 4609 89/<- %esp 5/r32/ebp - 4610 5d/pop-to-ebp - 4611 c3/return - 4612 - 4613 test-convert-function-with-branches-in-block: - 4614 # . prologue - 4615 55/push-ebp - 4616 89/<- %ebp 4/r32/esp - 4617 # setup - 4618 (clear-stream _test-input-stream) - 4619 (clear-stream $_test-input-buffered-file->buffer) - 4620 (clear-stream _test-output-stream) - 4621 (clear-stream $_test-output-buffered-file->buffer) - 4622 # - 4623 (write _test-input-stream "fn foo x: int {\n") - 4624 (write _test-input-stream " {\n") - 4625 (write _test-input-stream " break-if->=\n") - 4626 (write _test-input-stream " loop-if-addr<\n") - 4627 (write _test-input-stream " increment x\n") - 4628 (write _test-input-stream " loop\n") - 4629 (write _test-input-stream " }\n") - 4630 (write _test-input-stream "}\n") - 4631 # convert - 4632 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4633 (flush _test-output-buffered-file) - 4634 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4640 # check output - 4641 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") - 4642 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") - 4643 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") - 4644 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") - 4645 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") - 4646 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") - 4647 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") - 4648 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") - 4649 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") - 4650 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") - 4651 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") - 4652 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") - 4653 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") - 4654 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") - 4655 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") - 4656 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") - 4657 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") - 4658 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") - 4659 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") - 4660 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") - 4661 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") - 4662 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") - 4663 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") - 4664 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") - 4665 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") - 4666 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") - 4667 # . epilogue - 4668 89/<- %esp 5/r32/ebp - 4669 5d/pop-to-ebp - 4670 c3/return - 4671 - 4672 test-convert-function-with-branches-in-block-2: - 4673 # . prologue - 4674 55/push-ebp - 4675 89/<- %ebp 4/r32/esp - 4676 # setup - 4677 (clear-stream _test-input-stream) - 4678 (clear-stream $_test-input-buffered-file->buffer) - 4679 (clear-stream _test-output-stream) - 4680 (clear-stream $_test-output-buffered-file->buffer) - 4681 # - 4682 (write _test-input-stream "fn foo x: int {\n") - 4683 (write _test-input-stream " {\n") - 4684 (write _test-input-stream " break-if->=\n") - 4685 (write _test-input-stream " loop-if-float<\n") - 4686 (write _test-input-stream " increment x\n") - 4687 (write _test-input-stream " loop\n") - 4688 (write _test-input-stream " }\n") - 4689 (write _test-input-stream "}\n") - 4690 # convert - 4691 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4692 (flush _test-output-buffered-file) - 4693 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4699 # check output - 4700 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") - 4701 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") - 4702 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") - 4703 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") - 4704 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") - 4705 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") - 4706 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") - 4707 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") - 4708 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") - 4709 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") - 4710 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") - 4711 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") - 4712 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") - 4713 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") - 4714 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") - 4715 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") - 4716 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") - 4717 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") - 4718 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") - 4719 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") - 4720 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") - 4721 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") - 4722 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") - 4723 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") - 4724 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") - 4725 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") - 4726 # . epilogue - 4727 89/<- %esp 5/r32/ebp - 4728 5d/pop-to-ebp - 4729 c3/return - 4730 - 4731 test-convert-function-with-branches-in-named-block: - 4732 # . prologue - 4733 55/push-ebp - 4734 89/<- %ebp 4/r32/esp - 4735 # setup - 4736 (clear-stream _test-input-stream) - 4737 (clear-stream $_test-input-buffered-file->buffer) - 4738 (clear-stream _test-output-stream) - 4739 (clear-stream $_test-output-buffered-file->buffer) - 4740 # - 4741 (write _test-input-stream "fn foo x: int {\n") - 4742 (write _test-input-stream " $bar: {\n") - 4743 (write _test-input-stream " break-if->= $bar\n") - 4744 (write _test-input-stream " loop-if-addr< $bar\n") - 4745 (write _test-input-stream " increment x\n") - 4746 (write _test-input-stream " loop\n") - 4747 (write _test-input-stream " }\n") - 4748 (write _test-input-stream "}\n") - 4749 # convert - 4750 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4751 (flush _test-output-buffered-file) - 4752 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4758 # check output - 4759 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0") - 4760 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1") - 4761 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2") - 4762 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3") - 4763 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4") - 4764 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5") - 4765 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6") - 4766 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7") - 4767 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/8") - 4768 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-named-block/9") - 4769 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/10") - 4770 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/11") - 4771 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/12") - 4772 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-named-block/13") - 4773 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/14") - 4774 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/15") - 4775 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/16") - 4776 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/17") - 4777 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/18") - 4778 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/19") - 4779 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/20") - 4780 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/21") - 4781 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/22") - 4782 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/23") - 4783 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/24") - 4784 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/25") - 4785 # . epilogue - 4786 89/<- %esp 5/r32/ebp - 4787 5d/pop-to-ebp - 4788 c3/return - 4789 - 4790 test-convert-function-with-var-in-nested-block: - 4791 # . prologue - 4792 55/push-ebp - 4793 89/<- %ebp 4/r32/esp - 4794 # setup - 4795 (clear-stream _test-input-stream) - 4796 (clear-stream $_test-input-buffered-file->buffer) - 4797 (clear-stream _test-output-stream) - 4798 (clear-stream $_test-output-buffered-file->buffer) - 4799 # - 4800 (write _test-input-stream "fn foo x: int {\n") - 4801 (write _test-input-stream " {\n") - 4802 (write _test-input-stream " {\n") - 4803 (write _test-input-stream " var x: int\n") - 4804 (write _test-input-stream " increment x\n") - 4805 (write _test-input-stream " }\n") - 4806 (write _test-input-stream " }\n") - 4807 (write _test-input-stream "}\n") - 4808 # convert - 4809 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4810 (flush _test-output-buffered-file) - 4811 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4817 # check output - 4818 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0") - 4819 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1") - 4820 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2") - 4821 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3") - 4822 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4") - 4823 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5") - 4824 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6") - 4825 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7") - 4826 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8") - 4827 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9") - 4828 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10") - 4829 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11") - 4830 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-var-in-nested-block/12") - 4831 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13") - 4832 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14") - 4833 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15") - 4834 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16") - 4835 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17") - 4836 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18") - 4837 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19") - 4838 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20") - 4839 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21") - 4840 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22") - 4841 # . epilogue - 4842 89/<- %esp 5/r32/ebp - 4843 5d/pop-to-ebp - 4844 c3/return - 4845 - 4846 test-convert-function-with-multiple-vars-in-nested-blocks: - 4847 # . prologue - 4848 55/push-ebp - 4849 89/<- %ebp 4/r32/esp - 4850 # setup - 4851 (clear-stream _test-input-stream) - 4852 (clear-stream $_test-input-buffered-file->buffer) - 4853 (clear-stream _test-output-stream) - 4854 (clear-stream $_test-output-buffered-file->buffer) - 4855 # - 4856 (write _test-input-stream "fn foo x: int {\n") - 4857 (write _test-input-stream " {\n") - 4858 (write _test-input-stream " var x/eax: int <- copy 0\n") - 4859 (write _test-input-stream " {\n") - 4860 (write _test-input-stream " var y: int\n") - 4861 (write _test-input-stream " x <- add y\n") - 4862 (write _test-input-stream " }\n") - 4863 (write _test-input-stream " }\n") - 4864 (write _test-input-stream "}\n") - 4865 # convert - 4866 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4867 (flush _test-output-buffered-file) - 4868 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4874 # check output - 4875 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0") - 4876 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1") - 4877 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2") - 4878 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3") - 4879 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4") - 4880 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5") - 4881 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6") - 4882 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7") - 4883 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8") - 4884 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/9") - 4885 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10") - 4886 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11") - 4887 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12") - 4888 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/13") - 4889 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/14") - 4890 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15") - 4891 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16") - 4892 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17") - 4893 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18") - 4894 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19") - 4895 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20") - 4896 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21") - 4897 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22") - 4898 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23") - 4899 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24") - 4900 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25") - 4901 # . epilogue - 4902 89/<- %esp 5/r32/ebp - 4903 5d/pop-to-ebp - 4904 c3/return - 4905 - 4906 test-convert-function-with-branches-and-local-vars: - 4907 # A conditional 'break' after a 'var' in a block is converted into a - 4908 # nested block that performs all necessary cleanup before jumping. This - 4909 # results in some ugly code duplication. - 4910 # . prologue - 4911 55/push-ebp - 4912 89/<- %ebp 4/r32/esp - 4913 # setup - 4914 (clear-stream _test-input-stream) - 4915 (clear-stream $_test-input-buffered-file->buffer) - 4916 (clear-stream _test-output-stream) - 4917 (clear-stream $_test-output-buffered-file->buffer) - 4918 # - 4919 (write _test-input-stream "fn foo {\n") - 4920 (write _test-input-stream " {\n") - 4921 (write _test-input-stream " var x: int\n") - 4922 (write _test-input-stream " break-if->=\n") - 4923 (write _test-input-stream " increment x\n") - 4924 (write _test-input-stream " }\n") - 4925 (write _test-input-stream "}\n") - 4926 # convert - 4927 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4928 (flush _test-output-buffered-file) - 4929 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4935 # check output - 4936 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0") - 4937 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1") - 4938 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2") - 4939 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3") - 4940 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4") - 4941 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5") - 4942 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6") - 4943 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7") - 4944 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8") - 4945 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9") - 4946 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10") - 4947 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/11") - 4948 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12") - 4949 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13") - 4950 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14") - 4951 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/15") - 4952 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16") - 4953 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17") - 4954 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18") - 4955 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19") - 4956 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20") - 4957 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21") - 4958 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22") - 4959 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23") - 4960 # . epilogue - 4961 89/<- %esp 5/r32/ebp - 4962 5d/pop-to-ebp - 4963 c3/return - 4964 - 4965 test-convert-function-with-conditional-loops-and-local-vars: - 4966 # A conditional 'loop' after a 'var' in a block is converted into a nested - 4967 # block that performs all necessary cleanup before jumping. This results - 4968 # in some ugly code duplication. - 4969 # . prologue - 4970 55/push-ebp - 4971 89/<- %ebp 4/r32/esp - 4972 # setup - 4973 (clear-stream _test-input-stream) - 4974 (clear-stream $_test-input-buffered-file->buffer) - 4975 (clear-stream _test-output-stream) - 4976 (clear-stream $_test-output-buffered-file->buffer) - 4977 # - 4978 (write _test-input-stream "fn foo {\n") - 4979 (write _test-input-stream " {\n") - 4980 (write _test-input-stream " var x: int\n") - 4981 (write _test-input-stream " loop-if->=\n") - 4982 (write _test-input-stream " increment x\n") - 4983 (write _test-input-stream " }\n") - 4984 (write _test-input-stream "}\n") - 4985 # convert - 4986 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4987 (flush _test-output-buffered-file) - 4988 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4994 # check output - 4995 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0") - 4996 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1") - 4997 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2") - 4998 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3") - 4999 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4") - 5000 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5") - 5001 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6") - 5002 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7") - 5003 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8") - 5004 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9") - 5005 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/10") - 5006 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/11") - 5007 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/12") - 5008 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13") - 5009 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-conditional-loops-and-local-vars/14") - 5010 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/15") - 5011 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16") - 5012 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17") - 5013 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18") - 5014 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19") - 5015 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20") - 5016 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21") - 5017 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22") - 5018 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23") - 5019 # . epilogue - 5020 89/<- %esp 5/r32/ebp - 5021 5d/pop-to-ebp - 5022 c3/return - 5023 - 5024 test-convert-function-with-unconditional-loops-and-local-vars: - 5025 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the - 5026 # regular block cleanup. Any instructions after 'loop' are dead and - 5027 # therefore skipped. - 5028 # . prologue - 5029 55/push-ebp - 5030 89/<- %ebp 4/r32/esp - 5031 # setup - 5032 (clear-stream _test-input-stream) - 5033 (clear-stream $_test-input-buffered-file->buffer) - 5034 (clear-stream _test-output-stream) - 5035 (clear-stream $_test-output-buffered-file->buffer) - 5036 # - 5037 (write _test-input-stream "fn foo {\n") - 5038 (write _test-input-stream " {\n") - 5039 (write _test-input-stream " var x: int\n") - 5040 (write _test-input-stream " loop\n") - 5041 (write _test-input-stream " increment x\n") - 5042 (write _test-input-stream " }\n") - 5043 (write _test-input-stream "}\n") - 5044 # convert - 5045 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5046 (flush _test-output-buffered-file) - 5047 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5053 # check output - 5054 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0") - 5055 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1") - 5056 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2") - 5057 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3") - 5058 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4") - 5059 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5") - 5060 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6") - 5061 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7") - 5062 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8") - 5063 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/9") - 5064 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10") - 5065 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc) - 5066 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11") - 5067 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12") - 5068 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13") - 5069 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14") - 5070 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15") - 5071 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16") - 5072 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17") - 5073 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18") - 5074 # . epilogue - 5075 89/<- %esp 5/r32/ebp - 5076 5d/pop-to-ebp - 5077 c3/return - 5078 - 5079 test-convert-function-with-branches-and-loops-and-local-vars: - 5080 # . prologue - 5081 55/push-ebp - 5082 89/<- %ebp 4/r32/esp - 5083 # setup - 5084 (clear-stream _test-input-stream) - 5085 (clear-stream $_test-input-buffered-file->buffer) - 5086 (clear-stream _test-output-stream) - 5087 (clear-stream $_test-output-buffered-file->buffer) - 5088 # - 5089 (write _test-input-stream "fn foo {\n") - 5090 (write _test-input-stream " {\n") - 5091 (write _test-input-stream " var x: int\n") - 5092 (write _test-input-stream " break-if->=\n") - 5093 (write _test-input-stream " increment x\n") - 5094 (write _test-input-stream " loop\n") - 5095 (write _test-input-stream " }\n") - 5096 (write _test-input-stream "}\n") - 5097 # convert - 5098 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5099 (flush _test-output-buffered-file) - 5100 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5106 # check output - 5107 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0") - 5108 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1") - 5109 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2") - 5110 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-loops-and-local-vars/3") - 5111 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4") - 5112 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5") - 5113 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6") - 5114 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7") - 5115 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8") - 5116 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9") - 5117 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/10") - 5118 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/11") - 5119 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/12") - 5120 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13") - 5121 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-loops-and-local-vars/14") - 5122 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/15") - 5123 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16") - 5124 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17") - 5125 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18") - 5126 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19") - 5127 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20") - 5128 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21") - 5129 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/22") - 5130 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23") - 5131 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24") - 5132 # . epilogue - 5133 89/<- %esp 5/r32/ebp - 5134 5d/pop-to-ebp - 5135 c3/return - 5136 - 5137 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars: - 5138 # . prologue - 5139 55/push-ebp - 5140 89/<- %ebp 4/r32/esp - 5141 # setup - 5142 (clear-stream _test-input-stream) - 5143 (clear-stream $_test-input-buffered-file->buffer) - 5144 (clear-stream _test-output-stream) - 5145 (clear-stream $_test-output-buffered-file->buffer) - 5146 # - 5147 (write _test-input-stream "fn foo {\n") - 5148 (write _test-input-stream " a: {\n") - 5149 (write _test-input-stream " var x: int\n") - 5150 (write _test-input-stream " {\n") - 5151 (write _test-input-stream " var y: int\n") - 5152 (write _test-input-stream " break-if->= a\n") - 5153 (write _test-input-stream " increment x\n") - 5154 (write _test-input-stream " loop\n") - 5155 (write _test-input-stream " }\n") - 5156 (write _test-input-stream " }\n") - 5157 (write _test-input-stream "}\n") - 5158 # convert - 5159 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5160 (flush _test-output-buffered-file) - 5161 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5167 # check output - 5168 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0") - 5169 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1") - 5170 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2") - 5171 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/3") - 5172 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4") - 5173 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5") - 5174 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6") - 5175 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7") - 5176 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/8") - 5177 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9") - 5178 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10") - 5179 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/11") - 5180 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12") - 5181 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/13") - 5182 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/14") - 5183 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/15") - 5184 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/16") - 5185 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17") - 5186 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/18") - 5187 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/19") - 5188 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/20") - 5189 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21") - 5190 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22") - 5191 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/23") - 5192 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24") - 5193 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25") - 5194 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26") - 5195 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27") - 5196 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28") - 5197 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/29") - 5198 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/30") - 5199 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31") - 5200 # . epilogue - 5201 89/<- %esp 5/r32/ebp - 5202 5d/pop-to-ebp - 5203 c3/return - 5204 - 5205 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2: - 5206 # . prologue - 5207 55/push-ebp - 5208 89/<- %ebp 4/r32/esp - 5209 # setup - 5210 (clear-stream _test-input-stream) - 5211 (clear-stream $_test-input-buffered-file->buffer) - 5212 (clear-stream _test-output-stream) - 5213 (clear-stream $_test-output-buffered-file->buffer) - 5214 # non-local conditional branch from a block without a local variable, - 5215 # unwinding a local on the stack - 5216 (write _test-input-stream "fn foo {\n") - 5217 (write _test-input-stream " a: {\n") - 5218 (write _test-input-stream " var x: int\n") - 5219 (write _test-input-stream " {\n") - 5220 (write _test-input-stream " break-if->= a\n") - 5221 (write _test-input-stream " }\n") - 5222 (write _test-input-stream " }\n") - 5223 (write _test-input-stream "}\n") - 5224 # convert - 5225 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5226 (flush _test-output-buffered-file) - 5227 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5233 # check output - 5234 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0") - 5235 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1") - 5236 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/2") - 5237 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/3") - 5238 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4") - 5239 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/5") - 5240 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6") - 5241 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7") - 5242 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/8") - 5243 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9") - 5244 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/10") - 5245 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11") - 5246 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/12") - 5247 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/13") - 5248 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/14") - 5249 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15") - 5250 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16") - 5251 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/17") - 5252 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/18") - 5253 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19") - 5254 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20") - 5255 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21") - 5256 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/22") - 5257 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23") - 5258 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/24") - 5259 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/25") - 5260 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26") - 5261 # . epilogue - 5262 89/<- %esp 5/r32/ebp - 5263 5d/pop-to-ebp - 5264 c3/return - 5265 - 5266 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3: - 5267 # . prologue - 5268 55/push-ebp - 5269 89/<- %ebp 4/r32/esp - 5270 # setup - 5271 (clear-stream _test-input-stream) - 5272 (clear-stream $_test-input-buffered-file->buffer) - 5273 (clear-stream _test-output-stream) - 5274 (clear-stream $_test-output-buffered-file->buffer) - 5275 # non-local unconditional branch from a block without a local variable, - 5276 # unwinding a local on the stack - 5277 (write _test-input-stream "fn foo {\n") - 5278 (write _test-input-stream " a: {\n") - 5279 (write _test-input-stream " var x: int\n") - 5280 (write _test-input-stream " {\n") - 5281 (write _test-input-stream " break a\n") - 5282 (write _test-input-stream " }\n") - 5283 (write _test-input-stream " }\n") - 5284 (write _test-input-stream "}\n") - 5285 # convert - 5286 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5287 (flush _test-output-buffered-file) - 5288 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5294 # check output - 5295 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0") - 5296 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1") - 5297 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/2") - 5298 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/3") - 5299 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4") - 5300 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/5") - 5301 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6") - 5302 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7") - 5303 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/8") - 5304 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9") - 5305 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/10") - 5306 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/11") - 5307 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/12") - 5308 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14") - 5309 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/15") - 5310 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/16") - 5311 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17") - 5312 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18") - 5313 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19") - 5314 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/20") - 5315 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21") - 5316 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/22") - 5317 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/23") - 5318 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24") - 5319 # . epilogue - 5320 89/<- %esp 5/r32/ebp - 5321 5d/pop-to-ebp - 5322 c3/return - 5323 - 5324 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4: - 5325 # . prologue - 5326 55/push-ebp - 5327 89/<- %ebp 4/r32/esp - 5328 # setup - 5329 (clear-stream _test-input-stream) - 5330 (clear-stream $_test-input-buffered-file->buffer) - 5331 (clear-stream _test-output-stream) - 5332 (clear-stream $_test-output-buffered-file->buffer) - 5333 # - 5334 (write _test-input-stream "fn foo {\n") - 5335 (write _test-input-stream " a: {\n") - 5336 (write _test-input-stream " var x/esi: int <- copy 0\n") - 5337 (write _test-input-stream " {\n") - 5338 (write _test-input-stream " break a\n") - 5339 (write _test-input-stream " }\n") - 5340 (write _test-input-stream " }\n") - 5341 (write _test-input-stream "}\n") - 5342 # convert - 5343 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5344 (flush _test-output-buffered-file) - 5345 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5351 # check output - 5352 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0") - 5353 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1") - 5354 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/2") - 5355 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/3") - 5356 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4") - 5357 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/5") - 5358 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6") - 5359 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7") - 5360 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/8") - 5361 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/9") - 5362 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10") - 5363 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/11") - 5364 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/12") - 5365 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/13") - 5366 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/14") - 5367 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/15") - 5368 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/16") - 5369 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17") - 5370 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18") - 5371 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/19") - 5372 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/20") - 5373 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/21") - 5374 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/22") - 5375 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/23") - 5376 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24") - 5377 # . epilogue - 5378 89/<- %esp 5/r32/ebp - 5379 5d/pop-to-ebp - 5380 c3/return - 5381 - 5382 test-convert-function-with-nonlocal-unconditional-break-and-local-vars: - 5383 # . prologue - 5384 55/push-ebp - 5385 89/<- %ebp 4/r32/esp - 5386 # setup - 5387 (clear-stream _test-input-stream) - 5388 (clear-stream $_test-input-buffered-file->buffer) - 5389 (clear-stream _test-output-stream) - 5390 (clear-stream $_test-output-buffered-file->buffer) - 5391 # - 5392 (write _test-input-stream "fn foo {\n") - 5393 (write _test-input-stream " a: {\n") - 5394 (write _test-input-stream " var x: int\n") - 5395 (write _test-input-stream " {\n") - 5396 (write _test-input-stream " var y: int\n") - 5397 (write _test-input-stream " break a\n") - 5398 (write _test-input-stream " increment x\n") - 5399 (write _test-input-stream " }\n") - 5400 (write _test-input-stream " }\n") - 5401 (write _test-input-stream "}\n") - 5402 # convert - 5403 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5404 (flush _test-output-buffered-file) - 5405 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5411 # check output - 5412 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0") - 5413 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1") - 5414 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2") - 5415 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/3") - 5416 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4") - 5417 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5") - 5418 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6") - 5419 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7") - 5420 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8") - 5421 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9") - 5422 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10") - 5423 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11") - 5424 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/12") - 5425 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/13") - 5426 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/14") - 5427 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15") - 5428 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16") - 5429 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/17") - 5430 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18") - 5431 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19") - 5432 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20") - 5433 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21") - 5434 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22") - 5435 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/23") - 5436 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24") - 5437 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25") - 5438 # . epilogue - 5439 89/<- %esp 5/r32/ebp - 5440 5d/pop-to-ebp - 5441 c3/return - 5442 - 5443 test-convert-function-with-unconditional-break-and-local-vars: - 5444 # . prologue - 5445 55/push-ebp - 5446 89/<- %ebp 4/r32/esp - 5447 # setup - 5448 (clear-stream _test-input-stream) - 5449 (clear-stream $_test-input-buffered-file->buffer) - 5450 (clear-stream _test-output-stream) - 5451 (clear-stream $_test-output-buffered-file->buffer) - 5452 # - 5453 (write _test-input-stream "fn foo {\n") - 5454 (write _test-input-stream " {\n") - 5455 (write _test-input-stream " var x: int\n") - 5456 (write _test-input-stream " {\n") - 5457 (write _test-input-stream " var y: int\n") - 5458 (write _test-input-stream " break\n") - 5459 (write _test-input-stream " increment x\n") - 5460 (write _test-input-stream " }\n") - 5461 (write _test-input-stream " }\n") - 5462 (write _test-input-stream "}\n") - 5463 # convert - 5464 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5465 (flush _test-output-buffered-file) - 5466 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5472 # check output - 5473 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0") - 5474 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1") - 5475 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2") - 5476 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3") - 5477 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4") - 5478 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5") - 5479 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6") - 5480 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7") - 5481 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8") - 5482 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9") - 5483 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10") - 5484 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11") - 5485 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/12") - 5486 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13") - 5487 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14") - 5488 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/15") - 5489 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16") - 5490 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17") - 5491 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18") - 5492 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19") - 5493 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20") - 5494 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21") - 5495 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22") - 5496 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23") - 5497 # . epilogue - 5498 89/<- %esp 5/r32/ebp - 5499 5d/pop-to-ebp - 5500 c3/return - 5501 - 5502 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars: - 5503 # . prologue - 5504 55/push-ebp - 5505 89/<- %ebp 4/r32/esp - 5506 # setup - 5507 (clear-stream _test-input-stream) - 5508 (clear-stream $_test-input-buffered-file->buffer) - 5509 (clear-stream _test-output-stream) - 5510 (clear-stream $_test-output-buffered-file->buffer) - 5511 # - 5512 (write _test-input-stream "fn foo {\n") - 5513 (write _test-input-stream " a: {\n") - 5514 (write _test-input-stream " var x: int\n") - 5515 (write _test-input-stream " {\n") - 5516 (write _test-input-stream " var y: int\n") - 5517 (write _test-input-stream " loop a\n") - 5518 (write _test-input-stream " increment x\n") - 5519 (write _test-input-stream " }\n") - 5520 (write _test-input-stream " }\n") - 5521 (write _test-input-stream "}\n") - 5522 # convert - 5523 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5524 (flush _test-output-buffered-file) - 5525 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5531 # check output - 5532 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0") - 5533 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1") - 5534 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2") - 5535 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/3") - 5536 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4") - 5537 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5") - 5538 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6") - 5539 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7") - 5540 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8") - 5541 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9") - 5542 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10") - 5543 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11") - 5544 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/12") - 5545 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/13") - 5546 (check-next-stream-line-equal _test-output-stream " e9/jump a:loop/disp32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/14") - 5547 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15") - 5548 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16") - 5549 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/17") - 5550 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18") - 5551 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19") - 5552 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20") - 5553 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21") - 5554 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22") - 5555 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/23") - 5556 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24") - 5557 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25") - 5558 # . epilogue - 5559 89/<- %esp 5/r32/ebp - 5560 5d/pop-to-ebp - 5561 c3/return - 5562 - 5563 test-convert-function-with-local-array-var-in-mem: - 5564 # . prologue - 5565 55/push-ebp - 5566 89/<- %ebp 4/r32/esp - 5567 # setup - 5568 (clear-stream _test-input-stream) - 5569 (clear-stream $_test-input-buffered-file->buffer) - 5570 (clear-stream _test-output-stream) - 5571 (clear-stream $_test-output-buffered-file->buffer) - 5572 # - 5573 (write _test-input-stream "fn foo {\n") - 5574 (write _test-input-stream " var x: (array int 3)\n") - 5575 (write _test-input-stream "}\n") - 5576 # convert - 5577 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5578 (flush _test-output-buffered-file) - 5579 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5585 # check output - 5586 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0") - 5587 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1") - 5588 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2") - 5589 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3") - 5590 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4") - 5591 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5") - 5592 # define x - 5593 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7") - 5594 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8") - 5595 # reclaim x - 5596 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-function-with-local-array-var-in-mem/9") - 5597 # - 5598 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10") - 5599 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11") - 5600 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12") - 5601 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13") - 5602 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14") - 5603 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15") - 5604 # . epilogue - 5605 89/<- %esp 5/r32/ebp - 5606 5d/pop-to-ebp - 5607 c3/return - 5608 - 5609 test-array-size-in-hex: - 5610 # . prologue - 5611 55/push-ebp - 5612 89/<- %ebp 4/r32/esp - 5613 # setup - 5614 (clear-stream _test-input-stream) - 5615 (clear-stream $_test-input-buffered-file->buffer) - 5616 (clear-stream _test-output-stream) - 5617 (clear-stream $_test-output-buffered-file->buffer) - 5618 (clear-stream _test-error-stream) - 5619 (clear-stream $_test-error-buffered-file->buffer) - 5620 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5621 68/push 0/imm32 - 5622 68/push 0/imm32 - 5623 89/<- %edx 4/r32/esp - 5624 (tailor-exit-descriptor %edx 0x10) - 5625 # - 5626 (write _test-input-stream "fn foo {\n") - 5627 (write _test-input-stream " var x: (array int 10)\n") - 5628 (write _test-input-stream "}\n") - 5629 # convert - 5630 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5631 # registers except esp clobbered at this point - 5632 # restore ed - 5633 89/<- %edx 4/r32/esp - 5634 (flush _test-output-buffered-file) - 5635 (flush _test-error-buffered-file) - 5636 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5642 # check output - 5643 (check-stream-equal _test-output-stream "" "F - test-array-size-in-hex: output should be empty") - 5644 (check-next-stream-line-equal _test-error-stream "literal integers are always hex in Mu; start '10' with a '0x' to be unambiguous, converting it to hexadecimal as necessary." "F - test-array-size-in-hex: error message") - 5645 # check that stop(1) was called - 5646 (check-ints-equal *(edx+4) 2 "F - test-array-size-in-hex: exit status") - 5647 # don't restore from ebp - 5648 81 0/subop/add %esp 8/imm32 - 5649 # . epilogue - 5650 5d/pop-to-ebp - 5651 c3/return - 5652 - 5653 test-array-size-with-metadata: - 5654 # . prologue - 5655 55/push-ebp - 5656 89/<- %ebp 4/r32/esp - 5657 # setup - 5658 (clear-stream _test-input-stream) - 5659 (clear-stream $_test-input-buffered-file->buffer) - 5660 (clear-stream _test-output-stream) - 5661 (clear-stream $_test-output-buffered-file->buffer) - 5662 # - 5663 (write _test-input-stream "fn foo {\n") - 5664 (write _test-input-stream " var x: (array int 3/bar)\n") - 5665 (write _test-input-stream "}\n") - 5666 # convert - 5667 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5668 (flush _test-output-buffered-file) - 5669 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5675 # no errors - 5676 # . epilogue - 5677 89/<- %esp 5/r32/ebp - 5678 5d/pop-to-ebp - 5679 c3/return - 5680 - 5681 test-convert-function-with-populate: - 5682 # . prologue - 5683 55/push-ebp - 5684 89/<- %ebp 4/r32/esp - 5685 # setup - 5686 (clear-stream _test-input-stream) - 5687 (clear-stream $_test-input-buffered-file->buffer) - 5688 (clear-stream _test-output-stream) - 5689 (clear-stream $_test-output-buffered-file->buffer) - 5690 # - 5691 (write _test-input-stream "fn foo {\n") - 5692 (write _test-input-stream " var x/ecx: (addr handle array int) <- copy 0\n") - 5693 (write _test-input-stream " populate x, 7\n") - 5694 (write _test-input-stream "}\n") - 5695 # convert - 5696 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5697 (flush _test-output-buffered-file) - 5698 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5704 # check output - 5705 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-populate/0") - 5706 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-populate/1") - 5707 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-populate/2") - 5708 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-populate/3") - 5709 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-populate/4") - 5710 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-populate/5") - 5711 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-populate/6") - 5712 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-populate/7") - 5713 (check-next-stream-line-equal _test-output-stream " (allocate-array2 Heap 0x00000004 7 %ecx)" "F - test-convert-function-with-populate/8") # 4 = size-of(int) - 5714 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-populate/9") - 5715 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-populate/10") - 5716 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-populate/11") - 5717 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-populate/12") - 5718 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-populate/13") - 5719 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-populate/14") - 5720 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-populate/15") - 5721 # . epilogue - 5722 89/<- %esp 5/r32/ebp - 5723 5d/pop-to-ebp - 5724 c3/return - 5725 - 5726 # special-case for size(byte) when allocating array - 5727 test-convert-function-with-local-array-of-bytes-in-mem: - 5728 # . prologue - 5729 55/push-ebp - 5730 89/<- %ebp 4/r32/esp - 5731 # setup - 5732 (clear-stream _test-input-stream) - 5733 (clear-stream $_test-input-buffered-file->buffer) - 5734 (clear-stream _test-output-stream) - 5735 (clear-stream $_test-output-buffered-file->buffer) - 5736 # - 5737 (write _test-input-stream "fn foo {\n") - 5738 (write _test-input-stream " var x: (array byte 3)\n") - 5739 (write _test-input-stream "}\n") - 5740 # convert - 5741 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5742 (flush _test-output-buffered-file) - 5743 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5749 # check output - 5750 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-of-bytes-in-mem/0") - 5751 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-of-bytes-in-mem/1") - 5752 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/2") - 5753 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-of-bytes-in-mem/3") - 5754 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-of-bytes-in-mem/4") - 5755 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-of-bytes-in-mem/5") - 5756 # define x - 5757 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x00000003)" "F - test-convert-function-with-local-array-of-bytes-in-mem/7") - 5758 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/8") - 5759 # reclaim x - 5760 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000007/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/9") - 5761 # - 5762 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-of-bytes-in-mem/10") - 5763 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-of-bytes-in-mem/11") - 5764 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-of-bytes-in-mem/12") - 5765 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/13") - 5766 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/14") - 5767 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-of-bytes-in-mem/15") - 5768 # . epilogue - 5769 89/<- %esp 5/r32/ebp - 5770 5d/pop-to-ebp - 5771 c3/return - 5772 - 5773 test-convert-address: - 5774 # . prologue - 5775 55/push-ebp - 5776 89/<- %ebp 4/r32/esp - 5777 # setup - 5778 (clear-stream _test-input-stream) - 5779 (clear-stream $_test-input-buffered-file->buffer) - 5780 (clear-stream _test-output-stream) - 5781 (clear-stream $_test-output-buffered-file->buffer) - 5782 # - 5783 (write _test-input-stream "fn foo {\n") - 5784 (write _test-input-stream " var a: int\n") - 5785 (write _test-input-stream " var b/eax: (addr int) <- address a\n") - 5786 (write _test-input-stream "}\n") - 5787 # convert - 5788 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5789 (flush _test-output-buffered-file) - 5790 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5796 # check output - 5797 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0") - 5798 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1") - 5799 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2") - 5800 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3") - 5801 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4") - 5802 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5") - 5803 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6") - 5804 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7") - 5805 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8") - 5806 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9") - 5807 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10") - 5808 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11") - 5809 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12") - 5810 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13") - 5811 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14") - 5812 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15") - 5813 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16") - 5814 # . epilogue - 5815 89/<- %esp 5/r32/ebp - 5816 5d/pop-to-ebp - 5817 c3/return - 5818 - 5819 test-convert-floating-point-convert: - 5820 # . prologue - 5821 55/push-ebp - 5822 89/<- %ebp 4/r32/esp - 5823 # setup - 5824 (clear-stream _test-input-stream) - 5825 (clear-stream $_test-input-buffered-file->buffer) - 5826 (clear-stream _test-output-stream) - 5827 (clear-stream $_test-output-buffered-file->buffer) - 5828 # - 5829 (write _test-input-stream "fn foo {\n") - 5830 (write _test-input-stream " var a/eax: int <- copy 0\n") - 5831 (write _test-input-stream " var b/xmm1: float <- convert a\n") - 5832 (write _test-input-stream "}\n") - 5833 # convert - 5834 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5835 (flush _test-output-buffered-file) - 5836 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5842 # check output - 5843 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-floating-point-convert/0") - 5844 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-convert/1") - 5845 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-convert/2") - 5846 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-convert/3") - 5847 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-convert/4") - 5848 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-floating-point-convert/5") - 5849 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-convert/6") - 5850 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-convert/7") - 5851 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-convert/8") - 5852 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-convert/9") - 5853 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-floating-point-convert/10") - 5854 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-convert/11") - 5855 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-floating-point-convert/12") - 5856 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-convert/13") - 5857 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-convert/14") - 5858 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-floating-point-convert/15") - 5859 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-convert/16") - 5860 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-convert/17") - 5861 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-convert/18") - 5862 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-convert/19") - 5863 # . epilogue - 5864 89/<- %esp 5/r32/ebp - 5865 5d/pop-to-ebp - 5866 c3/return - 5867 - 5868 test-convert-floating-point-convert-2: - 5869 # . prologue - 5870 55/push-ebp - 5871 89/<- %ebp 4/r32/esp - 5872 # setup - 5873 (clear-stream _test-input-stream) - 5874 (clear-stream $_test-input-buffered-file->buffer) - 5875 (clear-stream _test-output-stream) - 5876 (clear-stream $_test-output-buffered-file->buffer) - 5877 # - 5878 (write _test-input-stream "fn foo {\n") - 5879 (write _test-input-stream " var a/eax: int <- copy 0\n") - 5880 (write _test-input-stream " var b/xmm1: float <- convert a\n") - 5881 (write _test-input-stream " a <- convert b\n") - 5882 (write _test-input-stream "}\n") - 5883 # convert - 5884 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5885 (flush _test-output-buffered-file) - 5886 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5892 # check output - 5893 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-floating-point-convert-2/0") - 5894 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-convert-2/1") - 5895 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-convert-2/2") - 5896 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-convert-2/3") - 5897 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-convert-2/4") - 5898 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-floating-point-convert-2/5") - 5899 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-convert-2/6") - 5900 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-convert-2/7") - 5901 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-convert-2/8") - 5902 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-convert-2/9") - 5903 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-floating-point-convert-2/10") - 5904 (check-next-stream-line-equal _test-output-stream " f3 0f 2d/convert-to-int %xmm1 0x00000000/r32" "F - test-convert-floating-point-convert-2/11") - 5905 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-convert-2/12") - 5906 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-floating-point-convert-2/13") - 5907 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-convert-2/14") - 5908 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-convert-2/15") - 5909 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-floating-point-convert-2/16") - 5910 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-convert-2/17") - 5911 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-convert-2/18") - 5912 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-convert-2/19") - 5913 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-convert-2/20") - 5914 # . epilogue - 5915 89/<- %esp 5/r32/ebp - 5916 5d/pop-to-ebp - 5917 c3/return - 5918 - 5919 test-convert-floating-point-operation: - 5920 # . prologue - 5921 55/push-ebp - 5922 89/<- %ebp 4/r32/esp - 5923 # setup - 5924 (clear-stream _test-input-stream) - 5925 (clear-stream $_test-input-buffered-file->buffer) - 5926 (clear-stream _test-output-stream) - 5927 (clear-stream $_test-output-buffered-file->buffer) - 5928 # - 5929 (write _test-input-stream "fn f {\n") - 5930 (write _test-input-stream " var m: float\n") - 5931 (write _test-input-stream " var x/xmm1: float <- copy m\n") - 5932 (write _test-input-stream " var y/xmm5: float <- copy m\n") - 5933 (write _test-input-stream " x <- copy y\n") - 5934 (write _test-input-stream " copy-to m, y\n") - 5935 (write _test-input-stream " x <- add y\n") - 5936 (write _test-input-stream " x <- add m\n") - 5937 (write _test-input-stream " x <- subtract y\n") - 5938 (write _test-input-stream " x <- subtract m\n") - 5939 (write _test-input-stream " x <- multiply y\n") - 5940 (write _test-input-stream " x <- multiply m\n") - 5941 (write _test-input-stream " x <- divide y\n") - 5942 (write _test-input-stream " x <- divide m\n") - 5943 (write _test-input-stream " x <- reciprocal y\n") - 5944 (write _test-input-stream " x <- reciprocal m\n") - 5945 (write _test-input-stream " x <- square-root y\n") - 5946 (write _test-input-stream " x <- square-root m\n") - 5947 (write _test-input-stream " x <- inverse-square-root y\n") - 5948 (write _test-input-stream " x <- inverse-square-root m\n") - 5949 (write _test-input-stream " x <- max y\n") - 5950 (write _test-input-stream " x <- max m\n") - 5951 (write _test-input-stream " x <- min y\n") - 5952 (write _test-input-stream " x <- min m\n") - 5953 (write _test-input-stream " compare x, y\n") - 5954 (write _test-input-stream " compare x, m\n") - 5955 (write _test-input-stream "}\n") - 5956 # convert - 5957 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5958 (flush _test-output-buffered-file) - 5959 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5965 # check output - 5966 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-floating-point-operation/0") - 5967 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-operation/1") - 5968 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-operation/2") - 5969 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-operation/3") - 5970 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-operation/4") - 5971 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-floating-point-operation/5") - 5972 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-floating-point-operation/6") - 5973 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-operation/7") - 5974 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-operation/8") - 5975 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/9") - 5976 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-operation/10") - 5977 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 5/x32" "F - test-convert-floating-point-operation/11") - 5978 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000005/x32" "F - test-convert-floating-point-operation/12") - 5979 (check-next-stream-line-equal _test-output-stream " f3 0f 11/copy %xmm1 0x00000005/x32" "F - test-convert-floating-point-operation/13") - 5980 (check-next-stream-line-equal _test-output-stream " f3 0f 11/copy *(ebp+0xfffffffc) 0x00000005/x32" "F - test-convert-floating-point-operation/14") - 5981 (check-next-stream-line-equal _test-output-stream " f3 0f 58/add %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/15") - 5982 (check-next-stream-line-equal _test-output-stream " f3 0f 58/add *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/16") - 5983 (check-next-stream-line-equal _test-output-stream " f3 0f 5c/subtract %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/17") - 5984 (check-next-stream-line-equal _test-output-stream " f3 0f 5c/subtract *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/18") - 5985 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/19") - 5986 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/20") - 5987 (check-next-stream-line-equal _test-output-stream " f3 0f 5e/divide %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/21") - 5988 (check-next-stream-line-equal _test-output-stream " f3 0f 5e/divide *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/22") - 5989 (check-next-stream-line-equal _test-output-stream " f3 0f 53/reciprocal %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/23") - 5990 (check-next-stream-line-equal _test-output-stream " f3 0f 53/reciprocal *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/24") - 5991 (check-next-stream-line-equal _test-output-stream " f3 0f 51/square-root %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/25") - 5992 (check-next-stream-line-equal _test-output-stream " f3 0f 51/square-root *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/26") - 5993 (check-next-stream-line-equal _test-output-stream " f3 0f 52/inverse-square-root %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/27") - 5994 (check-next-stream-line-equal _test-output-stream " f3 0f 52/inverse-square-root *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/28") - 5995 (check-next-stream-line-equal _test-output-stream " f3 0f 5f/max %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/29") - 5996 (check-next-stream-line-equal _test-output-stream " f3 0f 5f/max *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/30") - 5997 (check-next-stream-line-equal _test-output-stream " f3 0f 5d/min %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/31") - 5998 (check-next-stream-line-equal _test-output-stream " f3 0f 5d/min *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/32") - 5999 (check-next-stream-line-equal _test-output-stream " 0f 2f/compare %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/33") - 6000 (check-next-stream-line-equal _test-output-stream " 0f 2f/compare *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/34") - 6001 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 5/x32" "F - test-convert-floating-point-operation/35") - 6002 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-operation/36") - 6003 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-operation/37") - 6004 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-operation/38") - 6005 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-floating-point-operation/39") - 6006 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-operation/40") - 6007 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-floating-point-operation/41") - 6008 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-operation/42") - 6009 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-operation/43") - 6010 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-operation/44") - 6011 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-operation/45") - 6012 # . epilogue - 6013 89/<- %esp 5/r32/ebp - 6014 5d/pop-to-ebp - 6015 c3/return - 6016 - 6017 test-convert-floating-point-dereferenced: - 6018 # . prologue - 6019 55/push-ebp - 6020 89/<- %ebp 4/r32/esp - 6021 # setup - 6022 (clear-stream _test-input-stream) - 6023 (clear-stream $_test-input-buffered-file->buffer) - 6024 (clear-stream _test-output-stream) - 6025 (clear-stream $_test-output-buffered-file->buffer) - 6026 # - 6027 (write _test-input-stream "fn f {\n") - 6028 (write _test-input-stream " var m: float\n") - 6029 (write _test-input-stream " var x/xmm1: float <- copy m\n") - 6030 (write _test-input-stream " var y/eax: (addr float) <- copy 0\n") - 6031 (write _test-input-stream " x <- multiply *y\n") - 6032 (write _test-input-stream "}\n") - 6033 # convert - 6034 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6035 (flush _test-output-buffered-file) - 6036 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6042 # check output - 6043 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-floating-point-dereferenced/0") - 6044 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-dereferenced/1") - 6045 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-dereferenced/2") - 6046 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-dereferenced/3") - 6047 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-dereferenced/4") - 6048 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-floating-point-dereferenced/5") - 6049 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-floating-point-dereferenced/6") - 6050 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-dereferenced/7") - 6051 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-dereferenced/8") - 6052 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-dereferenced/9") - 6053 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-dereferenced/10") - 6054 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-dereferenced/11") - 6055 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply *eax 0x00000001/x32" "F - test-convert-floating-point-dereferenced/12") - 6056 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-dereferenced/13") - 6057 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-dereferenced/14") - 6058 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/15") - 6059 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-floating-point-dereferenced/16") - 6060 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-dereferenced/17") - 6061 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-floating-point-dereferenced/18") - 6062 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-dereferenced/19") - 6063 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-dereferenced/20") - 6064 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-dereferenced/21") - 6065 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-dereferenced/22") - 6066 # . epilogue - 6067 89/<- %esp 5/r32/ebp - 6068 5d/pop-to-ebp - 6069 c3/return - 6070 - 6071 test-convert-length-of-array: - 6072 # . prologue - 6073 55/push-ebp - 6074 89/<- %ebp 4/r32/esp - 6075 # setup - 6076 (clear-stream _test-input-stream) - 6077 (clear-stream $_test-input-buffered-file->buffer) - 6078 (clear-stream _test-output-stream) - 6079 (clear-stream $_test-output-buffered-file->buffer) - 6080 # - 6081 (write _test-input-stream "fn foo a: (addr array int) {\n") - 6082 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n") - 6083 (write _test-input-stream " var c/eax: int <- length b\n") - 6084 (write _test-input-stream "}\n") - 6085 # convert - 6086 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6087 (flush _test-output-buffered-file) - 6088 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6094 # check output - 6095 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0") - 6096 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1") - 6097 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2") - 6098 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3") - 6099 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4") - 6100 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") - 6101 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") - 6102 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") - 6103 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") - 6104 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9") - 6105 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") - 6106 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") - 6107 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") - 6108 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") - 6109 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") - 6110 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") - 6111 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") - 6112 # . epilogue - 6113 89/<- %esp 5/r32/ebp - 6114 5d/pop-to-ebp - 6115 c3/return - 6116 - 6117 # special-case for size(byte) when computing array length - 6118 test-convert-length-of-array-of-bytes: - 6119 # . prologue - 6120 55/push-ebp - 6121 89/<- %ebp 4/r32/esp - 6122 # setup - 6123 (clear-stream _test-input-stream) - 6124 (clear-stream $_test-input-buffered-file->buffer) - 6125 (clear-stream _test-output-stream) - 6126 (clear-stream $_test-output-buffered-file->buffer) - 6127 # - 6128 (write _test-input-stream "fn foo a: (addr array byte) {\n") - 6129 (write _test-input-stream " var b/eax: (addr array byte) <- copy a\n") - 6130 (write _test-input-stream " var c/eax: int <- length b\n") - 6131 (write _test-input-stream "}\n") - 6132 # convert - 6133 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6134 (flush _test-output-buffered-file) - 6135 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6141 # check output - 6142 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-bytes/0") - 6143 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-bytes/1") - 6144 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-bytes/2") - 6145 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-bytes/3") - 6146 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-bytes/4") - 6147 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-bytes/5") - 6148 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-bytes/6") - 6149 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/7") - 6150 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/8") - 6151 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-bytes/9") - 6152 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-bytes/10") - 6153 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-bytes/11") - 6154 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-bytes/12") - 6155 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-bytes/13") - 6156 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-bytes/14") - 6157 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-bytes/15") - 6158 # . epilogue - 6159 89/<- %esp 5/r32/ebp - 6160 5d/pop-to-ebp - 6161 c3/return - 6162 - 6163 test-convert-length-of-array-on-stack: - 6164 # . prologue - 6165 55/push-ebp - 6166 89/<- %ebp 4/r32/esp - 6167 # setup - 6168 (clear-stream _test-input-stream) - 6169 (clear-stream $_test-input-buffered-file->buffer) - 6170 (clear-stream _test-output-stream) - 6171 (clear-stream $_test-output-buffered-file->buffer) - 6172 # - 6173 (write _test-input-stream "fn foo {\n") - 6174 (write _test-input-stream " var a: (array int 3)\n") - 6175 (write _test-input-stream " var b/eax: int <- length a\n") - 6176 (write _test-input-stream "}\n") - 6177 # convert - 6178 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6179 (flush _test-output-buffered-file) - 6180 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6186 # check output - 6187 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0") - 6188 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1") - 6189 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2") - 6190 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3") - 6191 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4") - 6192 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5") - 6193 # define x - 6194 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6") - 6195 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") - 6196 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") - 6197 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") - 6198 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10") - 6199 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") - 6200 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") - 6201 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") - 6202 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") - 6203 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") - 6204 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") - 6205 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") - 6206 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") - 6207 # . epilogue - 6208 89/<- %esp 5/r32/ebp - 6209 5d/pop-to-ebp - 6210 c3/return - 6211 - 6212 test-reg-var-def-with-read-of-same-register: - 6213 # . prologue - 6214 55/push-ebp - 6215 89/<- %ebp 4/r32/esp - 6216 # setup - 6217 (clear-stream _test-input-stream) - 6218 (clear-stream $_test-input-buffered-file->buffer) - 6219 (clear-stream _test-output-stream) - 6220 (clear-stream $_test-output-buffered-file->buffer) - 6221 (clear-stream _test-error-stream) - 6222 (clear-stream $_test-error-buffered-file->buffer) - 6223 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu - 6224 68/push 0/imm32 - 6225 68/push 0/imm32 - 6226 89/<- %edx 4/r32/esp - 6227 (tailor-exit-descriptor %edx 0x10) - 6228 # - 6229 (write _test-input-stream "fn foo {\n") - 6230 (write _test-input-stream " var x/eax: int <- copy 3\n") - 6231 (write _test-input-stream " var y/eax: int <- add x\n") - 6232 (write _test-input-stream "}\n") - 6233 # convert - 6234 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6235 # registers except esp could be clobbered at this point (though they shouldn't be) - 6236 # restore ed - 6237 89/<- %edx 4/r32/esp - 6238 (flush _test-output-buffered-file) - 6239 (flush _test-error-buffered-file) - 6240 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6246 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6252 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty") - 6253 # check output - 6254 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0") - 6255 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1") - 6256 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2") - 6257 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3") - 6258 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4") - 6259 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5") - 6260 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6") - 6261 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-reg-var-def-with-read-of-same-register/7") - 6262 (check-next-stream-line-equal _test-output-stream " 01/add-to %eax 0x00000000/r32" "F - test-reg-var-def-with-read-of-same-register/8") - 6263 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/9") - 6264 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/10") - 6265 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/11") - 6266 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/12") - 6267 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/13") - 6268 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/14") - 6269 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/15") - 6270 # don't restore from ebp - 6271 81 0/subop/add %esp 8/imm32 - 6272 # . epilogue - 6273 5d/pop-to-ebp - 6274 c3/return - 6275 - 6276 test-convert-index-into-array: - 6277 # . prologue - 6278 55/push-ebp - 6279 89/<- %ebp 4/r32/esp - 6280 # setup - 6281 (clear-stream _test-input-stream) - 6282 (clear-stream $_test-input-buffered-file->buffer) - 6283 (clear-stream _test-output-stream) - 6284 (clear-stream $_test-output-buffered-file->buffer) - 6285 # - 6286 (write _test-input-stream "fn foo {\n") - 6287 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 6288 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 6289 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 6290 (write _test-input-stream "}\n") - 6291 # convert - 6292 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6293 (flush _test-output-buffered-file) - 6294 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6300 # check output - 6301 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") - 6302 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") - 6303 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") - 6304 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") - 6305 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") - 6306 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") - 6307 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") - 6308 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") - 6309 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") - 6310 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") - 6311 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000004 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array/10") - 6312 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array/11") - 6313 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array/12") - 6314 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/13") - 6315 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/14") - 6316 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/15") - 6317 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/16") - 6318 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/17") - 6319 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/18") - 6320 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/19") - 6321 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/20") - 6322 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/21") - 6323 # . epilogue - 6324 89/<- %esp 5/r32/ebp - 6325 5d/pop-to-ebp - 6326 c3/return - 6327 - 6328 test-convert-index-into-array-of-bytes: - 6329 # . prologue - 6330 55/push-ebp - 6331 89/<- %ebp 4/r32/esp - 6332 # setup - 6333 (clear-stream _test-input-stream) - 6334 (clear-stream $_test-input-buffered-file->buffer) - 6335 (clear-stream _test-output-stream) - 6336 (clear-stream $_test-output-buffered-file->buffer) - 6337 # - 6338 (write _test-input-stream "fn foo {\n") - 6339 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 6340 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 6341 (write _test-input-stream " var x/eax: (addr byte) <- index arr, idx\n") - 6342 (write _test-input-stream "}\n") - 6343 # convert - 6344 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6345 (flush _test-output-buffered-file) - 6346 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6352 # check output - 6353 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes/0") - 6354 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1") - 6355 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2") - 6356 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3") - 6357 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4") - 6358 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5") - 6359 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6") - 6360 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7") - 6361 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8") - 6362 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9") - 6363 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000001 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes/10") - 6364 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes/11") - 6365 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes/12") - 6366 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000000 + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes/13") - 6367 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/14") - 6368 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/15") - 6369 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/16") - 6370 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/17") - 6371 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/18") - 6372 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/19") - 6373 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/20") - 6374 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/21") - 6375 # . epilogue - 6376 89/<- %esp 5/r32/ebp - 6377 5d/pop-to-ebp - 6378 c3/return - 6379 - 6380 test-convert-index-into-array-with-literal: - 6381 # . prologue - 6382 55/push-ebp - 6383 89/<- %ebp 4/r32/esp - 6384 # setup - 6385 (clear-stream _test-input-stream) - 6386 (clear-stream $_test-input-buffered-file->buffer) - 6387 (clear-stream _test-output-stream) - 6388 (clear-stream $_test-output-buffered-file->buffer) - 6389 # - 6390 (write _test-input-stream "fn foo {\n") - 6391 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 6392 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 6393 (write _test-input-stream "}\n") - 6394 # convert - 6395 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6396 (flush _test-output-buffered-file) - 6397 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6403 # check output - 6404 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") - 6405 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") - 6406 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") - 6407 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") - 6408 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") - 6409 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") - 6410 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") - 6411 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") - 6412 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000004 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-with-literal/8") - 6413 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-with-literal/9") - 6414 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-with-literal/10") - 6415 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 - 6416 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/11") - 6417 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/12") - 6418 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/13") - 6419 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/14") - 6420 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/15") - 6421 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/16") - 6422 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/17") - 6423 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/18") - 6424 # . epilogue - 6425 89/<- %esp 5/r32/ebp - 6426 5d/pop-to-ebp - 6427 c3/return - 6428 - 6429 test-convert-index-into-array-of-bytes-with-literal: - 6430 # . prologue - 6431 55/push-ebp - 6432 89/<- %ebp 4/r32/esp - 6433 # setup - 6434 (clear-stream _test-input-stream) - 6435 (clear-stream $_test-input-buffered-file->buffer) - 6436 (clear-stream _test-output-stream) - 6437 (clear-stream $_test-output-buffered-file->buffer) - 6438 # - 6439 (write _test-input-stream "fn foo {\n") - 6440 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 6441 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") - 6442 (write _test-input-stream "}\n") - 6443 # convert - 6444 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6445 (flush _test-output-buffered-file) - 6446 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6452 # check output - 6453 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0") - 6454 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1") - 6455 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2") - 6456 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3") - 6457 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4") - 6458 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5") - 6459 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6") - 6460 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-with-literal/7") - 6461 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000001 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-with-literal/8") - 6462 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-with-literal/9") - 6463 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-with-literal/10") - 6464 # 2 * 1 byte/elem + 4 bytes for size = offset 6 - 6465 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000006) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-with-literal/11") - 6466 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/12") - 6467 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/13") - 6468 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/14") - 6469 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/15") - 6470 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/16") - 6471 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/17") - 6472 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/18") - 6473 # . epilogue - 6474 89/<- %esp 5/r32/ebp - 6475 5d/pop-to-ebp - 6476 c3/return - 6477 - 6478 test-convert-index-into-array-on-stack: - 6479 # . prologue - 6480 55/push-ebp - 6481 89/<- %ebp 4/r32/esp - 6482 # setup - 6483 (clear-stream _test-input-stream) - 6484 (clear-stream $_test-input-buffered-file->buffer) - 6485 (clear-stream _test-output-stream) - 6486 (clear-stream $_test-output-buffered-file->buffer) - 6487 # - 6488 (write _test-input-stream "fn foo {\n") - 6489 (write _test-input-stream " var arr: (array int 3)\n") - 6490 (write _test-input-stream " var idx/eax: int <- copy 2\n") - 6491 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 6492 (write _test-input-stream "}\n") - 6493 # convert - 6494 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6495 (flush _test-output-buffered-file) - 6496 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6502 # check output - 6503 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") - 6504 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") - 6505 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") - 6506 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") - 6507 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") - 6508 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") - 6509 # var arr - 6510 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") - 6511 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") - 6512 # var idx - 6513 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") - 6514 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") - 6515 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %eax 0x00000004 *(ebp+0xfffffff0) \"foo\" \"arr\")" "F - test-convert-index-into-array-on-stack/10") - 6516 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc - 6517 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + eax<<0x00000002 + 0xfffffff4) 0x00000000/r32" "F - test-convert-index-into-array-on-stack/11") - 6518 # reclaim idx - 6519 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/12") - 6520 # reclaim arr - 6521 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/13") - 6522 # - 6523 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/14") - 6524 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/15") - 6525 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/16") - 6526 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/17") - 6527 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/18") - 6528 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/19") - 6529 # . epilogue - 6530 89/<- %esp 5/r32/ebp - 6531 5d/pop-to-ebp - 6532 c3/return - 6533 - 6534 test-convert-index-into-array-on-stack-with-literal: - 6535 # . prologue - 6536 55/push-ebp - 6537 89/<- %ebp 4/r32/esp - 6538 # setup - 6539 (clear-stream _test-input-stream) - 6540 (clear-stream $_test-input-buffered-file->buffer) - 6541 (clear-stream _test-output-stream) - 6542 (clear-stream $_test-output-buffered-file->buffer) - 6543 # - 6544 (write _test-input-stream "fn foo {\n") - 6545 (write _test-input-stream " var arr: (array int 3)\n") - 6546 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 6547 (write _test-input-stream "}\n") - 6548 # convert - 6549 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6550 (flush _test-output-buffered-file) - 6551 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6557 # check output - 6558 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") - 6559 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") - 6560 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") - 6561 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") - 6562 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") - 6563 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") - 6564 # var arr - 6565 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") - 6566 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") - 6567 # var x - 6568 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") - 6569 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000004 *(ebp+0xfffffff0) \"foo\" \"arr\")" "F - test-convert-index-into-array-on-stack-with-literal/9") - 6570 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 - 6571 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xfffffffc) 0x00000000/r32" "F - test-convert-index-into-array-on-stack-with-literal/10") - 6572 # reclaim x - 6573 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/11") - 6574 # reclaim arr - 6575 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack-with-literal/12") - 6576 # - 6577 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/13") - 6578 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/14") - 6579 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/15") - 6580 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") - 6581 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/17") - 6582 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/18") - 6583 # . epilogue - 6584 89/<- %esp 5/r32/ebp - 6585 5d/pop-to-ebp - 6586 c3/return - 6587 - 6588 test-convert-index-into-array-of-bytes-on-stack-with-literal: - 6589 # . prologue - 6590 55/push-ebp - 6591 89/<- %ebp 4/r32/esp - 6592 # setup - 6593 (clear-stream _test-input-stream) - 6594 (clear-stream $_test-input-buffered-file->buffer) - 6595 (clear-stream _test-output-stream) - 6596 (clear-stream $_test-output-buffered-file->buffer) - 6597 # - 6598 (write _test-input-stream "fn foo {\n") - 6599 (write _test-input-stream " var arr: (array byte 3)\n") - 6600 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") - 6601 (write _test-input-stream "}\n") - 6602 # convert - 6603 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6604 (flush _test-output-buffered-file) - 6605 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6611 # check output - 6612 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0") - 6613 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1") - 6614 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2") - 6615 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/3") - 6616 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4") - 6617 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5") - 6618 # var arr - 6619 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x00000003)" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/6") - 6620 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/7") - 6621 # var x - 6622 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/8") - 6623 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000001 *(ebp+0xfffffff9) \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/9") - 6624 # x is at (ebp-7) + 4 + 2 = ebp-1 - 6625 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xffffffff) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/10") - 6626 # reclaim x - 6627 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/11") - 6628 # reclaim arr - 6629 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000007/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12") - 6630 # - 6631 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13") - 6632 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14") - 6633 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/15") - 6634 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/16") - 6635 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17") - 6636 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/18") - 6637 # . epilogue - 6638 89/<- %esp 5/r32/ebp - 6639 5d/pop-to-ebp - 6640 c3/return - 6641 - 6642 test-convert-index-into-array-using-offset: - 6643 # . prologue - 6644 55/push-ebp - 6645 89/<- %ebp 4/r32/esp - 6646 # setup - 6647 (clear-stream _test-input-stream) - 6648 (clear-stream $_test-input-buffered-file->buffer) - 6649 (clear-stream _test-output-stream) - 6650 (clear-stream $_test-output-buffered-file->buffer) - 6651 # - 6652 (write _test-input-stream "fn foo {\n") - 6653 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 6654 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 6655 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 6656 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 6657 (write _test-input-stream "}\n") - 6658 # convert - 6659 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6660 (flush _test-output-buffered-file) - 6661 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6667 # check output - 6668 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") - 6669 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") - 6670 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") - 6671 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") - 6672 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") - 6673 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") - 6674 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") - 6675 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") - 6676 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") - 6677 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") - 6678 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") - 6679 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-using-offset/11") - 6680 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-using-offset/12") - 6681 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-using-offset/13") - 6682 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/15") - 6683 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/16") - 6684 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/17") - 6685 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/18") - 6686 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/19") - 6687 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/20") - 6688 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/21") - 6689 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/22") - 6690 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/23") - 6691 # . epilogue - 6692 89/<- %esp 5/r32/ebp - 6693 5d/pop-to-ebp - 6694 c3/return - 6695 - 6696 test-convert-index-into-array-of-bytes-using-offset: - 6697 # . prologue - 6698 55/push-ebp - 6699 89/<- %ebp 4/r32/esp - 6700 # setup - 6701 (clear-stream _test-input-stream) - 6702 (clear-stream $_test-input-buffered-file->buffer) - 6703 (clear-stream _test-output-stream) - 6704 (clear-stream $_test-output-buffered-file->buffer) - 6705 # - 6706 (write _test-input-stream "fn foo {\n") - 6707 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 6708 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 6709 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") - 6710 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") - 6711 (write _test-input-stream "}\n") - 6712 # convert - 6713 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6714 (flush _test-output-buffered-file) - 6715 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6721 # check output - 6722 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0") - 6723 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1") - 6724 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2") - 6725 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3") - 6726 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4") - 6727 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5") - 6728 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6") - 6729 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/7") - 6730 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8") - 6731 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/9") - 6732 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset/10") - 6733 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-using-offset/11") - 6734 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/12") - 6735 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-using-offset/13") - 6736 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset/14") - 6737 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/15") - 6738 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/16") - 6739 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/17") - 6740 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/18") - 6741 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/19") - 6742 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/20") - 6743 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/21") - 6744 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/22") - 6745 # . epilogue - 6746 89/<- %esp 5/r32/ebp - 6747 5d/pop-to-ebp - 6748 c3/return - 6749 - 6750 test-convert-index-into-array-using-offset-on-stack: - 6751 # . prologue - 6752 55/push-ebp - 6753 89/<- %ebp 4/r32/esp - 6754 # setup - 6755 (clear-stream _test-input-stream) - 6756 (clear-stream $_test-input-buffered-file->buffer) - 6757 (clear-stream _test-output-stream) - 6758 (clear-stream $_test-output-buffered-file->buffer) - 6759 # - 6760 (write _test-input-stream "fn foo {\n") - 6761 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 6762 (write _test-input-stream " var idx: int\n") - 6763 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 6764 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 6765 (write _test-input-stream "}\n") - 6766 # convert - 6767 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6768 (flush _test-output-buffered-file) - 6769 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6775 # check output - 6776 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") - 6777 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") - 6778 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") - 6779 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") - 6780 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") - 6781 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") - 6782 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") - 6783 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/7") - 6784 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") - 6785 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") - 6786 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10") - 6787 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-using-offset-on-stack/11") - 6788 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/12") - 6789 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-using-offset-on-stack/13") - 6790 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset-on-stack/14") - 6791 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/15") - 6792 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-using-offset-on-stack/16") - 6793 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/17") - 6794 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/18") - 6795 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/19") - 6796 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/20") - 6797 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/21") - 6798 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/22") - 6799 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/23") - 6800 # . epilogue - 6801 89/<- %esp 5/r32/ebp - 6802 5d/pop-to-ebp - 6803 c3/return - 6804 - 6805 test-convert-index-into-array-of-bytes-using-offset-on-stack: - 6806 # . prologue - 6807 55/push-ebp - 6808 89/<- %ebp 4/r32/esp - 6809 # setup - 6810 (clear-stream _test-input-stream) - 6811 (clear-stream $_test-input-buffered-file->buffer) - 6812 (clear-stream _test-output-stream) - 6813 (clear-stream $_test-output-buffered-file->buffer) - 6814 # - 6815 (write _test-input-stream "fn foo {\n") - 6816 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 6817 (write _test-input-stream " var idx: int\n") - 6818 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") - 6819 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") - 6820 (write _test-input-stream "}\n") - 6821 # convert - 6822 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6823 (flush _test-output-buffered-file) - 6824 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6830 # check output - 6831 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0") - 6832 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1") - 6833 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2") - 6834 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/3") - 6835 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4") - 6836 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5") - 6837 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/6") - 6838 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/7") - 6839 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/8") - 6840 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/9") - 6841 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/10") - 6842 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/11") - 6843 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/12") - 6844 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/13") - 6845 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/14") - 6846 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15") - 6847 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16") - 6848 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17") - 6849 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/18") - 6850 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/19") - 6851 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20") - 6852 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/21") - 6853 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/22") - 6854 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/23") - 6855 # . epilogue - 6856 89/<- %esp 5/r32/ebp - 6857 5d/pop-to-ebp - 6858 c3/return - 6859 - 6860 test-convert-function-and-type-definition: - 6861 # . prologue - 6862 55/push-ebp - 6863 89/<- %ebp 4/r32/esp - 6864 # setup - 6865 (clear-stream _test-input-stream) - 6866 (clear-stream $_test-input-buffered-file->buffer) - 6867 (clear-stream _test-output-stream) - 6868 (clear-stream $_test-output-buffered-file->buffer) - 6869 # - 6870 (write _test-input-stream "fn foo a: (addr t) {\n") - 6871 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") - 6872 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") - 6873 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") - 6874 (write _test-input-stream "}\n") - 6875 (write _test-input-stream "type t {\n") - 6876 (write _test-input-stream " x: int\n") - 6877 (write _test-input-stream " y: int\n") - 6878 (write _test-input-stream "}\n") - 6879 # convert - 6880 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 6881 (flush _test-output-buffered-file) - 6882 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 6888 # check output - 6889 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") - 6890 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") - 6891 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") - 6892 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") - 6893 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") - 6894 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") - 6895 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") - 6896 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") - 6897 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") - 6898 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-function-and-type-definition/9") - 6899 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-get-base-address/disp32" "F - test-convert-function-and-type-definition/10") - 6900 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") - 6901 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-function-and-type-definition/12") - 6902 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-get-base-address/disp32" "F - test-convert-function-and-type-definition/13") - 6903 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/14") - 6904 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/15") - 6905 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/16") - 6906 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/17") - 6907 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/18") - 6908 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/19") - 6909 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/20") - 6910 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/21") - 6911 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/22") - 6912 # . epilogue - 6913 89/<- %esp 5/r32/ebp - 6914 5d/pop-to-ebp - 6915 c3/return - 6916 - 6917 test-type-definition-with-array: - 6918 # . prologue - 6919 55/push-ebp - 6920 89/<- %ebp 4/r32/esp - 6921 # setup - 6922 (clear-stream _test-input-stream) - 6923 (clear-stream $_test-input-buffered-file->buffer) - 6924 (clear-stream _test-output-stream) - 6925 (clear-stream $_test-output-buffered-file->buffer) - 6926 (clear-stream _test-error-stream) - 6927 (clear-stream $_test-error-buffered-file->buffer) - 6928 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 6929 68/push 0/imm32 - 6930 68/push 0/imm32 - 6931 89/<- %edx 4/r32/esp - 6932 (tailor-exit-descriptor %edx 0x10) - 6933 # - 6934 (write _test-input-stream "type t {\n") - 6935 (write _test-input-stream " a: (array int 3)\n") - 6936 (write _test-input-stream "}\n") - 6937 # convert - 6938 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6939 # registers except esp clobbered at this point - 6940 # restore ed - 6941 89/<- %edx 4/r32/esp - 6942 (flush _test-output-buffered-file) - 6943 (flush _test-error-buffered-file) - 6944 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6950 # check output - 6951 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-array: output should be empty") - 6952 (check-next-stream-line-equal _test-error-stream "type t: 'array' elements not allowed for now" "F - test-type-definition-with-array: error message") - 6953 # check that stop(1) was called - 6954 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-array: exit status") - 6955 # don't restore from ebp - 6956 81 0/subop/add %esp 8/imm32 - 6957 # . epilogue - 6958 5d/pop-to-ebp - 6959 c3/return - 6960 - 6961 test-type-definition-with-addr: - 6962 # . prologue - 6963 55/push-ebp - 6964 89/<- %ebp 4/r32/esp - 6965 # setup - 6966 (clear-stream _test-input-stream) - 6967 (clear-stream $_test-input-buffered-file->buffer) - 6968 (clear-stream _test-output-stream) - 6969 (clear-stream $_test-output-buffered-file->buffer) - 6970 (clear-stream _test-error-stream) - 6971 (clear-stream $_test-error-buffered-file->buffer) - 6972 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 6973 68/push 0/imm32 - 6974 68/push 0/imm32 - 6975 89/<- %edx 4/r32/esp - 6976 (tailor-exit-descriptor %edx 0x10) - 6977 # - 6978 (write _test-input-stream "type t {\n") - 6979 (write _test-input-stream " a: (addr int)\n") - 6980 (write _test-input-stream "}\n") - 6981 # convert - 6982 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 6983 # registers except esp clobbered at this point - 6984 # restore ed - 6985 89/<- %edx 4/r32/esp - 6986 (flush _test-output-buffered-file) - 6987 (flush _test-error-buffered-file) - 6988 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 6994 # check output - 6995 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-addr: output should be empty") - 6996 (check-next-stream-line-equal _test-error-stream "type t: 'addr' elements not allowed" "F - test-type-definition-with-addr: error message") - 6997 # check that stop(1) was called - 6998 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-addr: exit status") - 6999 # don't restore from ebp - 7000 81 0/subop/add %esp 8/imm32 - 7001 # . epilogue - 7002 5d/pop-to-ebp - 7003 c3/return - 7004 - 7005 test-convert-function-with-local-var-with-user-defined-type: - 7006 # . prologue - 7007 55/push-ebp - 7008 89/<- %ebp 4/r32/esp - 7009 # setup - 7010 (clear-stream _test-input-stream) - 7011 (clear-stream $_test-input-buffered-file->buffer) - 7012 (clear-stream _test-output-stream) - 7013 (clear-stream $_test-output-buffered-file->buffer) - 7014 # - 7015 (write _test-input-stream "fn foo {\n") - 7016 (write _test-input-stream " var a: t\n") - 7017 (write _test-input-stream "}\n") - 7018 (write _test-input-stream "type t {\n") - 7019 (write _test-input-stream " x: int\n") - 7020 (write _test-input-stream " y: int\n") - 7021 (write _test-input-stream "}\n") - 7022 # convert - 7023 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7024 (flush _test-output-buffered-file) - 7025 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 7031 # check output - 7032 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") - 7033 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") - 7034 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") - 7035 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type/3") - 7036 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") - 7037 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") - 7038 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") - 7039 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") - 7040 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/8") - 7041 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") - 7042 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") - 7043 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") - 7044 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type/12") - 7045 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") - 7046 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") - 7047 # . epilogue - 7048 89/<- %esp 5/r32/ebp - 7049 5d/pop-to-ebp - 7050 c3/return - 7051 - 7052 test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type: - 7053 # . prologue - 7054 55/push-ebp - 7055 89/<- %ebp 4/r32/esp - 7056 # setup - 7057 (clear-stream _test-input-stream) - 7058 (clear-stream $_test-input-buffered-file->buffer) - 7059 (clear-stream _test-output-stream) - 7060 (clear-stream $_test-output-buffered-file->buffer) - 7061 # - 7062 (write _test-input-stream "fn foo {\n") - 7063 (write _test-input-stream " var a: t\n") - 7064 (write _test-input-stream "}\n") - 7065 (write _test-input-stream "type t {\n") - 7066 (write _test-input-stream " x: s\n") - 7067 (write _test-input-stream "}\n") - 7068 (write _test-input-stream "type s {\n") - 7069 (write _test-input-stream " z: int\n") - 7070 (write _test-input-stream "}\n") - 7071 # convert - 7072 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7073 (flush _test-output-buffered-file) - 7074 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 7080 # check output - 7081 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/0") - 7082 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/1") - 7083 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/2") - 7084 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/3") - 7085 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/4") - 7086 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/5") - 7087 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/7") - 7088 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/8") - 7089 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/9") - 7090 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/10") - 7091 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/11") - 7092 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/12") - 7093 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/13") - 7094 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/14") - 7095 # . epilogue - 7096 89/<- %esp 5/r32/ebp - 7097 5d/pop-to-ebp - 7098 c3/return - 7099 - 7100 test-convert-function-call-with-arg-of-user-defined-type: - 7101 # . prologue - 7102 55/push-ebp - 7103 89/<- %ebp 4/r32/esp - 7104 # setup - 7105 (clear-stream _test-input-stream) - 7106 (clear-stream $_test-input-buffered-file->buffer) - 7107 (clear-stream _test-output-stream) - 7108 (clear-stream $_test-output-buffered-file->buffer) - 7109 # - 7110 (write _test-input-stream "fn f {\n") - 7111 (write _test-input-stream " var a: t\n") - 7112 (write _test-input-stream " foo a\n") - 7113 (write _test-input-stream "}\n") - 7114 (write _test-input-stream "fn foo x: t {\n") - 7115 (write _test-input-stream "}\n") - 7116 (write _test-input-stream "type t {\n") - 7117 (write _test-input-stream " x: int\n") - 7118 (write _test-input-stream " y: int\n") - 7119 (write _test-input-stream "}\n") - 7120 # convert - 7121 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7122 (flush _test-output-buffered-file) - 7123 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 7129 # check output - 7130 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 7131 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 7132 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 7133 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") - 7134 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 7135 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 7136 # var a: t - 7137 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") - 7138 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") - 7139 # foo a - 7140 (check-next-stream-line-equal _test-output-stream " (foo *(ebp+0xfffffff8) *(ebp+0xfffffffc))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") - 7141 # - 7142 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/9") - 7143 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 7144 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 7145 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 7146 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") - 7147 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 7148 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 7149 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 7150 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 7151 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 7152 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") - 7153 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 7154 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") - 7155 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 7156 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 7157 # . epilogue - 7158 89/<- %esp 5/r32/ebp - 7159 5d/pop-to-ebp - 7160 c3/return - 7161 - 7162 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: - 7163 # . prologue - 7164 55/push-ebp - 7165 89/<- %ebp 4/r32/esp - 7166 # setup - 7167 (clear-stream _test-input-stream) - 7168 (clear-stream $_test-input-buffered-file->buffer) - 7169 (clear-stream _test-output-stream) - 7170 (clear-stream $_test-output-buffered-file->buffer) - 7171 # - 7172 (write _test-input-stream "fn f {\n") - 7173 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") - 7174 (write _test-input-stream " foo *a\n") - 7175 (write _test-input-stream "}\n") - 7176 (write _test-input-stream "fn foo x: t {\n") - 7177 (write _test-input-stream "}\n") - 7178 (write _test-input-stream "type t {\n") - 7179 (write _test-input-stream " x: int\n") - 7180 (write _test-input-stream " y: int\n") - 7181 (write _test-input-stream "}\n") - 7182 # convert - 7183 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7184 (flush _test-output-buffered-file) - 7185 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 7191 # check output - 7192 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 7193 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 7194 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 7195 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") - 7196 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 7197 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 7198 # var a - 7199 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/6") - 7200 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") - 7201 # foo a - 7202 (check-next-stream-line-equal _test-output-stream " (foo *(eax+0x00000000) *(eax+0x00000004))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") - 7203 # - 7204 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9") - 7205 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 7206 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 7207 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 7208 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") - 7209 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 7210 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 7211 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 7212 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 7213 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 7214 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") - 7215 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 7216 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") - 7217 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 7218 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 7219 # . epilogue - 7220 89/<- %esp 5/r32/ebp - 7221 5d/pop-to-ebp - 7222 c3/return - 7223 - 7224 # we don't have special support for call-by-reference; just explicitly create - 7225 # a new variable with the address of the arg - 7226 test-convert-function-call-with-arg-of-user-defined-type-by-reference: - 7227 # . prologue - 7228 55/push-ebp - 7229 89/<- %ebp 4/r32/esp - 7230 # setup - 7231 (clear-stream _test-input-stream) - 7232 (clear-stream $_test-input-buffered-file->buffer) - 7233 (clear-stream _test-output-stream) - 7234 (clear-stream $_test-output-buffered-file->buffer) - 7235 # - 7236 (write _test-input-stream "fn f {\n") - 7237 (write _test-input-stream " var a: t\n") - 7238 (write _test-input-stream " var b/eax: (addr t) <- address a\n") - 7239 (write _test-input-stream " foo b\n") - 7240 (write _test-input-stream "}\n") - 7241 (write _test-input-stream "fn foo x: (addr t) {\n") - 7242 (write _test-input-stream " var x/ecx: (addr t) <- copy x\n") - 7243 (write _test-input-stream "}\n") - 7244 (write _test-input-stream "type t {\n") - 7245 (write _test-input-stream " x: int\n") - 7246 (write _test-input-stream " y: int\n") - 7247 (write _test-input-stream "}\n") - 7248 # convert - 7249 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7250 (flush _test-output-buffered-file) - 7251 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 7257 # check output - 7258 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") - 7259 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") - 7260 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/2") - 7261 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/3") - 7262 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") - 7263 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/5") - 7264 # var a: t - 7265 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/6") - 7266 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/7") - 7267 # var b/eax: (addr t) - 7268 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/8") - 7269 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/9") - 7270 # foo a - 7271 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") - 7272 # - 7273 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/11") - 7274 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/12") - 7275 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") - 7276 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/14") - 7277 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") - 7278 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/16") - 7279 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/17") - 7280 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") - 7281 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") - 7282 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") - 7283 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/21") - 7284 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/22") - 7285 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") - 7286 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24") - 7287 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25") - 7288 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26") - 7289 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27") - 7290 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28") - 7291 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") - 7292 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30") - 7293 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") - 7294 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/32") - 7295 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/33") - 7296 # . epilogue - 7297 89/<- %esp 5/r32/ebp - 7298 5d/pop-to-ebp - 7299 c3/return - 7300 - 7301 test-convert-get-on-local-variable: - 7302 # . prologue - 7303 55/push-ebp - 7304 89/<- %ebp 4/r32/esp - 7305 # setup - 7306 (clear-stream _test-input-stream) - 7307 (clear-stream $_test-input-buffered-file->buffer) - 7308 (clear-stream _test-output-stream) - 7309 (clear-stream $_test-output-buffered-file->buffer) - 7310 # - 7311 (write _test-input-stream "fn foo {\n") - 7312 (write _test-input-stream " var a: t\n") - 7313 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 7314 (write _test-input-stream "}\n") - 7315 (write _test-input-stream "type t {\n") - 7316 (write _test-input-stream " x: int\n") - 7317 (write _test-input-stream " y: int\n") - 7318 (write _test-input-stream "}\n") - 7319 # convert - 7320 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7321 (flush _test-output-buffered-file) - 7322 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 7328 # check output - 7329 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") - 7330 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") - 7331 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") - 7332 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") - 7333 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") - 7334 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") - 7335 # var a - 7336 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") - 7337 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") - 7338 # var c - 7339 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") - 7340 # get - 7341 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") - 7342 # reclaim c - 7343 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") - 7344 # reclaim a - 7345 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") - 7346 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") - 7347 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") - 7348 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") - 7349 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") - 7350 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") - 7351 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") - 7352 # . epilogue - 7353 89/<- %esp 5/r32/ebp - 7354 5d/pop-to-ebp - 7355 c3/return - 7356 - 7357 test-convert-get-on-function-argument: - 7358 # . prologue - 7359 55/push-ebp - 7360 89/<- %ebp 4/r32/esp - 7361 # setup - 7362 (clear-stream _test-input-stream) - 7363 (clear-stream $_test-input-buffered-file->buffer) - 7364 (clear-stream _test-output-stream) - 7365 (clear-stream $_test-output-buffered-file->buffer) - 7366 # - 7367 (write _test-input-stream "fn foo a: t {\n") - 7368 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 7369 (write _test-input-stream "}\n") - 7370 (write _test-input-stream "type t {\n") - 7371 (write _test-input-stream " x: int\n") - 7372 (write _test-input-stream " y: int\n") - 7373 (write _test-input-stream "}\n") - 7374 # convert - 7375 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7376 (flush _test-output-buffered-file) - 7377 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 7383 # check output - 7384 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") - 7385 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") - 7386 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") - 7387 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") - 7388 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") - 7389 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") - 7390 # var c - 7391 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") - 7392 # get - 7393 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") - 7394 # reclaim c - 7395 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") - 7396 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") - 7397 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") - 7398 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") - 7399 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") - 7400 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") - 7401 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") - 7402 # . epilogue - 7403 89/<- %esp 5/r32/ebp - 7404 5d/pop-to-ebp - 7405 c3/return - 7406 - 7407 test-convert-get-on-function-argument-with-known-type: - 7408 # . prologue - 7409 55/push-ebp - 7410 89/<- %ebp 4/r32/esp - 7411 # setup - 7412 (clear-stream _test-input-stream) - 7413 (clear-stream $_test-input-buffered-file->buffer) - 7414 (clear-stream _test-output-stream) - 7415 (clear-stream $_test-output-buffered-file->buffer) - 7416 # - 7417 (write _test-input-stream "type t {\n") - 7418 (write _test-input-stream " x: int\n") - 7419 (write _test-input-stream " y: int\n") - 7420 (write _test-input-stream "}\n") - 7421 (write _test-input-stream "fn foo a: t {\n") - 7422 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 7423 (write _test-input-stream "}\n") - 7424 # convert - 7425 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7426 (flush _test-output-buffered-file) - 7427 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 7433 # check output - 7434 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") - 7435 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") - 7436 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") - 7437 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") - 7438 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") - 7439 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") - 7440 # var c - 7441 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") - 7442 # get - 7443 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument-with-known-type/7") - 7444 # reclaim c - 7445 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") - 7446 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") - 7447 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") - 7448 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") - 7449 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") - 7450 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") - 7451 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") - 7452 # . epilogue - 7453 89/<- %esp 5/r32/ebp - 7454 5d/pop-to-ebp - 7455 c3/return - 7456 - 7457 test-add-with-too-many-inouts: - 7458 # . prologue - 7459 55/push-ebp - 7460 89/<- %ebp 4/r32/esp - 7461 # setup - 7462 (clear-stream _test-input-stream) - 7463 (clear-stream $_test-input-buffered-file->buffer) - 7464 (clear-stream _test-output-stream) - 7465 (clear-stream $_test-output-buffered-file->buffer) - 7466 (clear-stream _test-error-stream) - 7467 (clear-stream $_test-error-buffered-file->buffer) - 7468 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7469 68/push 0/imm32 - 7470 68/push 0/imm32 - 7471 89/<- %edx 4/r32/esp - 7472 (tailor-exit-descriptor %edx 0x10) - 7473 # - 7474 (write _test-input-stream "fn foo {\n") - 7475 (write _test-input-stream " var a: int\n") - 7476 (write _test-input-stream " var b/ecx: int <- add a, 0\n") - 7477 (write _test-input-stream "}\n") - 7478 # convert - 7479 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7480 # registers except esp clobbered at this point - 7481 # restore ed - 7482 89/<- %edx 4/r32/esp - 7483 (flush _test-output-buffered-file) - 7484 (flush _test-error-buffered-file) - 7485 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7491 # check output - 7492 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts: output should be empty") - 7493 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts: error message") - 7494 # check that stop(1) was called - 7495 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status") - 7496 # don't restore from ebp - 7497 81 0/subop/add %esp 8/imm32 - 7498 # . epilogue - 7499 5d/pop-to-ebp - 7500 c3/return - 7501 - 7502 test-add-with-too-many-inouts-2: - 7503 # . prologue - 7504 55/push-ebp - 7505 89/<- %ebp 4/r32/esp - 7506 # setup - 7507 (clear-stream _test-input-stream) - 7508 (clear-stream $_test-input-buffered-file->buffer) - 7509 (clear-stream _test-output-stream) - 7510 (clear-stream $_test-output-buffered-file->buffer) - 7511 (clear-stream _test-error-stream) - 7512 (clear-stream $_test-error-buffered-file->buffer) - 7513 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7514 68/push 0/imm32 - 7515 68/push 0/imm32 - 7516 89/<- %edx 4/r32/esp - 7517 (tailor-exit-descriptor %edx 0x10) - 7518 # - 7519 (write _test-input-stream "fn foo {\n") - 7520 (write _test-input-stream " var a: int\n") - 7521 (write _test-input-stream " add-to a, 0, 1\n") - 7522 (write _test-input-stream "}\n") - 7523 # convert - 7524 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7525 # registers except esp clobbered at this point - 7526 # restore ed - 7527 89/<- %edx 4/r32/esp - 7528 (flush _test-output-buffered-file) - 7529 (flush _test-error-buffered-file) - 7530 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7536 # check output - 7537 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts-2: output should be empty") - 7538 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add-to: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts-2: error message") - 7539 # check that stop(1) was called - 7540 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status") - 7541 # don't restore from ebp - 7542 81 0/subop/add %esp 8/imm32 - 7543 # . epilogue - 7544 5d/pop-to-ebp - 7545 c3/return - 7546 - 7547 test-add-with-too-many-outputs: - 7548 # . prologue - 7549 55/push-ebp - 7550 89/<- %ebp 4/r32/esp - 7551 # setup - 7552 (clear-stream _test-input-stream) - 7553 (clear-stream $_test-input-buffered-file->buffer) - 7554 (clear-stream _test-output-stream) - 7555 (clear-stream $_test-output-buffered-file->buffer) - 7556 (clear-stream _test-error-stream) - 7557 (clear-stream $_test-error-buffered-file->buffer) - 7558 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7559 68/push 0/imm32 - 7560 68/push 0/imm32 - 7561 89/<- %edx 4/r32/esp - 7562 (tailor-exit-descriptor %edx 0x10) - 7563 # - 7564 (write _test-input-stream "fn foo {\n") - 7565 (write _test-input-stream " var a/eax: int <- copy 0\n") - 7566 (write _test-input-stream " var b/ebx: int <- copy 0\n") - 7567 (write _test-input-stream " var c/ecx: int <- copy 0\n") - 7568 (write _test-input-stream " c, b <- add a\n") - 7569 (write _test-input-stream "}\n") - 7570 # convert - 7571 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7572 # registers except esp clobbered at this point - 7573 # restore ed - 7574 89/<- %edx 4/r32/esp - 7575 (flush _test-output-buffered-file) - 7576 (flush _test-error-buffered-file) - 7577 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7583 # check output - 7584 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-outputs: output should be empty") - 7585 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many outputs; most primitives support at most one output" "F - test-add-with-too-many-outputs: error message") - 7586 # check that stop(1) was called - 7587 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status") - 7588 # don't restore from ebp - 7589 81 0/subop/add %esp 8/imm32 - 7590 # . epilogue - 7591 5d/pop-to-ebp - 7592 c3/return - 7593 - 7594 test-add-with-non-number: - 7595 # . prologue - 7596 55/push-ebp - 7597 89/<- %ebp 4/r32/esp - 7598 # setup - 7599 (clear-stream _test-input-stream) - 7600 (clear-stream $_test-input-buffered-file->buffer) - 7601 (clear-stream _test-output-stream) - 7602 (clear-stream $_test-output-buffered-file->buffer) - 7603 (clear-stream _test-error-stream) - 7604 (clear-stream $_test-error-buffered-file->buffer) - 7605 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7606 68/push 0/imm32 - 7607 68/push 0/imm32 - 7608 89/<- %edx 4/r32/esp - 7609 (tailor-exit-descriptor %edx 0x10) - 7610 # - 7611 (write _test-input-stream "fn foo {\n") - 7612 (write _test-input-stream " var a: int\n") - 7613 (write _test-input-stream " var b/ecx: (addr int) <- add a\n") - 7614 (write _test-input-stream "}\n") - 7615 # convert - 7616 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7617 # registers except esp clobbered at this point - 7618 # restore ed - 7619 89/<- %edx 4/r32/esp - 7620 (flush _test-output-buffered-file) - 7621 (flush _test-error-buffered-file) - 7622 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7628 # check output - 7629 (check-stream-equal _test-output-stream "" "F - test-add-with-non-number: output should be empty") - 7630 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: 'b' must be a non-addr non-offset scalar" "F - test-add-with-non-number: error message") - 7631 # check that stop(1) was called - 7632 (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status") - 7633 # don't restore from ebp - 7634 81 0/subop/add %esp 8/imm32 - 7635 # . epilogue - 7636 5d/pop-to-ebp - 7637 c3/return - 7638 - 7639 test-add-with-addr-dereferenced: - 7640 # . prologue - 7641 55/push-ebp - 7642 89/<- %ebp 4/r32/esp - 7643 # setup - 7644 (clear-stream _test-input-stream) - 7645 (clear-stream $_test-input-buffered-file->buffer) - 7646 (clear-stream _test-output-stream) - 7647 (clear-stream $_test-output-buffered-file->buffer) - 7648 # - 7649 (write _test-input-stream "fn foo {\n") - 7650 (write _test-input-stream " var a/eax: (addr int) <- copy 0\n") - 7651 (write _test-input-stream " add-to *a, 1\n") - 7652 (write _test-input-stream "}\n") - 7653 # convert - 7654 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7655 (flush _test-output-buffered-file) - 7656 # no error - 7657 # . epilogue - 7658 89/<- %esp 5/r32/ebp + 2300 (write _test-input-stream "fn foo {\n") + 2301 (write _test-input-stream " bar 0\n") + 2302 (write _test-input-stream "}\n") + 2303 (write _test-input-stream "sig bar in: (addr int)\n") + 2304 # convert + 2305 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2306 # no errors + 2307 # not bothering checking output + 2308 # . epilogue + 2309 89/<- %esp 5/r32/ebp + 2310 5d/pop-to-ebp + 2311 c3/return + 2312 + 2313 test-convert-function-call-with-signature: + 2314 # . prologue + 2315 55/push-ebp + 2316 89/<- %ebp 4/r32/esp + 2317 # setup + 2318 (clear-stream _test-input-stream) + 2319 (clear-stream $_test-input-buffered-file->buffer) + 2320 (clear-stream _test-output-stream) + 2321 (clear-stream $_test-output-buffered-file->buffer) + 2322 # + 2323 (write _test-input-stream "fn main -> _/ebx: int {\n") + 2324 (write _test-input-stream " var result/eax: int <- do-add 3 4\n") + 2325 (write _test-input-stream " return result\n") + 2326 (write _test-input-stream "}\n") + 2327 (write _test-input-stream "sig do-add a: int, b: int -> _/eax: int\n") + 2328 # convert + 2329 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2330 (flush _test-output-buffered-file) + 2331 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2337 # check output + 2338 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-signature/0") + 2339 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-signature/1") + 2340 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-signature/2") + 2341 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-signature/3") + 2342 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-signature/4") + 2343 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-signature/5") + 2344 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/6") + 2345 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-signature/6") + 2346 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8") + 2347 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-local-var-in-reg/9") + 2348 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10") + 2349 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-signature/7") + 2350 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-signature/8") + 2351 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-signature/9") + 2352 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-signature/10") + 2353 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-signature/11") + 2354 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-signature/12") + 2355 # . epilogue + 2356 89/<- %esp 5/r32/ebp + 2357 5d/pop-to-ebp + 2358 c3/return + 2359 + 2360 test-convert-function-with-local-var-in-mem: + 2361 # . prologue + 2362 55/push-ebp + 2363 89/<- %ebp 4/r32/esp + 2364 # setup + 2365 (clear-stream _test-input-stream) + 2366 (clear-stream $_test-input-buffered-file->buffer) + 2367 (clear-stream _test-output-stream) + 2368 (clear-stream $_test-output-buffered-file->buffer) + 2369 # + 2370 (write _test-input-stream "fn foo {\n") + 2371 (write _test-input-stream " var x: int\n") + 2372 (write _test-input-stream " increment x\n") + 2373 (write _test-input-stream "}\n") + 2374 # convert + 2375 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2376 (flush _test-output-buffered-file) + 2377 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2383 # check output + 2384 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0") + 2385 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1") + 2386 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2") + 2387 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3") + 2388 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4") + 2389 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5") + 2390 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6") + 2391 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7") + 2392 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem/8") + 2393 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9") + 2394 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10") + 2395 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11") + 2396 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12") + 2397 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13") + 2398 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14") + 2399 # . epilogue + 2400 89/<- %esp 5/r32/ebp + 2401 5d/pop-to-ebp + 2402 c3/return + 2403 + 2404 test-convert-invalid-literal: + 2405 # . prologue + 2406 55/push-ebp + 2407 89/<- %ebp 4/r32/esp + 2408 # setup + 2409 (clear-stream _test-input-stream) + 2410 (clear-stream $_test-input-buffered-file->buffer) + 2411 (clear-stream _test-output-stream) + 2412 (clear-stream $_test-output-buffered-file->buffer) + 2413 (clear-stream _test-error-stream) + 2414 (clear-stream $_test-error-buffered-file->buffer) + 2415 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2416 68/push 0/imm32 + 2417 68/push 0/imm32 + 2418 89/<- %edx 4/r32/esp + 2419 (tailor-exit-descriptor %edx 0x10) + 2420 # + 2421 (write _test-input-stream "fn foo {\n") + 2422 (write _test-input-stream " increment 1n\n") + 2423 (write _test-input-stream "}\n") + 2424 # convert + 2425 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2426 # registers except esp clobbered at this point + 2427 # restore ed + 2428 89/<- %edx 4/r32/esp + 2429 (flush _test-output-buffered-file) + 2430 (flush _test-error-buffered-file) + 2431 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2437 # check output + 2438 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-literal: output should be empty") + 2439 (check-next-stream-line-equal _test-error-stream "fn foo: variable '1n' cannot begin with a digit (or do you have a typo in a number?)" "F - test-convert-invalid-literal: error message") + 2440 # check that stop(1) was called + 2441 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-literal: exit status") + 2442 # don't restore from ebp + 2443 81 0/subop/add %esp 8/imm32 + 2444 # . epilogue + 2445 5d/pop-to-ebp + 2446 c3/return + 2447 + 2448 test-convert-valid-literal-with-metadata: + 2449 # . prologue + 2450 55/push-ebp + 2451 89/<- %ebp 4/r32/esp + 2452 # setup + 2453 (clear-stream _test-input-stream) + 2454 (clear-stream $_test-input-buffered-file->buffer) + 2455 (clear-stream _test-output-stream) + 2456 (clear-stream $_test-output-buffered-file->buffer) + 2457 # + 2458 (write _test-input-stream "fn foo {\n") + 2459 (write _test-input-stream " var x/eax: int <- copy 1/abc\n") + 2460 (write _test-input-stream "}\n") + 2461 # convert + 2462 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2463 (flush _test-output-buffered-file) + 2464 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2470 # no errors + 2471 # . epilogue + 2472 89/<- %esp 5/r32/ebp + 2473 5d/pop-to-ebp + 2474 c3/return + 2475 + 2476 test-local-var-in-mem-has-no-initializer: + 2477 # . prologue + 2478 55/push-ebp + 2479 89/<- %ebp 4/r32/esp + 2480 # setup + 2481 (clear-stream _test-input-stream) + 2482 (clear-stream $_test-input-buffered-file->buffer) + 2483 (clear-stream _test-output-stream) + 2484 (clear-stream $_test-output-buffered-file->buffer) + 2485 (clear-stream _test-error-stream) + 2486 (clear-stream $_test-error-buffered-file->buffer) + 2487 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2488 68/push 0/imm32 + 2489 68/push 0/imm32 + 2490 89/<- %edx 4/r32/esp + 2491 (tailor-exit-descriptor %edx 0x10) + 2492 # + 2493 (write _test-input-stream "fn foo {\n") + 2494 (write _test-input-stream " var x: int <- copy 0\n") + 2495 (write _test-input-stream " increment x\n") + 2496 (write _test-input-stream "}\n") + 2497 # convert + 2498 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2499 # registers except esp clobbered at this point + 2500 # restore ed + 2501 89/<- %edx 4/r32/esp + 2502 (flush _test-output-buffered-file) + 2503 (flush _test-error-buffered-file) + 2504 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2510 # check output + 2511 (check-stream-equal _test-output-stream "" "F - test-var-in-mem-has-no-initializer: output should be empty") + 2512 (check-next-stream-line-equal _test-error-stream "fn foo: var x: variables on the stack can't take an initializer" "F - test-var-in-mem-has-no-initializer: error message") + 2513 # check that stop(1) was called + 2514 (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status") + 2515 # don't restore from ebp + 2516 81 0/subop/add %esp 8/imm32 + 2517 # . epilogue + 2518 5d/pop-to-ebp + 2519 c3/return + 2520 + 2521 test-convert-function-with-local-var-with-compound-type-in-mem: + 2522 # . prologue + 2523 55/push-ebp + 2524 89/<- %ebp 4/r32/esp + 2525 # setup + 2526 (clear-stream _test-input-stream) + 2527 (clear-stream $_test-input-buffered-file->buffer) + 2528 (clear-stream _test-output-stream) + 2529 (clear-stream $_test-output-buffered-file->buffer) + 2530 # + 2531 (write _test-input-stream "fn foo {\n") + 2532 (write _test-input-stream " var x: (addr int)\n") + 2533 (write _test-input-stream " copy-to x, 0\n") + 2534 (write _test-input-stream "}\n") + 2535 # convert + 2536 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2537 (flush _test-output-buffered-file) + 2538 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2544 # check output + 2545 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0") + 2546 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1") + 2547 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2") + 2548 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/3") + 2549 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4") + 2550 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5") + 2551 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/6") + 2552 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy *(ebp+0xfffffffc) 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/7") + 2553 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/8") + 2554 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9") + 2555 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10") + 2556 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11") + 2557 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/12") + 2558 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/13") + 2559 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14") + 2560 # . epilogue + 2561 89/<- %esp 5/r32/ebp + 2562 5d/pop-to-ebp + 2563 c3/return + 2564 + 2565 test-convert-function-with-local-var-in-reg: + 2566 # . prologue + 2567 55/push-ebp + 2568 89/<- %ebp 4/r32/esp + 2569 # setup + 2570 (clear-stream _test-input-stream) + 2571 (clear-stream $_test-input-buffered-file->buffer) + 2572 (clear-stream _test-output-stream) + 2573 (clear-stream $_test-output-buffered-file->buffer) + 2574 # + 2575 (write _test-input-stream "fn foo {\n") + 2576 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2577 (write _test-input-stream " x <- increment\n") + 2578 (write _test-input-stream "}\n") + 2579 # convert + 2580 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2581 (flush _test-output-buffered-file) + 2582 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2588 # check output + 2589 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0") + 2590 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1") + 2591 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2") + 2592 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3") + 2593 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4") + 2594 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5") + 2595 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6") + 2596 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7") + 2597 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8") + 2598 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9") + 2599 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10") + 2600 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11") + 2601 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12") + 2602 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13") + 2603 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14") + 2604 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15") + 2605 # . epilogue + 2606 89/<- %esp 5/r32/ebp + 2607 5d/pop-to-ebp + 2608 c3/return + 2609 + 2610 test-convert-function-with-local-var-in-same-reg: + 2611 # . prologue + 2612 55/push-ebp + 2613 89/<- %ebp 4/r32/esp + 2614 # setup + 2615 (clear-stream _test-input-stream) + 2616 (clear-stream $_test-input-buffered-file->buffer) + 2617 (clear-stream _test-output-stream) + 2618 (clear-stream $_test-output-buffered-file->buffer) + 2619 # + 2620 (write _test-input-stream "fn foo {\n") + 2621 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2622 (write _test-input-stream " var y/ecx: int <- copy x\n") + 2623 (write _test-input-stream "}\n") + 2624 # convert + 2625 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2626 (flush _test-output-buffered-file) + 2627 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2633 # check output + 2634 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-same-reg/0") + 2635 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-same-reg/1") + 2636 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-same-reg/2") + 2637 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-same-reg/3") + 2638 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-same-reg/4") + 2639 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-same-reg/5") + 2640 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-same-reg/6") + 2641 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-same-reg/7") + 2642 # optimization: skip the second copy + 2643 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-same-reg/8") + 2644 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-same-reg/9") + 2645 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-same-reg/10") + 2646 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-same-reg/11") + 2647 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-same-reg/12") + 2648 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-same-reg/13") + 2649 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-same-reg/14") + 2650 # . epilogue + 2651 89/<- %esp 5/r32/ebp + 2652 5d/pop-to-ebp + 2653 c3/return + 2654 + 2655 test-convert-function-with-local-var-in-same-reg-dereferenced: + 2656 # . prologue + 2657 55/push-ebp + 2658 89/<- %ebp 4/r32/esp + 2659 # setup + 2660 (clear-stream _test-input-stream) + 2661 (clear-stream $_test-input-buffered-file->buffer) + 2662 (clear-stream _test-output-stream) + 2663 (clear-stream $_test-output-buffered-file->buffer) + 2664 # + 2665 (write _test-input-stream "fn foo {\n") + 2666 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") + 2667 (write _test-input-stream " var y/ecx: int <- copy *x\n") + 2668 (write _test-input-stream "}\n") + 2669 # convert + 2670 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2671 (flush _test-output-buffered-file) + 2672 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2678 # check output + 2679 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/0") + 2680 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/1") + 2681 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/2") + 2682 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/3") + 2683 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/4") + 2684 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/5") + 2685 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/6") + 2686 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/7") + 2687 (check-next-stream-line-equal _test-output-stream " 8b/-> *ecx 0x00000001/r32" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/8") # don't optimize this away + 2688 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/9") + 2689 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/10") + 2690 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/11") + 2691 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/12") + 2692 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/13") + 2693 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/14") + 2694 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/15") + 2695 # . epilogue + 2696 89/<- %esp 5/r32/ebp + 2697 5d/pop-to-ebp + 2698 c3/return + 2699 + 2700 test-float-var-in-wrong-register: + 2701 # . prologue + 2702 55/push-ebp + 2703 89/<- %ebp 4/r32/esp + 2704 # setup + 2705 (clear-stream _test-input-stream) + 2706 (clear-stream $_test-input-buffered-file->buffer) + 2707 (clear-stream _test-output-stream) + 2708 (clear-stream $_test-output-buffered-file->buffer) + 2709 (clear-stream _test-error-stream) + 2710 (clear-stream $_test-error-buffered-file->buffer) + 2711 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2712 68/push 0/imm32 + 2713 68/push 0/imm32 + 2714 89/<- %edx 4/r32/esp + 2715 (tailor-exit-descriptor %edx 0x10) + 2716 # + 2717 (write _test-input-stream "fn foo {\n") + 2718 (write _test-input-stream " var x/eax: int <- copy 0\n") + 2719 (write _test-input-stream " var y/eax: float <- convert x\n") + 2720 (write _test-input-stream "}\n") + 2721 # convert + 2722 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2723 # registers except esp clobbered at this point + 2724 # restore ed + 2725 89/<- %edx 4/r32/esp + 2726 (flush _test-output-buffered-file) + 2727 (flush _test-error-buffered-file) + 2728 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2734 # check output + 2735 (check-stream-equal _test-output-stream "" "F - test-float-var-in-wrong-register: output should be empty") + 2736 (check-next-stream-line-equal _test-error-stream "fn foo: float var 'y' should be in a floating-point register" "F - test-float-var-in-wrong-register: error message") + 2737 # check that stop(1) was called + 2738 (check-ints-equal *(edx+4) 2 "F - test-float-var-in-wrong-register: exit status") + 2739 # don't restore from ebp + 2740 81 0/subop/add %esp 8/imm32 + 2741 # . epilogue + 2742 5d/pop-to-ebp + 2743 c3/return + 2744 + 2745 test-non-float-var-in-wrong-register: + 2746 # . prologue + 2747 55/push-ebp + 2748 89/<- %ebp 4/r32/esp + 2749 # setup + 2750 (clear-stream _test-input-stream) + 2751 (clear-stream $_test-input-buffered-file->buffer) + 2752 (clear-stream _test-output-stream) + 2753 (clear-stream $_test-output-buffered-file->buffer) + 2754 (clear-stream _test-error-stream) + 2755 (clear-stream $_test-error-buffered-file->buffer) + 2756 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2757 68/push 0/imm32 + 2758 68/push 0/imm32 + 2759 89/<- %edx 4/r32/esp + 2760 (tailor-exit-descriptor %edx 0x10) + 2761 # + 2762 (write _test-input-stream "fn foo {\n") + 2763 (write _test-input-stream " var x/xmm5: int <- copy 0\n") + 2764 (write _test-input-stream "}\n") + 2765 # convert + 2766 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2767 # registers except esp clobbered at this point + 2768 # restore ed + 2769 89/<- %edx 4/r32/esp + 2770 (flush _test-output-buffered-file) + 2771 (flush _test-error-buffered-file) + 2772 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2778 # check output + 2779 (check-stream-equal _test-output-stream "" "F - test-non-float-var-in-wrong-register: output should be empty") + 2780 (check-next-stream-line-equal _test-error-stream "fn foo: non-float var 'x' should be in an integer register" "F - test-non-float-var-in-wrong-register: error message") + 2781 # check that stop(1) was called + 2782 (check-ints-equal *(edx+4) 2 "F - test-non-float-var-in-wrong-register: exit status") + 2783 # don't restore from ebp + 2784 81 0/subop/add %esp 8/imm32 + 2785 # . epilogue + 2786 5d/pop-to-ebp + 2787 c3/return + 2788 + 2789 test-convert-function-with-allocate: + 2790 # . prologue + 2791 55/push-ebp + 2792 89/<- %ebp 4/r32/esp + 2793 # setup + 2794 (clear-stream _test-input-stream) + 2795 (clear-stream $_test-input-buffered-file->buffer) + 2796 (clear-stream _test-output-stream) + 2797 (clear-stream $_test-output-buffered-file->buffer) + 2798 # + 2799 (write _test-input-stream "fn foo {\n") + 2800 (write _test-input-stream " var x/ecx: (addr handle int) <- copy 0\n") + 2801 (write _test-input-stream " allocate x\n") + 2802 (write _test-input-stream "}\n") + 2803 # convert + 2804 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2805 (flush _test-output-buffered-file) + 2806 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2812 # check output + 2813 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-allocate/0") + 2814 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-allocate/1") + 2815 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-allocate/2") + 2816 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-allocate/3") + 2817 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-allocate/4") + 2818 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-allocate/5") + 2819 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-allocate/6") + 2820 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-allocate/7") + 2821 (check-next-stream-line-equal _test-output-stream " (allocate Heap 0x00000004 %ecx)" "F - test-convert-function-with-allocate/8") # 4 = size-of(int) + 2822 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-allocate/9") + 2823 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-allocate/10") + 2824 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-allocate/11") + 2825 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-allocate/12") + 2826 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-allocate/13") + 2827 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-allocate/14") + 2828 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-allocate/15") + 2829 # . epilogue + 2830 89/<- %esp 5/r32/ebp + 2831 5d/pop-to-ebp + 2832 c3/return + 2833 + 2834 test-initializer-in-hex: + 2835 # . prologue + 2836 55/push-ebp + 2837 89/<- %ebp 4/r32/esp + 2838 # setup + 2839 (clear-stream _test-input-stream) + 2840 (clear-stream $_test-input-buffered-file->buffer) + 2841 (clear-stream _test-output-stream) + 2842 (clear-stream $_test-output-buffered-file->buffer) + 2843 (clear-stream _test-error-stream) + 2844 (clear-stream $_test-error-buffered-file->buffer) + 2845 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2846 68/push 0/imm32 + 2847 68/push 0/imm32 + 2848 89/<- %edx 4/r32/esp + 2849 (tailor-exit-descriptor %edx 0x10) + 2850 # + 2851 (write _test-input-stream "fn foo {\n") + 2852 (write _test-input-stream " var x/ecx: int <- copy 10\n") + 2853 (write _test-input-stream "}\n") + 2854 # convert + 2855 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2856 # registers except esp clobbered at this point + 2857 # restore ed + 2858 89/<- %edx 4/r32/esp + 2859 (flush _test-output-buffered-file) + 2860 (flush _test-error-buffered-file) + 2861 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2867 # check output + 2868 (check-stream-equal _test-output-stream "" "F - test-initializer-in-hex: output should be empty") + 2869 (check-next-stream-line-equal _test-error-stream "literal integers are always hex in Mu; start '10' with a '0x' to be unambiguous, converting it to hexadecimal as necessary." "F - test-initializer-in-hex: error message") + 2870 # check that stop(1) was called + 2871 (check-ints-equal *(edx+4) 2 "F - test-initializer-in-hex: exit status") + 2872 # don't restore from ebp + 2873 81 0/subop/add %esp 8/imm32 + 2874 # . epilogue + 2875 5d/pop-to-ebp + 2876 c3/return + 2877 + 2878 test-convert-function-with-second-local-var-in-same-reg: + 2879 # . prologue + 2880 55/push-ebp + 2881 89/<- %ebp 4/r32/esp + 2882 # setup + 2883 (clear-stream _test-input-stream) + 2884 (clear-stream $_test-input-buffered-file->buffer) + 2885 (clear-stream _test-output-stream) + 2886 (clear-stream $_test-output-buffered-file->buffer) + 2887 # + 2888 (write _test-input-stream "fn foo {\n") + 2889 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2890 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2891 (write _test-input-stream " y <- increment\n") + 2892 (write _test-input-stream "}\n") + 2893 # convert + 2894 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2895 (flush _test-output-buffered-file) + 2896 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2902 # check output + 2903 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0") + 2904 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1") + 2905 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2") + 2906 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-second-local-var-in-same-reg/3") + 2907 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4") + 2908 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5") + 2909 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/6") + 2910 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/7") + 2911 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/8") + 2912 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9") + 2913 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/10") + 2914 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11") + 2915 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12") + 2916 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13") + 2917 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-second-local-var-in-same-reg/14") + 2918 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15") + 2919 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16") + 2920 # . epilogue + 2921 89/<- %esp 5/r32/ebp + 2922 5d/pop-to-ebp + 2923 c3/return + 2924 + 2925 test-read-clobbered-reg-var: + 2926 # . prologue + 2927 55/push-ebp + 2928 89/<- %ebp 4/r32/esp + 2929 # setup + 2930 (clear-stream _test-input-stream) + 2931 (clear-stream $_test-input-buffered-file->buffer) + 2932 (clear-stream _test-output-stream) + 2933 (clear-stream $_test-output-buffered-file->buffer) + 2934 (clear-stream _test-error-stream) + 2935 (clear-stream $_test-error-buffered-file->buffer) + 2936 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu + 2937 68/push 0/imm32 + 2938 68/push 0/imm32 + 2939 89/<- %edx 4/r32/esp + 2940 (tailor-exit-descriptor %edx 0x10) + 2941 # + 2942 (write _test-input-stream "fn foo {\n") + 2943 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2944 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2945 (write _test-input-stream " x <- increment\n") + 2946 (write _test-input-stream "}\n") + 2947 # convert + 2948 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2949 # registers except esp clobbered at this point + 2950 # restore ed + 2951 89/<- %edx 4/r32/esp + 2952 (flush _test-output-buffered-file) + 2953 (flush _test-error-buffered-file) + 2954 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2960 # check output + 2961 (check-stream-equal _test-output-stream "" "F - test-read-clobbered-reg-var: output should be empty") + 2962 (check-next-stream-line-equal _test-error-stream "fn foo: register ecx reads var 'x' after writing var 'y'" "F - test-read-clobbered-reg-var: error message") + 2963 # check that stop(1) was called + 2964 (check-ints-equal *(edx+4) 2 "F - test-read-clobbered-reg-var: exit status") + 2965 # don't restore from ebp + 2966 81 0/subop/add %esp 8/imm32 + 2967 # . epilogue + 2968 5d/pop-to-ebp + 2969 c3/return + 2970 + 2971 test-overlapping-int-fp-registers: + 2972 # . prologue + 2973 55/push-ebp + 2974 89/<- %ebp 4/r32/esp + 2975 # setup + 2976 (clear-stream _test-input-stream) + 2977 (clear-stream $_test-input-buffered-file->buffer) + 2978 (clear-stream _test-output-stream) + 2979 (clear-stream $_test-output-buffered-file->buffer) + 2980 (clear-stream _test-error-stream) + 2981 (clear-stream $_test-error-buffered-file->buffer) + 2982 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu + 2983 68/push 0/imm32 + 2984 68/push 0/imm32 + 2985 89/<- %edx 4/r32/esp + 2986 (tailor-exit-descriptor %edx 0x10) + 2987 # + 2988 (write _test-input-stream "fn foo {\n") + 2989 (write _test-input-stream " var x/eax: int <- copy 3\n") + 2990 (write _test-input-stream " var y/xmm0: float <- convert x\n") + 2991 (write _test-input-stream " x <- increment\n") + 2992 (write _test-input-stream "}\n") + 2993 # convert + 2994 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2995 # registers except esp clobbered at this point + 2996 # restore ed + 2997 89/<- %edx 4/r32/esp + 2998 (flush _test-output-buffered-file) + 2999 (flush _test-error-buffered-file) + 3000 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3006 # no errors + 3007 (check-next-stream-line-equal _test-error-stream "" "F - test-overlapping-int-fp-registers: error message") + 3008 # don't bother checking the generated code + 3009 # don't restore from ebp + 3010 81 0/subop/add %esp 8/imm32 + 3011 # . epilogue + 3012 5d/pop-to-ebp + 3013 c3/return + 3014 + 3015 test-convert-function-call: + 3016 # . prologue + 3017 55/push-ebp + 3018 89/<- %ebp 4/r32/esp + 3019 # setup + 3020 (clear-stream _test-input-stream) + 3021 (clear-stream $_test-input-buffered-file->buffer) + 3022 (clear-stream _test-output-stream) + 3023 (clear-stream $_test-output-buffered-file->buffer) + 3024 # + 3025 (write _test-input-stream "fn main -> _/ebx: int {\n") + 3026 (write _test-input-stream " var result/ebx: int <- foo\n") + 3027 (write _test-input-stream " return result\n") + 3028 (write _test-input-stream "}\n") + 3029 (write _test-input-stream "fn foo -> _/ebx: int {\n") + 3030 (write _test-input-stream " var result/ebx: int <- copy 3\n") + 3031 (write _test-input-stream " return result\n") + 3032 (write _test-input-stream "}\n") + 3033 # convert + 3034 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3035 (flush _test-output-buffered-file) + 3036 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3042 # check output + 3043 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call/0") + 3044 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/1") + 3045 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/2") + 3046 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/3") + 3047 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/4") + 3048 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call/5") + 3049 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-call-with-literal-arg/6") + 3050 (check-next-stream-line-equal _test-output-stream " (foo)" "F - test-convert-function-call/6") + 3051 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8") + 3052 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27") + 3053 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10") + 3054 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/7") + 3055 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call/8") + 3056 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/9") + 3057 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/10") + 3058 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/11") + 3059 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/12") + 3060 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call/13") + 3061 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/14") + 3062 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/15") + 3063 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/16") + 3064 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/17") + 3065 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call/18") + 3066 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-call-with-literal-arg/6") + 3067 (check-next-stream-line-equal _test-output-stream " bb/copy-to-ebx 3/imm32" "F - test-convert-function-call/19") + 3068 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8") + 3069 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27") + 3070 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-call-with-literal-arg/10") + 3071 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/20") + 3072 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call/21") + 3073 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/22") + 3074 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/23") + 3075 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/24") + 3076 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/25") + 3077 # . epilogue + 3078 89/<- %esp 5/r32/ebp + 3079 5d/pop-to-ebp + 3080 c3/return + 3081 + 3082 test-convert-function-call-with-inout-with-compound-type: + 3083 # . prologue + 3084 55/push-ebp + 3085 89/<- %ebp 4/r32/esp + 3086 # setup + 3087 (clear-stream _test-input-stream) + 3088 (clear-stream $_test-input-buffered-file->buffer) + 3089 (clear-stream _test-output-stream) + 3090 (clear-stream $_test-output-buffered-file->buffer) + 3091 # + 3092 (write _test-input-stream "fn f {\n") + 3093 (write _test-input-stream " var x: (addr int)\n") + 3094 (write _test-input-stream " g x\n") + 3095 (write _test-input-stream "}\n") + 3096 (write _test-input-stream "fn g a: (addr int) {\n") + 3097 (write _test-input-stream "}\n") + 3098 # convert + 3099 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3100 (flush _test-output-buffered-file) + 3101 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3107 # check output + 3108 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-inout-with-compound-type/0") + 3109 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-inout-with-compound-type/1") + 3110 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-inout-with-compound-type/2") + 3111 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-inout-with-compound-type/3") + 3112 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-inout-with-compound-type/4") + 3113 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-inout-with-compound-type/5") + 3114 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-inout-with-compound-type/6") + 3115 (check-next-stream-line-equal _test-output-stream " (g *(ebp+0xfffffffc))" "F - test-convert-function-call-with-inout-with-compound-type/7") + 3116 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-call-with-inout-with-compound-type/8") + 3117 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-inout-with-compound-type/9") + 3118 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-inout-with-compound-type/10") + 3119 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-inout-with-compound-type/11") + 3120 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-inout-with-compound-type/12") + 3121 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-inout-with-compound-type/13") + 3122 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-inout-with-compound-type/14") + 3123 (check-next-stream-line-equal _test-output-stream "g:" "F - test-convert-function-call-with-inout-with-compound-type/15") + 3124 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-inout-with-compound-type/16") + 3125 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-inout-with-compound-type/17") + 3126 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-inout-with-compound-type/18") + 3127 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-inout-with-compound-type/19") + 3128 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-inout-with-compound-type/20") + 3129 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-inout-with-compound-type/21") + 3130 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-inout-with-compound-type/22") + 3131 # . epilogue + 3132 89/<- %esp 5/r32/ebp + 3133 5d/pop-to-ebp + 3134 c3/return + 3135 + 3136 test-convert-function-call-with-inout-with-type-parameter: + 3137 # . prologue + 3138 55/push-ebp + 3139 89/<- %ebp 4/r32/esp + 3140 # setup + 3141 (clear-stream _test-input-stream) + 3142 (clear-stream $_test-input-buffered-file->buffer) + 3143 (clear-stream _test-output-stream) + 3144 (clear-stream $_test-output-buffered-file->buffer) + 3145 (clear-stream _test-error-stream) + 3146 (clear-stream $_test-error-buffered-file->buffer) + 3147 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3148 68/push 0/imm32 + 3149 68/push 0/imm32 + 3150 89/<- %edx 4/r32/esp + 3151 (tailor-exit-descriptor %edx 0x10) + 3152 # + 3153 (write _test-input-stream "fn f {\n") + 3154 (write _test-input-stream " var x: (addr int)\n") + 3155 (write _test-input-stream " g x\n") + 3156 (write _test-input-stream "}\n") + 3157 (write _test-input-stream "fn g a: (addr _) {\n") + 3158 (write _test-input-stream "}\n") + 3159 # convert + 3160 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3161 # registers except esp clobbered at this point + 3162 # restore ed + 3163 89/<- %edx 4/r32/esp + 3164 (flush _test-output-buffered-file) + 3165 (flush _test-error-buffered-file) + 3166 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3172 # no error; types matched + 3173 (check-stream-equal _test-error-stream "" "F - test-convert-function-call-with-inout-with-type-parameter: error stream should be empty") + 3174 # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below + 3175 # don't restore from ebp + 3176 81 0/subop/add %esp 8/imm32 + 3177 # . epilogue + 3178 5d/pop-to-ebp + 3179 c3/return + 3180 + 3181 test-convert-function-call-with-incorrect-inout-type: + 3182 # . prologue + 3183 55/push-ebp + 3184 89/<- %ebp 4/r32/esp + 3185 # setup + 3186 (clear-stream _test-input-stream) + 3187 (clear-stream $_test-input-buffered-file->buffer) + 3188 (clear-stream _test-output-stream) + 3189 (clear-stream $_test-output-buffered-file->buffer) + 3190 (clear-stream _test-error-stream) + 3191 (clear-stream $_test-error-buffered-file->buffer) + 3192 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3193 68/push 0/imm32 + 3194 68/push 0/imm32 + 3195 89/<- %edx 4/r32/esp + 3196 (tailor-exit-descriptor %edx 0x10) + 3197 # + 3198 (write _test-input-stream "fn f {\n") + 3199 (write _test-input-stream " var x: int\n") + 3200 (write _test-input-stream " g x\n") + 3201 (write _test-input-stream "}\n") + 3202 (write _test-input-stream "fn g a: foo {\n") + 3203 (write _test-input-stream "}\n") + 3204 # convert + 3205 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3206 # registers except esp clobbered at this point + 3207 # restore ed + 3208 89/<- %edx 4/r32/esp + 3209 (flush _test-output-buffered-file) + 3210 (flush _test-error-buffered-file) + 3211 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3217 # check output + 3218 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-inout-type: output should be empty") + 3219 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'x' is not right" "F - test-convert-function-call-with-incorrect-inout-type: error message") + 3220 # check that stop(1) was called + 3221 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-inout-type: exit status") + 3222 # don't restore from ebp + 3223 81 0/subop/add %esp 8/imm32 + 3224 5d/pop-to-ebp + 3225 c3/return + 3226 + 3227 test-convert-function-call-with-inout-with-incorrect-compound-type: + 3228 # . prologue + 3229 55/push-ebp + 3230 89/<- %ebp 4/r32/esp + 3231 # setup + 3232 (clear-stream _test-input-stream) + 3233 (clear-stream $_test-input-buffered-file->buffer) + 3234 (clear-stream _test-output-stream) + 3235 (clear-stream $_test-output-buffered-file->buffer) + 3236 (clear-stream _test-error-stream) + 3237 (clear-stream $_test-error-buffered-file->buffer) + 3238 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3239 68/push 0/imm32 + 3240 68/push 0/imm32 + 3241 89/<- %edx 4/r32/esp + 3242 (tailor-exit-descriptor %edx 0x10) + 3243 # + 3244 (write _test-input-stream "fn f {\n") + 3245 (write _test-input-stream " var x: (addr int)\n") + 3246 (write _test-input-stream " g x\n") + 3247 (write _test-input-stream "}\n") + 3248 (write _test-input-stream "fn g a: (addr bool) {\n") + 3249 (write _test-input-stream "}\n") + 3250 # convert + 3251 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3252 # registers except esp clobbered at this point + 3253 # restore ed + 3254 89/<- %edx 4/r32/esp + 3255 (flush _test-output-buffered-file) + 3256 (flush _test-error-buffered-file) + 3257 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3263 # check output + 3264 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-inout-with-incorrect-compound-type: output should be empty") + 3265 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'x' is not right" "F - test-convert-function-call-with-inout-with-incorrect-compound-type: error message") + 3266 # don't restore from ebp + 3267 81 0/subop/add %esp 8/imm32 + 3268 # . epilogue + 3269 5d/pop-to-ebp + 3270 c3/return + 3271 + 3272 test-convert-function-call-with-inout-with-multiple-type-parameters: + 3273 # . prologue + 3274 55/push-ebp + 3275 89/<- %ebp 4/r32/esp + 3276 # setup + 3277 (clear-stream _test-input-stream) + 3278 (clear-stream $_test-input-buffered-file->buffer) + 3279 (clear-stream _test-output-stream) + 3280 (clear-stream $_test-output-buffered-file->buffer) + 3281 (clear-stream _test-error-stream) + 3282 (clear-stream $_test-error-buffered-file->buffer) + 3283 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3284 68/push 0/imm32 + 3285 68/push 0/imm32 + 3286 89/<- %edx 4/r32/esp + 3287 (tailor-exit-descriptor %edx 0x10) + 3288 # + 3289 (write _test-input-stream "fn f {\n") + 3290 (write _test-input-stream " var x: (addr int)\n") + 3291 (write _test-input-stream " var y: (addr int)\n") + 3292 (write _test-input-stream " g x, y\n") + 3293 (write _test-input-stream "}\n") + 3294 (write _test-input-stream "fn g a: (addr _), b: (addr _) {\n") + 3295 (write _test-input-stream "}\n") + 3296 # convert + 3297 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3298 # registers except esp clobbered at this point + 3299 # restore ed + 3300 89/<- %edx 4/r32/esp + 3301 (flush _test-output-buffered-file) + 3302 (flush _test-error-buffered-file) + 3303 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3309 # no errors + 3310 (check-stream-equal _test-error-stream "" "F - test-convert-function-call-with-inout-with-multiple-type-parameters: error stream should be empty") + 3311 # don't bother checking the generated code + 3312 # don't restore from ebp + 3313 81 0/subop/add %esp 8/imm32 + 3314 # . epilogue + 3315 5d/pop-to-ebp + 3316 c3/return + 3317 + 3318 test-type-parameter-matches-rest-of-type: + 3319 # . prologue + 3320 55/push-ebp + 3321 89/<- %ebp 4/r32/esp + 3322 # setup + 3323 (clear-stream _test-input-stream) + 3324 (clear-stream $_test-input-buffered-file->buffer) + 3325 (clear-stream _test-output-stream) + 3326 (clear-stream $_test-output-buffered-file->buffer) + 3327 (clear-stream _test-error-stream) + 3328 (clear-stream $_test-error-buffered-file->buffer) + 3329 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3330 68/push 0/imm32 + 3331 68/push 0/imm32 + 3332 89/<- %edx 4/r32/esp + 3333 (tailor-exit-descriptor %edx 0x10) + 3334 # + 3335 (write _test-input-stream "fn f {\n") + 3336 (write _test-input-stream " var x: (addr array int)\n") + 3337 (write _test-input-stream " g x\n") + 3338 (write _test-input-stream "}\n") + 3339 (write _test-input-stream "fn g a: (addr _) {\n") + 3340 (write _test-input-stream "}\n") + 3341 # convert + 3342 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3343 # registers except esp clobbered at this point + 3344 # restore ed + 3345 89/<- %edx 4/r32/esp + 3346 (flush _test-output-buffered-file) + 3347 (flush _test-error-buffered-file) + 3348 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3354 # no errors + 3355 (check-stream-equal _test-error-stream "" "F - test-type-parameter-matches-rest-of-type: error stream should be empty") + 3356 # don't bother checking the generated code + 3357 # don't restore from ebp + 3358 81 0/subop/add %esp 8/imm32 + 3359 # . epilogue + 3360 5d/pop-to-ebp + 3361 c3/return + 3362 + 3363 test-convert-function-call-with-inout-with-incompatible-type-parameters: + 3364 # . prologue + 3365 55/push-ebp + 3366 89/<- %ebp 4/r32/esp + 3367 # setup + 3368 (clear-stream _test-input-stream) + 3369 (clear-stream $_test-input-buffered-file->buffer) + 3370 (clear-stream _test-output-stream) + 3371 (clear-stream $_test-output-buffered-file->buffer) + 3372 (clear-stream _test-error-stream) + 3373 (clear-stream $_test-error-buffered-file->buffer) + 3374 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3375 68/push 0/imm32 + 3376 68/push 0/imm32 + 3377 89/<- %edx 4/r32/esp + 3378 (tailor-exit-descriptor %edx 0x10) + 3379 # + 3380 (write _test-input-stream "fn f {\n") + 3381 (write _test-input-stream " var x: (addr int)\n") + 3382 (write _test-input-stream " var y: (addr boolean)\n") + 3383 (write _test-input-stream " g x, y\n") + 3384 (write _test-input-stream "}\n") + 3385 (write _test-input-stream "fn g a: (addr _T), b: (addr _T) {\n") + 3386 (write _test-input-stream "}\n") + 3387 # convert + 3388 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3389 # registers except esp clobbered at this point + 3390 # restore ed + 3391 89/<- %edx 4/r32/esp + 3392 (flush _test-output-buffered-file) + 3393 (flush _test-error-buffered-file) + 3394 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3400 # check output + 3401 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-inout-with-incompatible-type-parameters: output should be empty") + 3402 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'y' is not right" "F - test-convert-function-call-with-inout-with-incompatible-type-parameters: error message") + 3403 # don't restore from ebp + 3404 81 0/subop/add %esp 8/imm32 + 3405 # . epilogue + 3406 5d/pop-to-ebp + 3407 c3/return + 3408 + 3409 test-convert-function-call-with-too-few-inouts: + 3410 # . prologue + 3411 55/push-ebp + 3412 89/<- %ebp 4/r32/esp + 3413 # setup + 3414 (clear-stream _test-input-stream) + 3415 (clear-stream $_test-input-buffered-file->buffer) + 3416 (clear-stream _test-output-stream) + 3417 (clear-stream $_test-output-buffered-file->buffer) + 3418 (clear-stream _test-error-stream) + 3419 (clear-stream $_test-error-buffered-file->buffer) + 3420 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3421 68/push 0/imm32 + 3422 68/push 0/imm32 + 3423 89/<- %edx 4/r32/esp + 3424 (tailor-exit-descriptor %edx 0x10) + 3425 # + 3426 (write _test-input-stream "fn f {\n") + 3427 (write _test-input-stream " g\n") + 3428 (write _test-input-stream "}\n") + 3429 (write _test-input-stream "fn g a: int {\n") + 3430 (write _test-input-stream "}\n") + 3431 # convert + 3432 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3433 # registers except esp clobbered at this point + 3434 # restore ed + 3435 89/<- %edx 4/r32/esp + 3436 (flush _test-output-buffered-file) + 3437 (flush _test-error-buffered-file) + 3438 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3444 # check output + 3445 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-inouts: output should be empty") + 3446 (check-next-stream-line-equal _test-error-stream "fn f: call g: too few inouts" "F - test-convert-function-call-with-too-few-inouts: error message") + 3447 # check that stop(1) was called + 3448 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-inouts: exit status") + 3449 # don't restore from ebp + 3450 81 0/subop/add %esp 8/imm32 + 3451 5d/pop-to-ebp + 3452 c3/return + 3453 + 3454 test-convert-function-call-with-too-many-inouts: + 3455 # . prologue + 3456 55/push-ebp + 3457 89/<- %ebp 4/r32/esp + 3458 # setup + 3459 (clear-stream _test-input-stream) + 3460 (clear-stream $_test-input-buffered-file->buffer) + 3461 (clear-stream _test-output-stream) + 3462 (clear-stream $_test-output-buffered-file->buffer) + 3463 (clear-stream _test-error-stream) + 3464 (clear-stream $_test-error-buffered-file->buffer) + 3465 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3466 68/push 0/imm32 + 3467 68/push 0/imm32 + 3468 89/<- %edx 4/r32/esp + 3469 (tailor-exit-descriptor %edx 0x10) + 3470 # + 3471 (write _test-input-stream "fn f {\n") + 3472 (write _test-input-stream " var x: int\n") + 3473 (write _test-input-stream " g x\n") + 3474 (write _test-input-stream "}\n") + 3475 (write _test-input-stream "fn g {\n") + 3476 (write _test-input-stream "}\n") + 3477 # convert + 3478 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3479 # registers except esp clobbered at this point + 3480 # restore ed + 3481 89/<- %edx 4/r32/esp + 3482 (flush _test-output-buffered-file) + 3483 (flush _test-error-buffered-file) + 3484 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3490 # check output + 3491 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-inouts: output should be empty") + 3492 (check-next-stream-line-equal _test-error-stream "fn f: call g: too many inouts" "F - test-convert-function-call-with-too-many-inouts: error message") + 3493 # check that stop(1) was called + 3494 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-inouts: exit status") + 3495 # don't restore from ebp + 3496 81 0/subop/add %esp 8/imm32 + 3497 5d/pop-to-ebp + 3498 c3/return + 3499 + 3500 test-convert-function-call-with-incorrect-output-type: + 3501 # . prologue + 3502 55/push-ebp + 3503 89/<- %ebp 4/r32/esp + 3504 # setup + 3505 (clear-stream _test-input-stream) + 3506 (clear-stream $_test-input-buffered-file->buffer) + 3507 (clear-stream _test-output-stream) + 3508 (clear-stream $_test-output-buffered-file->buffer) + 3509 (clear-stream _test-error-stream) + 3510 (clear-stream $_test-error-buffered-file->buffer) + 3511 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3512 68/push 0/imm32 + 3513 68/push 0/imm32 + 3514 89/<- %edx 4/r32/esp + 3515 (tailor-exit-descriptor %edx 0x10) + 3516 # + 3517 (write _test-input-stream "fn f {\n") + 3518 (write _test-input-stream " var x/eax: int <- g\n") + 3519 (write _test-input-stream "}\n") + 3520 (write _test-input-stream "fn g -> _/eax: foo {\n") + 3521 (write _test-input-stream "}\n") + 3522 # convert + 3523 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3524 # registers except esp clobbered at this point + 3525 # restore ed + 3526 89/<- %edx 4/r32/esp + 3527 (flush _test-output-buffered-file) + 3528 (flush _test-error-buffered-file) + 3529 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3535 # check output + 3536 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-type: output should be empty") + 3537 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for output 'x' is not right" "F - test-convert-function-call-with-incorrect-output-type: error message") + 3538 # check that stop(1) was called + 3539 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-type: exit status") + 3540 # don't restore from ebp + 3541 81 0/subop/add %esp 8/imm32 + 3542 5d/pop-to-ebp + 3543 c3/return + 3544 + 3545 test-convert-function-call-with-too-few-outputs: + 3546 # . prologue + 3547 55/push-ebp + 3548 89/<- %ebp 4/r32/esp + 3549 # setup + 3550 (clear-stream _test-input-stream) + 3551 (clear-stream $_test-input-buffered-file->buffer) + 3552 (clear-stream _test-output-stream) + 3553 (clear-stream $_test-output-buffered-file->buffer) + 3554 (clear-stream _test-error-stream) + 3555 (clear-stream $_test-error-buffered-file->buffer) + 3556 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3557 68/push 0/imm32 + 3558 68/push 0/imm32 + 3559 89/<- %edx 4/r32/esp + 3560 (tailor-exit-descriptor %edx 0x10) + 3561 # + 3562 (write _test-input-stream "fn f {\n") + 3563 (write _test-input-stream " g\n") + 3564 (write _test-input-stream "}\n") + 3565 (write _test-input-stream "fn g -> _/eax: int {\n") + 3566 (write _test-input-stream "}\n") + 3567 # convert + 3568 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3569 # registers except esp clobbered at this point + 3570 # restore ed + 3571 89/<- %edx 4/r32/esp + 3572 (flush _test-output-buffered-file) + 3573 (flush _test-error-buffered-file) + 3574 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3580 # check output + 3581 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-outputs: output should be empty") + 3582 (check-next-stream-line-equal _test-error-stream "fn f: call g: too few outputs" "F - test-convert-function-call-with-too-few-outputs: error message") + 3583 # check that stop(1) was called + 3584 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-outputs: exit status") + 3585 # don't restore from ebp + 3586 81 0/subop/add %esp 8/imm32 + 3587 5d/pop-to-ebp + 3588 c3/return + 3589 + 3590 test-convert-function-call-with-too-many-outputs: + 3591 # . prologue + 3592 55/push-ebp + 3593 89/<- %ebp 4/r32/esp + 3594 # setup + 3595 (clear-stream _test-input-stream) + 3596 (clear-stream $_test-input-buffered-file->buffer) + 3597 (clear-stream _test-output-stream) + 3598 (clear-stream $_test-output-buffered-file->buffer) + 3599 (clear-stream _test-error-stream) + 3600 (clear-stream $_test-error-buffered-file->buffer) + 3601 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3602 68/push 0/imm32 + 3603 68/push 0/imm32 + 3604 89/<- %edx 4/r32/esp + 3605 (tailor-exit-descriptor %edx 0x10) + 3606 # + 3607 (write _test-input-stream "fn f {\n") + 3608 (write _test-input-stream " var x/eax: int <- g\n") + 3609 (write _test-input-stream "}\n") + 3610 (write _test-input-stream "fn g {\n") + 3611 (write _test-input-stream "}\n") + 3612 # convert + 3613 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3614 # registers except esp clobbered at this point + 3615 # restore ed + 3616 89/<- %edx 4/r32/esp + 3617 (flush _test-output-buffered-file) + 3618 (flush _test-error-buffered-file) + 3619 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3625 # check output + 3626 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-outputs: output should be empty") + 3627 (check-next-stream-line-equal _test-error-stream "fn f: call g: too many outputs" "F - test-convert-function-call-with-too-many-outputs: error message") + 3628 # check that stop(1) was called + 3629 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-outputs: exit status") + 3630 # don't restore from ebp + 3631 81 0/subop/add %esp 8/imm32 + 3632 5d/pop-to-ebp + 3633 c3/return + 3634 + 3635 test-convert-function-call-with-missing-output-register: + 3636 # . prologue + 3637 55/push-ebp + 3638 89/<- %ebp 4/r32/esp + 3639 # setup + 3640 (clear-stream _test-input-stream) + 3641 (clear-stream $_test-input-buffered-file->buffer) + 3642 (clear-stream _test-output-stream) + 3643 (clear-stream $_test-output-buffered-file->buffer) + 3644 (clear-stream _test-error-stream) + 3645 (clear-stream $_test-error-buffered-file->buffer) + 3646 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3647 68/push 0/imm32 + 3648 68/push 0/imm32 + 3649 89/<- %edx 4/r32/esp + 3650 (tailor-exit-descriptor %edx 0x10) + 3651 # + 3652 (write _test-input-stream "fn f {\n") + 3653 (write _test-input-stream " var x: int\n") + 3654 (write _test-input-stream " x <- g\n") + 3655 (write _test-input-stream "}\n") + 3656 (write _test-input-stream "fn g -> _/eax: int {\n") + 3657 (write _test-input-stream "}\n") + 3658 # convert + 3659 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3660 # registers except esp clobbered at this point + 3661 # restore ed + 3662 89/<- %edx 4/r32/esp + 3663 (flush _test-output-buffered-file) + 3664 (flush _test-error-buffered-file) + 3665 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3671 # check output + 3672 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-missing-output-register: output should be empty") + 3673 (check-next-stream-line-equal _test-error-stream "fn f: call g: output 'x' is not in a register" "F - test-convert-function-call-with-missing-output-register: error message") + 3674 # check that stop(1) was called + 3675 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-missing-output-register: exit status") + 3676 # don't restore from ebp + 3677 81 0/subop/add %esp 8/imm32 + 3678 5d/pop-to-ebp + 3679 c3/return + 3680 + 3681 test-convert-function-call-with-incorrect-output-register: + 3682 # . prologue + 3683 55/push-ebp + 3684 89/<- %ebp 4/r32/esp + 3685 # setup + 3686 (clear-stream _test-input-stream) + 3687 (clear-stream $_test-input-buffered-file->buffer) + 3688 (clear-stream _test-output-stream) + 3689 (clear-stream $_test-output-buffered-file->buffer) + 3690 (clear-stream _test-error-stream) + 3691 (clear-stream $_test-error-buffered-file->buffer) + 3692 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3693 68/push 0/imm32 + 3694 68/push 0/imm32 + 3695 89/<- %edx 4/r32/esp + 3696 (tailor-exit-descriptor %edx 0x10) + 3697 # + 3698 (write _test-input-stream "fn f {\n") + 3699 (write _test-input-stream " var x/ecx: int <- g\n") + 3700 (write _test-input-stream "}\n") + 3701 (write _test-input-stream "fn g -> _/eax: int {\n") + 3702 (write _test-input-stream "}\n") + 3703 # convert + 3704 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3705 # registers except esp clobbered at this point + 3706 # restore ed + 3707 89/<- %edx 4/r32/esp + 3708 (flush _test-output-buffered-file) + 3709 (flush _test-error-buffered-file) + 3710 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3716 # check output + 3717 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-register: output should be empty") + 3718 (check-next-stream-line-equal _test-error-stream "fn f: call g: register for output 'x' is not right" "F - test-convert-function-call-with-incorrect-output-register: error message") + 3719 # check that stop(1) was called + 3720 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-register: exit status") + 3721 # don't restore from ebp + 3722 81 0/subop/add %esp 8/imm32 + 3723 5d/pop-to-ebp + 3724 c3/return + 3725 + 3726 test-convert-function-with-local-var-dereferenced: + 3727 # . prologue + 3728 55/push-ebp + 3729 89/<- %ebp 4/r32/esp + 3730 # setup + 3731 (clear-stream _test-input-stream) + 3732 (clear-stream $_test-input-buffered-file->buffer) + 3733 (clear-stream _test-output-stream) + 3734 (clear-stream $_test-output-buffered-file->buffer) + 3735 # + 3736 (write _test-input-stream "fn foo {\n") + 3737 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") + 3738 (write _test-input-stream " increment *x\n") + 3739 (write _test-input-stream "}\n") + 3740 # convert + 3741 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3742 (flush _test-output-buffered-file) + 3743 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3749 # check output + 3750 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0") + 3751 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1") + 3752 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2") + 3753 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3") + 3754 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4") + 3755 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5") + 3756 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6") + 3757 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7") + 3758 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8") + 3759 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9") + 3760 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10") + 3761 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11") + 3762 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12") + 3763 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13") + 3764 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14") + 3765 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15") + 3766 # . epilogue + 3767 89/<- %esp 5/r32/ebp + 3768 5d/pop-to-ebp + 3769 c3/return + 3770 + 3771 test-dereference-of-var-on-stack: + 3772 # . prologue + 3773 55/push-ebp + 3774 89/<- %ebp 4/r32/esp + 3775 # setup + 3776 (clear-stream _test-input-stream) + 3777 (clear-stream $_test-input-buffered-file->buffer) + 3778 (clear-stream _test-output-stream) + 3779 (clear-stream $_test-output-buffered-file->buffer) + 3780 (clear-stream _test-error-stream) + 3781 (clear-stream $_test-error-buffered-file->buffer) + 3782 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3783 68/push 0/imm32 + 3784 68/push 0/imm32 + 3785 89/<- %edx 4/r32/esp + 3786 (tailor-exit-descriptor %edx 0x10) + 3787 # + 3788 (write _test-input-stream "fn foo {\n") + 3789 (write _test-input-stream " var x: (addr int)\n") + 3790 (write _test-input-stream " increment *x\n") + 3791 (write _test-input-stream "}\n") + 3792 # convert + 3793 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3794 # registers except esp clobbered at this point + 3795 # restore ed + 3796 89/<- %edx 4/r32/esp + 3797 (flush _test-output-buffered-file) + 3798 (flush _test-error-buffered-file) + 3799 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3805 # check output + 3806 (check-stream-equal _test-output-stream "" "F - test-dereference-of-var-on-stack: output should be empty") + 3807 (check-next-stream-line-equal _test-error-stream "fn foo: cannot dereference var 'x' on stack" "F - test-dereference-of-var-on-stack: error message") + 3808 # check that stop(1) was called + 3809 (check-ints-equal *(edx+4) 2 "F - test-dereference-of-var-on-stack: exit status") + 3810 # don't restore from ebp + 3811 81 0/subop/add %esp 8/imm32 + 3812 # . epilogue + 3813 5d/pop-to-ebp + 3814 c3/return + 3815 + 3816 test-convert-function-with-byte-operations: + 3817 # . prologue + 3818 55/push-ebp + 3819 89/<- %ebp 4/r32/esp + 3820 # setup + 3821 (clear-stream _test-input-stream) + 3822 (clear-stream $_test-input-buffered-file->buffer) + 3823 (clear-stream _test-output-stream) + 3824 (clear-stream $_test-output-buffered-file->buffer) + 3825 # + 3826 (write _test-input-stream "fn foo {\n") + 3827 (write _test-input-stream " var x/eax: byte <- copy 0\n") + 3828 (write _test-input-stream " var y/ecx: byte <- copy 0\n") + 3829 (write _test-input-stream " y <- copy-byte x\n") + 3830 (write _test-input-stream " var z/edx: (addr byte) <- copy 0\n") + 3831 (write _test-input-stream " y <- copy-byte *z\n") + 3832 (write _test-input-stream " copy-byte-to *z, x\n") + 3833 (write _test-input-stream "}\n") + 3834 # convert + 3835 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3836 (flush _test-output-buffered-file) + 3837 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3843 # check output + 3844 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-byte-operations/0") + 3845 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-byte-operations/1") + 3846 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-byte-operations/2") + 3847 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-byte-operations/3") + 3848 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-byte-operations/4") + 3849 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-byte-operations/5") + 3850 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-byte-operations/6") + 3851 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-byte-operations/7") + 3852 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-byte-operations/8") + 3853 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-byte-operations/9") + 3854 (check-next-stream-line-equal _test-output-stream " 8a/byte-> %eax 0x00000001/r32" "F - test-convert-function-with-byte-operations/10") + 3855 (check-next-stream-line-equal _test-output-stream " 81 4/subop/and %ecx 0xff/imm32" "F - test-convert-function-with-byte-operations/11") + 3856 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/12") + 3857 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/13") + 3858 (check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/14") + 3859 (check-next-stream-line-equal _test-output-stream " 81 4/subop/and %ecx 0xff/imm32" "F - test-convert-function-with-byte-operations/15") + 3860 (check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/16") + 3861 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/17") + 3862 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/18") + 3863 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/19") + 3864 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/20") + 3865 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/21") + 3866 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/22") + 3867 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/23") + 3868 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/24") + 3869 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/25") + 3870 # . epilogue + 3871 89/<- %esp 5/r32/ebp + 3872 5d/pop-to-ebp + 3873 c3/return + 3874 + 3875 # variables of type 'byte' are not allowed on the stack + 3876 test-byte-values-on-stack: + 3877 # . prologue + 3878 55/push-ebp + 3879 89/<- %ebp 4/r32/esp + 3880 # setup + 3881 (clear-stream _test-input-stream) + 3882 (clear-stream $_test-input-buffered-file->buffer) + 3883 (clear-stream _test-output-stream) + 3884 (clear-stream $_test-output-buffered-file->buffer) + 3885 (clear-stream _test-error-stream) + 3886 (clear-stream $_test-error-buffered-file->buffer) + 3887 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3888 68/push 0/imm32 + 3889 68/push 0/imm32 + 3890 89/<- %edx 4/r32/esp + 3891 (tailor-exit-descriptor %edx 0x10) + 3892 # + 3893 (write _test-input-stream "fn foo {\n") + 3894 (write _test-input-stream " var x: byte\n") + 3895 (write _test-input-stream "}\n") + 3896 # convert + 3897 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3898 # registers except esp clobbered at this point + 3899 # restore ed + 3900 89/<- %edx 4/r32/esp + 3901 (flush _test-output-buffered-file) + 3902 (flush _test-error-buffered-file) + 3903 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3909 # check output + 3910 (check-stream-equal _test-output-stream "" "F - test-byte-values-on-stack: output should be empty") + 3911 (check-next-stream-line-equal _test-error-stream "fn foo: var 'x' of type 'byte' cannot be on the stack" "F - test-byte-values-on-stack: error message") + 3912 # check that stop(1) was called + 3913 (check-ints-equal *(edx+4) 2 "F - test-byte-values-on-stack: exit status") + 3914 # don't restore from ebp + 3915 81 0/subop/add %esp 8/imm32 + 3916 # . epilogue + 3917 5d/pop-to-ebp + 3918 c3/return + 3919 + 3920 # variables of type 'byte' are not allowed in esi or edi + 3921 test-byte-values-in-unsupported-registers: + 3922 # . prologue + 3923 55/push-ebp + 3924 89/<- %ebp 4/r32/esp + 3925 # setup + 3926 (clear-stream _test-input-stream) + 3927 (clear-stream $_test-input-buffered-file->buffer) + 3928 (clear-stream _test-output-stream) + 3929 (clear-stream $_test-output-buffered-file->buffer) + 3930 (clear-stream _test-error-stream) + 3931 (clear-stream $_test-error-buffered-file->buffer) + 3932 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3933 68/push 0/imm32 + 3934 68/push 0/imm32 + 3935 89/<- %edx 4/r32/esp + 3936 (tailor-exit-descriptor %edx 0x10) + 3937 # + 3938 (write _test-input-stream "fn foo {\n") + 3939 (write _test-input-stream " var x/esi: byte <- copy 0\n") + 3940 (write _test-input-stream "}\n") + 3941 # convert + 3942 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3943 # registers except esp clobbered at this point + 3944 # restore ed + 3945 89/<- %edx 4/r32/esp + 3946 (flush _test-output-buffered-file) + 3947 (flush _test-error-buffered-file) + 3948 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3954 # check output + 3955 (check-stream-equal _test-output-stream "" "F - test-byte-values-in-unsupported-registers: output should be empty") + 3956 (check-next-stream-line-equal _test-error-stream "fn foo: var 'x' of type 'byte' cannot be in esi or edi" "F - test-byte-values-in-unsupported-registers: error message") + 3957 # check that stop(1) was called + 3958 (check-ints-equal *(edx+4) 2 "F - test-byte-values-in-unsupported-registers: exit status") + 3959 # don't restore from ebp + 3960 81 0/subop/add %esp 8/imm32 + 3961 # . epilogue + 3962 5d/pop-to-ebp + 3963 c3/return + 3964 + 3965 # variables of type 'byte' _can_ be function args. They then occupy 4 bytes. + 3966 test-copy-byte-var-from-fn-arg: + 3967 # . prologue + 3968 55/push-ebp + 3969 89/<- %ebp 4/r32/esp + 3970 # setup + 3971 (clear-stream _test-input-stream) + 3972 (clear-stream $_test-input-buffered-file->buffer) + 3973 (clear-stream _test-output-stream) + 3974 (clear-stream $_test-output-buffered-file->buffer) + 3975 # + 3976 (write _test-input-stream "fn foo x: byte, y: int {\n") + 3977 (write _test-input-stream " var a/eax: byte <- copy x\n") + 3978 (write _test-input-stream " var b/eax: int <- copy y\n") + 3979 (write _test-input-stream "}\n") + 3980 # convert + 3981 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3982 (flush _test-output-buffered-file) + 3983 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3989 # check output + 3990 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-copy-byte-from-fn-arg/0") + 3991 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-copy-byte-from-fn-arg/1") + 3992 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-copy-byte-from-fn-arg/2") + 3993 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-copy-byte-from-fn-arg/3") + 3994 (check-next-stream-line-equal _test-output-stream " {" "F - test-copy-byte-from-fn-arg/4") + 3995 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-copy-byte-from-fn-arg/5") + 3996 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-copy-byte-from-fn-arg/6") + 3997 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/7") + 3998 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x0000000c) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/8") + 3999 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-copy-byte-from-fn-arg/9") + 4000 (check-next-stream-line-equal _test-output-stream " }" "F - test-copy-byte-from-fn-arg/10") + 4001 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-copy-byte-from-fn-arg/11") + 4002 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-copy-byte-from-fn-arg/12") + 4003 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-copy-byte-from-fn-arg/13") + 4004 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-copy-byte-from-fn-arg/14") + 4005 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-copy-byte-from-fn-arg/15") + 4006 # . epilogue + 4007 89/<- %esp 5/r32/ebp + 4008 5d/pop-to-ebp + 4009 c3/return + 4010 + 4011 test-convert-compare-register-with-literal: + 4012 # . prologue + 4013 55/push-ebp + 4014 89/<- %ebp 4/r32/esp + 4015 # setup + 4016 (clear-stream _test-input-stream) + 4017 (clear-stream $_test-input-buffered-file->buffer) + 4018 (clear-stream _test-output-stream) + 4019 (clear-stream $_test-output-buffered-file->buffer) + 4020 # + 4021 (write _test-input-stream "fn foo {\n") + 4022 (write _test-input-stream " var x/ecx: int <- copy 0\n") + 4023 (write _test-input-stream " compare x, 0\n") + 4024 (write _test-input-stream "}\n") + 4025 # convert + 4026 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4027 (flush _test-output-buffered-file) + 4028 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4034 # check output + 4035 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0") + 4036 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1") + 4037 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2") + 4038 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3") + 4039 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4") + 4040 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5") + 4041 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") + 4042 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7") + 4043 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8") + 4044 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") + 4045 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10") + 4046 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11") + 4047 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12") + 4048 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13") + 4049 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14") + 4050 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15") + 4051 # . epilogue + 4052 89/<- %esp 5/r32/ebp + 4053 5d/pop-to-ebp + 4054 c3/return + 4055 + 4056 test-convert-compare-byte-with-literal: + 4057 # . prologue + 4058 55/push-ebp + 4059 89/<- %ebp 4/r32/esp + 4060 # setup + 4061 (clear-stream _test-input-stream) + 4062 (clear-stream $_test-input-buffered-file->buffer) + 4063 (clear-stream _test-output-stream) + 4064 (clear-stream $_test-output-buffered-file->buffer) + 4065 # + 4066 (write _test-input-stream "fn foo {\n") + 4067 (write _test-input-stream " var x/ecx: byte <- copy 0\n") + 4068 (write _test-input-stream " compare x, 0\n") + 4069 (write _test-input-stream "}\n") + 4070 # convert + 4071 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4072 (flush _test-output-buffered-file) + 4073 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4079 # no errors; output is identical to test-convert-compare-register-with-literal + 4080 # . epilogue + 4081 89/<- %esp 5/r32/ebp + 4082 5d/pop-to-ebp + 4083 c3/return + 4084 + 4085 test-unknown-variable: + 4086 # . prologue + 4087 55/push-ebp + 4088 89/<- %ebp 4/r32/esp + 4089 # setup + 4090 (clear-stream _test-input-stream) + 4091 (clear-stream $_test-input-buffered-file->buffer) + 4092 (clear-stream _test-output-stream) + 4093 (clear-stream $_test-output-buffered-file->buffer) + 4094 (clear-stream _test-error-stream) + 4095 (clear-stream $_test-error-buffered-file->buffer) + 4096 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4097 68/push 0/imm32 + 4098 68/push 0/imm32 + 4099 89/<- %edx 4/r32/esp + 4100 (tailor-exit-descriptor %edx 0x10) + 4101 # + 4102 (write _test-input-stream "fn foo {\n") + 4103 (write _test-input-stream " compare x, 0\n") + 4104 (write _test-input-stream "}\n") + 4105 # convert + 4106 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4107 # registers except esp clobbered at this point + 4108 # restore ed + 4109 89/<- %edx 4/r32/esp + 4110 (flush _test-output-buffered-file) + 4111 (flush _test-error-buffered-file) + 4112 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4118 # check output + 4119 (check-stream-equal _test-output-stream "" "F - test-unknown-variable: output should be empty") + 4120 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable: error message") + 4121 # check that stop(1) was called + 4122 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable: exit status") + 4123 # don't restore from ebp + 4124 81 0/subop/add %esp 8/imm32 + 4125 # . epilogue + 4126 5d/pop-to-ebp + 4127 c3/return + 4128 + 4129 test-convert-function-with-local-var-in-block: + 4130 # . prologue + 4131 55/push-ebp + 4132 89/<- %ebp 4/r32/esp + 4133 # setup + 4134 (clear-stream _test-input-stream) + 4135 (clear-stream $_test-input-buffered-file->buffer) + 4136 (clear-stream _test-output-stream) + 4137 (clear-stream $_test-output-buffered-file->buffer) + 4138 # + 4139 (write _test-input-stream "fn foo {\n") + 4140 (write _test-input-stream " {\n") + 4141 (write _test-input-stream " var x: int\n") + 4142 (write _test-input-stream " increment x\n") + 4143 (write _test-input-stream " }\n") + 4144 (write _test-input-stream "}\n") + 4145 # convert + 4146 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4147 (flush _test-output-buffered-file) + 4148 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4154 # check output + 4155 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0") + 4156 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1") + 4157 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2") + 4158 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3") + 4159 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4") + 4160 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5") + 4161 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6") + 4162 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7") + 4163 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8") + 4164 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9") + 4165 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-block/10") + 4166 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11") + 4167 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12") + 4168 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13") + 4169 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14") + 4170 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15") + 4171 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16") + 4172 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17") + 4173 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18") + 4174 # . epilogue + 4175 89/<- %esp 5/r32/ebp + 4176 5d/pop-to-ebp + 4177 c3/return + 4178 + 4179 test-convert-function-with-local-var-in-mem-after-block: + 4180 # . prologue + 4181 55/push-ebp + 4182 89/<- %ebp 4/r32/esp + 4183 # setup + 4184 (clear-stream _test-input-stream) + 4185 (clear-stream $_test-input-buffered-file->buffer) + 4186 (clear-stream _test-output-stream) + 4187 (clear-stream $_test-output-buffered-file->buffer) + 4188 # + 4189 (write _test-input-stream "fn foo {\n") + 4190 (write _test-input-stream " {\n") + 4191 (write _test-input-stream " var y: int\n") + 4192 (write _test-input-stream " }\n") + 4193 (write _test-input-stream " var x: int\n") + 4194 (write _test-input-stream " increment x\n") + 4195 (write _test-input-stream "}\n") + 4196 # convert + 4197 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4198 (flush _test-output-buffered-file) + 4199 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4205 # check output + 4206 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem-after-block/0") + 4207 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem-after-block/1") + 4208 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem-after-block/2") + 4209 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem-after-block/3") + 4210 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem-after-block/4") + 4211 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem-after-block/5") + 4212 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem-after-block/6") + 4213 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-mem-after-block/7") + 4214 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/8") + 4215 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/9") + 4216 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem-after-block/10") + 4217 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-mem-after-block/11") + 4218 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/12") + 4219 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem-after-block/13") + 4220 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/14") + 4221 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem-after-block/15") + 4222 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem-after-block/16") + 4223 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem-after-block/17") + 4224 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem-after-block/18") + 4225 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem-after-block/19") + 4226 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem-after-block/20") + 4227 # . epilogue + 4228 89/<- %esp 5/r32/ebp + 4229 5d/pop-to-ebp + 4230 c3/return + 4231 + 4232 test-convert-function-with-local-var-in-named-block: + 4233 # . prologue + 4234 55/push-ebp + 4235 89/<- %ebp 4/r32/esp + 4236 # setup + 4237 (clear-stream _test-input-stream) + 4238 (clear-stream $_test-input-buffered-file->buffer) + 4239 (clear-stream _test-output-stream) + 4240 (clear-stream $_test-output-buffered-file->buffer) + 4241 # + 4242 (write _test-input-stream "fn foo {\n") + 4243 (write _test-input-stream " $bar: {\n") + 4244 (write _test-input-stream " var x: int\n") + 4245 (write _test-input-stream " increment x\n") + 4246 (write _test-input-stream " }\n") + 4247 (write _test-input-stream "}\n") + 4248 # convert + 4249 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4250 (flush _test-output-buffered-file) + 4251 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4257 # check output + 4258 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0") + 4259 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1") + 4260 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2") + 4261 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3") + 4262 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4") + 4263 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5") + 4264 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6") + 4265 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7") + 4266 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8") + 4267 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-named-block/9") + 4268 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-named-block/10") + 4269 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11") + 4270 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12") + 4271 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13") + 4272 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14") + 4273 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15") + 4274 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16") + 4275 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17") + 4276 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18") + 4277 # . epilogue + 4278 89/<- %esp 5/r32/ebp + 4279 5d/pop-to-ebp + 4280 c3/return + 4281 + 4282 test-unknown-variable-in-named-block: + 4283 # . prologue + 4284 55/push-ebp + 4285 89/<- %ebp 4/r32/esp + 4286 # setup + 4287 (clear-stream _test-input-stream) + 4288 (clear-stream $_test-input-buffered-file->buffer) + 4289 (clear-stream _test-output-stream) + 4290 (clear-stream $_test-output-buffered-file->buffer) + 4291 (clear-stream _test-error-stream) + 4292 (clear-stream $_test-error-buffered-file->buffer) + 4293 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4294 68/push 0/imm32 + 4295 68/push 0/imm32 + 4296 89/<- %edx 4/r32/esp + 4297 (tailor-exit-descriptor %edx 0x10) + 4298 # + 4299 (write _test-input-stream "fn foo {\n") + 4300 (write _test-input-stream " $a: {\n") + 4301 (write _test-input-stream " compare x, 0\n") + 4302 (write _test-input-stream " }\n") + 4303 (write _test-input-stream "}\n") + 4304 # convert + 4305 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4306 # registers except esp clobbered at this point + 4307 # restore ed + 4308 89/<- %edx 4/r32/esp + 4309 (flush _test-output-buffered-file) + 4310 (flush _test-error-buffered-file) + 4311 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4317 # check output + 4318 (check-stream-equal _test-output-stream "" "F - test-unknown-variable-in-named-block: output should be empty") + 4319 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable-in-named-block: error message") + 4320 # check that stop(1) was called + 4321 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable-in-named-block: exit status") + 4322 # don't restore from ebp + 4323 81 0/subop/add %esp 8/imm32 + 4324 # . epilogue + 4325 5d/pop-to-ebp + 4326 c3/return + 4327 + 4328 test-always-shadow-outermost-reg-vars-in-function: + 4329 # . prologue + 4330 55/push-ebp + 4331 89/<- %ebp 4/r32/esp + 4332 # setup + 4333 (clear-stream _test-input-stream) + 4334 (clear-stream $_test-input-buffered-file->buffer) + 4335 (clear-stream _test-output-stream) + 4336 (clear-stream $_test-output-buffered-file->buffer) + 4337 # + 4338 (write _test-input-stream "fn foo {\n") + 4339 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 4340 (write _test-input-stream "}\n") + 4341 # convert + 4342 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4343 (flush _test-output-buffered-file) + 4344 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4350 # check output + 4351 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0") + 4352 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1") + 4353 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2") + 4354 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3") + 4355 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4") + 4356 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5") + 4357 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") + 4358 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8") + 4359 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") + 4360 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12") + 4361 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13") + 4362 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14") + 4363 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15") + 4364 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16") + 4365 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17") + 4366 # . epilogue + 4367 89/<- %esp 5/r32/ebp + 4368 5d/pop-to-ebp + 4369 c3/return + 4370 + 4371 test-shadow-local: + 4372 # . prologue + 4373 55/push-ebp + 4374 89/<- %ebp 4/r32/esp + 4375 # setup + 4376 (clear-stream _test-input-stream) + 4377 (clear-stream $_test-input-buffered-file->buffer) + 4378 (clear-stream _test-output-stream) + 4379 (clear-stream $_test-output-buffered-file->buffer) + 4380 # + 4381 (write _test-input-stream "fn foo {\n") + 4382 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 4383 (write _test-input-stream " {\n") + 4384 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 4385 (write _test-input-stream " }\n") + 4386 (write _test-input-stream " x <- increment\n") + 4387 (write _test-input-stream "}\n") + 4388 # convert + 4389 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4390 (flush _test-output-buffered-file) + 4391 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4397 # check output + 4398 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-local/0") + 4399 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-local/1") + 4400 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-local/2") + 4401 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-local/3") + 4402 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-local/4") + 4403 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-local/5") + 4404 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-local/6") + 4405 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-local/7") + 4406 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-local/8") + 4407 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-local/9") + 4408 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-local/10") + 4409 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-local/11") + 4410 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-local/12") + 4411 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-local/13") + 4412 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-local/14") + 4413 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-local/15") + 4414 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-local/16") + 4415 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-local/17") + 4416 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-local/18") + 4417 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-local/19") + 4418 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-local/20") + 4419 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-local/21") + 4420 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-local/22") + 4421 # . epilogue + 4422 89/<- %esp 5/r32/ebp + 4423 5d/pop-to-ebp + 4424 c3/return + 4425 + 4426 test-shadow-name: + 4427 # . prologue + 4428 55/push-ebp + 4429 89/<- %ebp 4/r32/esp + 4430 # setup + 4431 (clear-stream _test-input-stream) + 4432 (clear-stream $_test-input-buffered-file->buffer) + 4433 (clear-stream _test-output-stream) + 4434 (clear-stream $_test-output-buffered-file->buffer) + 4435 # + 4436 (write _test-input-stream "fn foo {\n") + 4437 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 4438 (write _test-input-stream " {\n") + 4439 (write _test-input-stream " var x/edx: int <- copy 4\n") + 4440 (write _test-input-stream " }\n") + 4441 (write _test-input-stream " x <- increment\n") + 4442 (write _test-input-stream "}\n") + 4443 # convert + 4444 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4445 (flush _test-output-buffered-file) + 4446 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4452 # check output + 4453 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name/0") + 4454 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name/1") + 4455 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name/2") + 4456 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name/3") + 4457 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/4") + 4458 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name/5") + 4459 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name/6") + 4460 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name/7") + 4461 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/8") + 4462 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name/9") + 4463 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name/10") + 4464 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name/11") + 4465 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name/12") + 4466 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/13") + 4467 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name/14") + 4468 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name/15") + 4469 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name/16") + 4470 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/17") + 4471 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name/18") + 4472 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name/19") + 4473 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name/20") + 4474 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name/21") + 4475 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name/22") + 4476 # . epilogue + 4477 89/<- %esp 5/r32/ebp + 4478 5d/pop-to-ebp + 4479 c3/return + 4480 + 4481 test-shadow-name-2: + 4482 # . prologue + 4483 55/push-ebp + 4484 89/<- %ebp 4/r32/esp + 4485 # setup + 4486 (clear-stream _test-input-stream) + 4487 (clear-stream $_test-input-buffered-file->buffer) + 4488 (clear-stream _test-output-stream) + 4489 (clear-stream $_test-output-buffered-file->buffer) + 4490 # + 4491 (write _test-input-stream "fn foo {\n") + 4492 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 4493 (write _test-input-stream " {\n") + 4494 (write _test-input-stream " var x/edx: int <- copy 4\n") + 4495 (write _test-input-stream " var y/ecx: int <- copy 5\n") + 4496 (write _test-input-stream " }\n") + 4497 (write _test-input-stream " x <- increment\n") + 4498 (write _test-input-stream "}\n") + 4499 # convert + 4500 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4501 (flush _test-output-buffered-file) + 4502 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4508 # check output + 4509 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name-2/0") + 4510 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name-2/1") + 4511 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name-2/2") + 4512 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name-2/3") + 4513 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/4") + 4514 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name-2/5") + 4515 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/6") + 4516 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name-2/7") + 4517 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/8") + 4518 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name-2/9") + 4519 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name-2/10") + 4520 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name-2/11") + 4521 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/12") + 4522 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 5/imm32" "F - test-shadow-name-2/13") + 4523 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/14") + 4524 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name-2/15") + 4525 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/16") + 4526 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name-2/17") + 4527 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name-2/18") + 4528 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/19") + 4529 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/20") + 4530 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name-2/21") + 4531 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name-2/22") + 4532 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name-2/23") + 4533 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name-2/24") + 4534 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name-2/25") + 4535 # . epilogue + 4536 89/<- %esp 5/r32/ebp + 4537 5d/pop-to-ebp + 4538 c3/return + 4539 + 4540 test-do-not-spill-same-register-in-block: + 4541 # . prologue + 4542 55/push-ebp + 4543 89/<- %ebp 4/r32/esp + 4544 # setup + 4545 (clear-stream _test-input-stream) + 4546 (clear-stream $_test-input-buffered-file->buffer) + 4547 (clear-stream _test-output-stream) + 4548 (clear-stream $_test-output-buffered-file->buffer) + 4549 # + 4550 (write _test-input-stream "fn foo {\n") + 4551 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 4552 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 4553 (write _test-input-stream " y <- increment\n") + 4554 (write _test-input-stream "}\n") + 4555 # convert + 4556 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4557 (flush _test-output-buffered-file) + 4558 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4564 # check output + 4565 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0") + 4566 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1") + 4567 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2") + 4568 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3") + 4569 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4") + 4570 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5") + 4571 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6") + 4572 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7") + 4573 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8") + 4574 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9") + 4575 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10") + 4576 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11") + 4577 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12") + 4578 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13") + 4579 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14") + 4580 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15") + 4581 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16") + 4582 # . epilogue + 4583 89/<- %esp 5/r32/ebp + 4584 5d/pop-to-ebp + 4585 c3/return + 4586 + 4587 test-spill-different-register-in-block: + 4588 # . prologue + 4589 55/push-ebp + 4590 89/<- %ebp 4/r32/esp + 4591 # setup + 4592 (clear-stream _test-input-stream) + 4593 (clear-stream $_test-input-buffered-file->buffer) + 4594 (clear-stream _test-output-stream) + 4595 (clear-stream $_test-output-buffered-file->buffer) + 4596 # + 4597 (write _test-input-stream "fn foo {\n") + 4598 (write _test-input-stream " var x/eax: int <- copy 3\n") + 4599 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 4600 (write _test-input-stream " y <- increment\n") + 4601 (write _test-input-stream "}\n") + 4602 # convert + 4603 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4604 (flush _test-output-buffered-file) + 4605 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4611 # check output + 4612 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0") + 4613 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1") + 4614 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2") + 4615 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3") + 4616 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4") + 4617 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5") + 4618 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6") + 4619 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7") + 4620 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8") + 4621 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9") + 4622 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10") + 4623 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11") + 4624 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12") + 4625 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13") + 4626 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14") + 4627 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15") + 4628 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16") + 4629 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17") + 4630 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18") + 4631 # . epilogue + 4632 89/<- %esp 5/r32/ebp + 4633 5d/pop-to-ebp + 4634 c3/return + 4635 + 4636 test-convert-function-with-branches-in-block: + 4637 # . prologue + 4638 55/push-ebp + 4639 89/<- %ebp 4/r32/esp + 4640 # setup + 4641 (clear-stream _test-input-stream) + 4642 (clear-stream $_test-input-buffered-file->buffer) + 4643 (clear-stream _test-output-stream) + 4644 (clear-stream $_test-output-buffered-file->buffer) + 4645 # + 4646 (write _test-input-stream "fn foo x: int {\n") + 4647 (write _test-input-stream " {\n") + 4648 (write _test-input-stream " break-if->=\n") + 4649 (write _test-input-stream " loop-if-addr<\n") + 4650 (write _test-input-stream " increment x\n") + 4651 (write _test-input-stream " loop\n") + 4652 (write _test-input-stream " }\n") + 4653 (write _test-input-stream "}\n") + 4654 # convert + 4655 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4656 (flush _test-output-buffered-file) + 4657 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4663 # check output + 4664 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") + 4665 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") + 4666 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") + 4667 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") + 4668 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") + 4669 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") + 4670 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") + 4671 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") + 4672 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") + 4673 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") + 4674 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") + 4675 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") + 4676 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") + 4677 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") + 4678 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") + 4679 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") + 4680 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") + 4681 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") + 4682 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") + 4683 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") + 4684 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") + 4685 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") + 4686 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") + 4687 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") + 4688 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") + 4689 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") + 4690 # . epilogue + 4691 89/<- %esp 5/r32/ebp + 4692 5d/pop-to-ebp + 4693 c3/return + 4694 + 4695 test-convert-function-with-branches-in-block-2: + 4696 # . prologue + 4697 55/push-ebp + 4698 89/<- %ebp 4/r32/esp + 4699 # setup + 4700 (clear-stream _test-input-stream) + 4701 (clear-stream $_test-input-buffered-file->buffer) + 4702 (clear-stream _test-output-stream) + 4703 (clear-stream $_test-output-buffered-file->buffer) + 4704 # + 4705 (write _test-input-stream "fn foo x: int {\n") + 4706 (write _test-input-stream " {\n") + 4707 (write _test-input-stream " break-if->=\n") + 4708 (write _test-input-stream " loop-if-float<\n") + 4709 (write _test-input-stream " increment x\n") + 4710 (write _test-input-stream " loop\n") + 4711 (write _test-input-stream " }\n") + 4712 (write _test-input-stream "}\n") + 4713 # convert + 4714 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4715 (flush _test-output-buffered-file) + 4716 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4722 # check output + 4723 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") + 4724 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") + 4725 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") + 4726 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") + 4727 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") + 4728 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") + 4729 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") + 4730 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") + 4731 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") + 4732 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") + 4733 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") + 4734 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") + 4735 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") + 4736 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") + 4737 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") + 4738 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") + 4739 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") + 4740 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") + 4741 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") + 4742 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") + 4743 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") + 4744 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") + 4745 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") + 4746 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") + 4747 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") + 4748 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") + 4749 # . epilogue + 4750 89/<- %esp 5/r32/ebp + 4751 5d/pop-to-ebp + 4752 c3/return + 4753 + 4754 test-convert-function-with-branches-in-named-block: + 4755 # . prologue + 4756 55/push-ebp + 4757 89/<- %ebp 4/r32/esp + 4758 # setup + 4759 (clear-stream _test-input-stream) + 4760 (clear-stream $_test-input-buffered-file->buffer) + 4761 (clear-stream _test-output-stream) + 4762 (clear-stream $_test-output-buffered-file->buffer) + 4763 # + 4764 (write _test-input-stream "fn foo x: int {\n") + 4765 (write _test-input-stream " $bar: {\n") + 4766 (write _test-input-stream " break-if->= $bar\n") + 4767 (write _test-input-stream " loop-if-addr< $bar\n") + 4768 (write _test-input-stream " increment x\n") + 4769 (write _test-input-stream " loop\n") + 4770 (write _test-input-stream " }\n") + 4771 (write _test-input-stream "}\n") + 4772 # convert + 4773 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4774 (flush _test-output-buffered-file) + 4775 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4781 # check output + 4782 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0") + 4783 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1") + 4784 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2") + 4785 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3") + 4786 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4") + 4787 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5") + 4788 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6") + 4789 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7") + 4790 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/8") + 4791 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-named-block/9") + 4792 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/10") + 4793 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/11") + 4794 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/12") + 4795 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-named-block/13") + 4796 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/14") + 4797 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/15") + 4798 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/16") + 4799 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/17") + 4800 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/18") + 4801 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/19") + 4802 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/20") + 4803 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/21") + 4804 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/22") + 4805 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/23") + 4806 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/24") + 4807 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/25") + 4808 # . epilogue + 4809 89/<- %esp 5/r32/ebp + 4810 5d/pop-to-ebp + 4811 c3/return + 4812 + 4813 test-convert-function-with-var-in-nested-block: + 4814 # . prologue + 4815 55/push-ebp + 4816 89/<- %ebp 4/r32/esp + 4817 # setup + 4818 (clear-stream _test-input-stream) + 4819 (clear-stream $_test-input-buffered-file->buffer) + 4820 (clear-stream _test-output-stream) + 4821 (clear-stream $_test-output-buffered-file->buffer) + 4822 # + 4823 (write _test-input-stream "fn foo x: int {\n") + 4824 (write _test-input-stream " {\n") + 4825 (write _test-input-stream " {\n") + 4826 (write _test-input-stream " var x: int\n") + 4827 (write _test-input-stream " increment x\n") + 4828 (write _test-input-stream " }\n") + 4829 (write _test-input-stream " }\n") + 4830 (write _test-input-stream "}\n") + 4831 # convert + 4832 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4833 (flush _test-output-buffered-file) + 4834 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4840 # check output + 4841 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0") + 4842 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1") + 4843 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2") + 4844 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3") + 4845 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4") + 4846 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5") + 4847 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6") + 4848 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7") + 4849 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8") + 4850 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9") + 4851 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10") + 4852 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11") + 4853 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-var-in-nested-block/12") + 4854 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13") + 4855 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14") + 4856 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15") + 4857 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16") + 4858 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17") + 4859 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18") + 4860 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19") + 4861 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20") + 4862 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21") + 4863 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22") + 4864 # . epilogue + 4865 89/<- %esp 5/r32/ebp + 4866 5d/pop-to-ebp + 4867 c3/return + 4868 + 4869 test-convert-function-with-multiple-vars-in-nested-blocks: + 4870 # . prologue + 4871 55/push-ebp + 4872 89/<- %ebp 4/r32/esp + 4873 # setup + 4874 (clear-stream _test-input-stream) + 4875 (clear-stream $_test-input-buffered-file->buffer) + 4876 (clear-stream _test-output-stream) + 4877 (clear-stream $_test-output-buffered-file->buffer) + 4878 # + 4879 (write _test-input-stream "fn foo x: int {\n") + 4880 (write _test-input-stream " {\n") + 4881 (write _test-input-stream " var x/eax: int <- copy 0\n") + 4882 (write _test-input-stream " {\n") + 4883 (write _test-input-stream " var y: int\n") + 4884 (write _test-input-stream " x <- add y\n") + 4885 (write _test-input-stream " }\n") + 4886 (write _test-input-stream " }\n") + 4887 (write _test-input-stream "}\n") + 4888 # convert + 4889 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4890 (flush _test-output-buffered-file) + 4891 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4897 # check output + 4898 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0") + 4899 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1") + 4900 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2") + 4901 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3") + 4902 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4") + 4903 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5") + 4904 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6") + 4905 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7") + 4906 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8") + 4907 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/9") + 4908 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10") + 4909 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11") + 4910 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12") + 4911 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/13") + 4912 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/14") + 4913 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15") + 4914 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16") + 4915 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17") + 4916 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18") + 4917 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19") + 4918 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20") + 4919 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21") + 4920 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22") + 4921 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23") + 4922 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24") + 4923 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25") + 4924 # . epilogue + 4925 89/<- %esp 5/r32/ebp + 4926 5d/pop-to-ebp + 4927 c3/return + 4928 + 4929 test-convert-function-with-branches-and-local-vars: + 4930 # A conditional 'break' after a 'var' in a block is converted into a + 4931 # nested block that performs all necessary cleanup before jumping. This + 4932 # results in some ugly code duplication. + 4933 # . prologue + 4934 55/push-ebp + 4935 89/<- %ebp 4/r32/esp + 4936 # setup + 4937 (clear-stream _test-input-stream) + 4938 (clear-stream $_test-input-buffered-file->buffer) + 4939 (clear-stream _test-output-stream) + 4940 (clear-stream $_test-output-buffered-file->buffer) + 4941 # + 4942 (write _test-input-stream "fn foo {\n") + 4943 (write _test-input-stream " {\n") + 4944 (write _test-input-stream " var x: int\n") + 4945 (write _test-input-stream " break-if->=\n") + 4946 (write _test-input-stream " increment x\n") + 4947 (write _test-input-stream " }\n") + 4948 (write _test-input-stream "}\n") + 4949 # convert + 4950 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4951 (flush _test-output-buffered-file) + 4952 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4958 # check output + 4959 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0") + 4960 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1") + 4961 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2") + 4962 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3") + 4963 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4") + 4964 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5") + 4965 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6") + 4966 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7") + 4967 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8") + 4968 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9") + 4969 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10") + 4970 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/11") + 4971 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12") + 4972 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13") + 4973 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14") + 4974 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/15") + 4975 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16") + 4976 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17") + 4977 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18") + 4978 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19") + 4979 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20") + 4980 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21") + 4981 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22") + 4982 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23") + 4983 # . epilogue + 4984 89/<- %esp 5/r32/ebp + 4985 5d/pop-to-ebp + 4986 c3/return + 4987 + 4988 test-convert-function-with-conditional-loops-and-local-vars: + 4989 # A conditional 'loop' after a 'var' in a block is converted into a nested + 4990 # block that performs all necessary cleanup before jumping. This results + 4991 # in some ugly code duplication. + 4992 # . prologue + 4993 55/push-ebp + 4994 89/<- %ebp 4/r32/esp + 4995 # setup + 4996 (clear-stream _test-input-stream) + 4997 (clear-stream $_test-input-buffered-file->buffer) + 4998 (clear-stream _test-output-stream) + 4999 (clear-stream $_test-output-buffered-file->buffer) + 5000 # + 5001 (write _test-input-stream "fn foo {\n") + 5002 (write _test-input-stream " {\n") + 5003 (write _test-input-stream " var x: int\n") + 5004 (write _test-input-stream " loop-if->=\n") + 5005 (write _test-input-stream " increment x\n") + 5006 (write _test-input-stream " }\n") + 5007 (write _test-input-stream "}\n") + 5008 # convert + 5009 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5010 (flush _test-output-buffered-file) + 5011 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5017 # check output + 5018 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0") + 5019 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1") + 5020 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2") + 5021 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3") + 5022 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4") + 5023 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5") + 5024 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6") + 5025 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7") + 5026 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8") + 5027 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9") + 5028 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/10") + 5029 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/11") + 5030 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/12") + 5031 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13") + 5032 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-conditional-loops-and-local-vars/14") + 5033 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/15") + 5034 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16") + 5035 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17") + 5036 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18") + 5037 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19") + 5038 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20") + 5039 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21") + 5040 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22") + 5041 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23") + 5042 # . epilogue + 5043 89/<- %esp 5/r32/ebp + 5044 5d/pop-to-ebp + 5045 c3/return + 5046 + 5047 test-convert-function-with-unconditional-loops-and-local-vars: + 5048 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the + 5049 # regular block cleanup. Any instructions after 'loop' are dead and + 5050 # therefore skipped. + 5051 # . prologue + 5052 55/push-ebp + 5053 89/<- %ebp 4/r32/esp + 5054 # setup + 5055 (clear-stream _test-input-stream) + 5056 (clear-stream $_test-input-buffered-file->buffer) + 5057 (clear-stream _test-output-stream) + 5058 (clear-stream $_test-output-buffered-file->buffer) + 5059 # + 5060 (write _test-input-stream "fn foo {\n") + 5061 (write _test-input-stream " {\n") + 5062 (write _test-input-stream " var x: int\n") + 5063 (write _test-input-stream " loop\n") + 5064 (write _test-input-stream " increment x\n") + 5065 (write _test-input-stream " }\n") + 5066 (write _test-input-stream "}\n") + 5067 # convert + 5068 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5069 (flush _test-output-buffered-file) + 5070 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5076 # check output + 5077 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0") + 5078 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1") + 5079 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2") + 5080 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3") + 5081 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4") + 5082 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5") + 5083 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6") + 5084 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7") + 5085 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8") + 5086 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/9") + 5087 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10") + 5088 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc) + 5089 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11") + 5090 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12") + 5091 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13") + 5092 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14") + 5093 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15") + 5094 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16") + 5095 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17") + 5096 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18") + 5097 # . epilogue + 5098 89/<- %esp 5/r32/ebp + 5099 5d/pop-to-ebp + 5100 c3/return + 5101 + 5102 test-convert-function-with-branches-and-loops-and-local-vars: + 5103 # . prologue + 5104 55/push-ebp + 5105 89/<- %ebp 4/r32/esp + 5106 # setup + 5107 (clear-stream _test-input-stream) + 5108 (clear-stream $_test-input-buffered-file->buffer) + 5109 (clear-stream _test-output-stream) + 5110 (clear-stream $_test-output-buffered-file->buffer) + 5111 # + 5112 (write _test-input-stream "fn foo {\n") + 5113 (write _test-input-stream " {\n") + 5114 (write _test-input-stream " var x: int\n") + 5115 (write _test-input-stream " break-if->=\n") + 5116 (write _test-input-stream " increment x\n") + 5117 (write _test-input-stream " loop\n") + 5118 (write _test-input-stream " }\n") + 5119 (write _test-input-stream "}\n") + 5120 # convert + 5121 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5122 (flush _test-output-buffered-file) + 5123 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5129 # check output + 5130 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0") + 5131 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1") + 5132 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2") + 5133 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-loops-and-local-vars/3") + 5134 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4") + 5135 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5") + 5136 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6") + 5137 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7") + 5138 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8") + 5139 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9") + 5140 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/10") + 5141 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/11") + 5142 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/12") + 5143 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13") + 5144 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-loops-and-local-vars/14") + 5145 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/15") + 5146 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16") + 5147 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17") + 5148 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18") + 5149 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19") + 5150 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20") + 5151 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21") + 5152 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/22") + 5153 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23") + 5154 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24") + 5155 # . epilogue + 5156 89/<- %esp 5/r32/ebp + 5157 5d/pop-to-ebp + 5158 c3/return + 5159 + 5160 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars: + 5161 # . prologue + 5162 55/push-ebp + 5163 89/<- %ebp 4/r32/esp + 5164 # setup + 5165 (clear-stream _test-input-stream) + 5166 (clear-stream $_test-input-buffered-file->buffer) + 5167 (clear-stream _test-output-stream) + 5168 (clear-stream $_test-output-buffered-file->buffer) + 5169 # + 5170 (write _test-input-stream "fn foo {\n") + 5171 (write _test-input-stream " a: {\n") + 5172 (write _test-input-stream " var x: int\n") + 5173 (write _test-input-stream " {\n") + 5174 (write _test-input-stream " var y: int\n") + 5175 (write _test-input-stream " break-if->= a\n") + 5176 (write _test-input-stream " increment x\n") + 5177 (write _test-input-stream " loop\n") + 5178 (write _test-input-stream " }\n") + 5179 (write _test-input-stream " }\n") + 5180 (write _test-input-stream "}\n") + 5181 # convert + 5182 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5183 (flush _test-output-buffered-file) + 5184 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5190 # check output + 5191 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0") + 5192 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1") + 5193 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2") + 5194 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/3") + 5195 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4") + 5196 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5") + 5197 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6") + 5198 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7") + 5199 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/8") + 5200 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9") + 5201 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10") + 5202 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/11") + 5203 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12") + 5204 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/13") + 5205 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/14") + 5206 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/15") + 5207 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/16") + 5208 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17") + 5209 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/18") + 5210 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/19") + 5211 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/20") + 5212 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21") + 5213 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22") + 5214 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/23") + 5215 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24") + 5216 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25") + 5217 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26") + 5218 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27") + 5219 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28") + 5220 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/29") + 5221 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/30") + 5222 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31") + 5223 # . epilogue + 5224 89/<- %esp 5/r32/ebp + 5225 5d/pop-to-ebp + 5226 c3/return + 5227 + 5228 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2: + 5229 # . prologue + 5230 55/push-ebp + 5231 89/<- %ebp 4/r32/esp + 5232 # setup + 5233 (clear-stream _test-input-stream) + 5234 (clear-stream $_test-input-buffered-file->buffer) + 5235 (clear-stream _test-output-stream) + 5236 (clear-stream $_test-output-buffered-file->buffer) + 5237 # non-local conditional branch from a block without a local variable, + 5238 # unwinding a local on the stack + 5239 (write _test-input-stream "fn foo {\n") + 5240 (write _test-input-stream " a: {\n") + 5241 (write _test-input-stream " var x: int\n") + 5242 (write _test-input-stream " {\n") + 5243 (write _test-input-stream " break-if->= a\n") + 5244 (write _test-input-stream " }\n") + 5245 (write _test-input-stream " }\n") + 5246 (write _test-input-stream "}\n") + 5247 # convert + 5248 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5249 (flush _test-output-buffered-file) + 5250 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5256 # check output + 5257 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0") + 5258 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1") + 5259 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/2") + 5260 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/3") + 5261 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4") + 5262 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/5") + 5263 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6") + 5264 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7") + 5265 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/8") + 5266 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9") + 5267 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/10") + 5268 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11") + 5269 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/12") + 5270 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/13") + 5271 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/14") + 5272 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15") + 5273 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16") + 5274 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/17") + 5275 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/18") + 5276 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19") + 5277 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20") + 5278 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21") + 5279 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/22") + 5280 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23") + 5281 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/24") + 5282 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/25") + 5283 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26") + 5284 # . epilogue + 5285 89/<- %esp 5/r32/ebp + 5286 5d/pop-to-ebp + 5287 c3/return + 5288 + 5289 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3: + 5290 # . prologue + 5291 55/push-ebp + 5292 89/<- %ebp 4/r32/esp + 5293 # setup + 5294 (clear-stream _test-input-stream) + 5295 (clear-stream $_test-input-buffered-file->buffer) + 5296 (clear-stream _test-output-stream) + 5297 (clear-stream $_test-output-buffered-file->buffer) + 5298 # non-local unconditional branch from a block without a local variable, + 5299 # unwinding a local on the stack + 5300 (write _test-input-stream "fn foo {\n") + 5301 (write _test-input-stream " a: {\n") + 5302 (write _test-input-stream " var x: int\n") + 5303 (write _test-input-stream " {\n") + 5304 (write _test-input-stream " break a\n") + 5305 (write _test-input-stream " }\n") + 5306 (write _test-input-stream " }\n") + 5307 (write _test-input-stream "}\n") + 5308 # convert + 5309 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5310 (flush _test-output-buffered-file) + 5311 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5317 # check output + 5318 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0") + 5319 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1") + 5320 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/2") + 5321 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/3") + 5322 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4") + 5323 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/5") + 5324 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6") + 5325 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7") + 5326 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/8") + 5327 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9") + 5328 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/10") + 5329 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/11") + 5330 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/12") + 5331 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14") + 5332 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/15") + 5333 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/16") + 5334 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17") + 5335 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18") + 5336 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19") + 5337 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/20") + 5338 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21") + 5339 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/22") + 5340 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/23") + 5341 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24") + 5342 # . epilogue + 5343 89/<- %esp 5/r32/ebp + 5344 5d/pop-to-ebp + 5345 c3/return + 5346 + 5347 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4: + 5348 # . prologue + 5349 55/push-ebp + 5350 89/<- %ebp 4/r32/esp + 5351 # setup + 5352 (clear-stream _test-input-stream) + 5353 (clear-stream $_test-input-buffered-file->buffer) + 5354 (clear-stream _test-output-stream) + 5355 (clear-stream $_test-output-buffered-file->buffer) + 5356 # + 5357 (write _test-input-stream "fn foo {\n") + 5358 (write _test-input-stream " a: {\n") + 5359 (write _test-input-stream " var x/esi: int <- copy 0\n") + 5360 (write _test-input-stream " {\n") + 5361 (write _test-input-stream " break a\n") + 5362 (write _test-input-stream " }\n") + 5363 (write _test-input-stream " }\n") + 5364 (write _test-input-stream "}\n") + 5365 # convert + 5366 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5367 (flush _test-output-buffered-file) + 5368 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5374 # check output + 5375 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0") + 5376 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1") + 5377 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/2") + 5378 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/3") + 5379 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4") + 5380 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/5") + 5381 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6") + 5382 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7") + 5383 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/8") + 5384 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/9") + 5385 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10") + 5386 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/11") + 5387 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/12") + 5388 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/13") + 5389 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/14") + 5390 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/15") + 5391 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/16") + 5392 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17") + 5393 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18") + 5394 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/19") + 5395 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/20") + 5396 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/21") + 5397 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/22") + 5398 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/23") + 5399 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24") + 5400 # . epilogue + 5401 89/<- %esp 5/r32/ebp + 5402 5d/pop-to-ebp + 5403 c3/return + 5404 + 5405 test-convert-function-with-nonlocal-unconditional-break-and-local-vars: + 5406 # . prologue + 5407 55/push-ebp + 5408 89/<- %ebp 4/r32/esp + 5409 # setup + 5410 (clear-stream _test-input-stream) + 5411 (clear-stream $_test-input-buffered-file->buffer) + 5412 (clear-stream _test-output-stream) + 5413 (clear-stream $_test-output-buffered-file->buffer) + 5414 # + 5415 (write _test-input-stream "fn foo {\n") + 5416 (write _test-input-stream " a: {\n") + 5417 (write _test-input-stream " var x: int\n") + 5418 (write _test-input-stream " {\n") + 5419 (write _test-input-stream " var y: int\n") + 5420 (write _test-input-stream " break a\n") + 5421 (write _test-input-stream " increment x\n") + 5422 (write _test-input-stream " }\n") + 5423 (write _test-input-stream " }\n") + 5424 (write _test-input-stream "}\n") + 5425 # convert + 5426 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5427 (flush _test-output-buffered-file) + 5428 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5434 # check output + 5435 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0") + 5436 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1") + 5437 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2") + 5438 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/3") + 5439 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4") + 5440 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5") + 5441 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6") + 5442 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7") + 5443 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8") + 5444 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9") + 5445 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10") + 5446 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11") + 5447 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/12") + 5448 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/13") + 5449 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/14") + 5450 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15") + 5451 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16") + 5452 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/17") + 5453 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18") + 5454 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19") + 5455 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20") + 5456 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21") + 5457 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22") + 5458 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/23") + 5459 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24") + 5460 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25") + 5461 # . epilogue + 5462 89/<- %esp 5/r32/ebp + 5463 5d/pop-to-ebp + 5464 c3/return + 5465 + 5466 test-convert-function-with-unconditional-break-and-local-vars: + 5467 # . prologue + 5468 55/push-ebp + 5469 89/<- %ebp 4/r32/esp + 5470 # setup + 5471 (clear-stream _test-input-stream) + 5472 (clear-stream $_test-input-buffered-file->buffer) + 5473 (clear-stream _test-output-stream) + 5474 (clear-stream $_test-output-buffered-file->buffer) + 5475 # + 5476 (write _test-input-stream "fn foo {\n") + 5477 (write _test-input-stream " {\n") + 5478 (write _test-input-stream " var x: int\n") + 5479 (write _test-input-stream " {\n") + 5480 (write _test-input-stream " var y: int\n") + 5481 (write _test-input-stream " break\n") + 5482 (write _test-input-stream " increment x\n") + 5483 (write _test-input-stream " }\n") + 5484 (write _test-input-stream " }\n") + 5485 (write _test-input-stream "}\n") + 5486 # convert + 5487 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5488 (flush _test-output-buffered-file) + 5489 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5495 # check output + 5496 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0") + 5497 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1") + 5498 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2") + 5499 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3") + 5500 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4") + 5501 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5") + 5502 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6") + 5503 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7") + 5504 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8") + 5505 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9") + 5506 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10") + 5507 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11") + 5508 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/12") + 5509 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13") + 5510 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14") + 5511 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/15") + 5512 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16") + 5513 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17") + 5514 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18") + 5515 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19") + 5516 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20") + 5517 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21") + 5518 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22") + 5519 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23") + 5520 # . epilogue + 5521 89/<- %esp 5/r32/ebp + 5522 5d/pop-to-ebp + 5523 c3/return + 5524 + 5525 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars: + 5526 # . prologue + 5527 55/push-ebp + 5528 89/<- %ebp 4/r32/esp + 5529 # setup + 5530 (clear-stream _test-input-stream) + 5531 (clear-stream $_test-input-buffered-file->buffer) + 5532 (clear-stream _test-output-stream) + 5533 (clear-stream $_test-output-buffered-file->buffer) + 5534 # + 5535 (write _test-input-stream "fn foo {\n") + 5536 (write _test-input-stream " a: {\n") + 5537 (write _test-input-stream " var x: int\n") + 5538 (write _test-input-stream " {\n") + 5539 (write _test-input-stream " var y: int\n") + 5540 (write _test-input-stream " loop a\n") + 5541 (write _test-input-stream " increment x\n") + 5542 (write _test-input-stream " }\n") + 5543 (write _test-input-stream " }\n") + 5544 (write _test-input-stream "}\n") + 5545 # convert + 5546 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5547 (flush _test-output-buffered-file) + 5548 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5554 # check output + 5555 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0") + 5556 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1") + 5557 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2") + 5558 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/3") + 5559 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4") + 5560 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5") + 5561 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6") + 5562 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7") + 5563 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8") + 5564 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9") + 5565 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10") + 5566 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11") + 5567 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/12") + 5568 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/13") + 5569 (check-next-stream-line-equal _test-output-stream " e9/jump a:loop/disp32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/14") + 5570 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15") + 5571 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16") + 5572 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/17") + 5573 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18") + 5574 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19") + 5575 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20") + 5576 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21") + 5577 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22") + 5578 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/23") + 5579 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24") + 5580 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25") + 5581 # . epilogue + 5582 89/<- %esp 5/r32/ebp + 5583 5d/pop-to-ebp + 5584 c3/return + 5585 + 5586 test-convert-function-with-local-array-var-in-mem: + 5587 # . prologue + 5588 55/push-ebp + 5589 89/<- %ebp 4/r32/esp + 5590 # setup + 5591 (clear-stream _test-input-stream) + 5592 (clear-stream $_test-input-buffered-file->buffer) + 5593 (clear-stream _test-output-stream) + 5594 (clear-stream $_test-output-buffered-file->buffer) + 5595 # + 5596 (write _test-input-stream "fn foo {\n") + 5597 (write _test-input-stream " var x: (array int 3)\n") + 5598 (write _test-input-stream "}\n") + 5599 # convert + 5600 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5601 (flush _test-output-buffered-file) + 5602 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5608 # check output + 5609 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0") + 5610 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1") + 5611 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2") + 5612 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3") + 5613 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4") + 5614 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5") + 5615 # define x + 5616 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7") + 5617 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8") + 5618 # reclaim x + 5619 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-function-with-local-array-var-in-mem/9") + 5620 # + 5621 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10") + 5622 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11") + 5623 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12") + 5624 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13") + 5625 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14") + 5626 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15") + 5627 # . epilogue + 5628 89/<- %esp 5/r32/ebp + 5629 5d/pop-to-ebp + 5630 c3/return + 5631 + 5632 test-array-size-in-hex: + 5633 # . prologue + 5634 55/push-ebp + 5635 89/<- %ebp 4/r32/esp + 5636 # setup + 5637 (clear-stream _test-input-stream) + 5638 (clear-stream $_test-input-buffered-file->buffer) + 5639 (clear-stream _test-output-stream) + 5640 (clear-stream $_test-output-buffered-file->buffer) + 5641 (clear-stream _test-error-stream) + 5642 (clear-stream $_test-error-buffered-file->buffer) + 5643 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5644 68/push 0/imm32 + 5645 68/push 0/imm32 + 5646 89/<- %edx 4/r32/esp + 5647 (tailor-exit-descriptor %edx 0x10) + 5648 # + 5649 (write _test-input-stream "fn foo {\n") + 5650 (write _test-input-stream " var x: (array int 10)\n") + 5651 (write _test-input-stream "}\n") + 5652 # convert + 5653 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5654 # registers except esp clobbered at this point + 5655 # restore ed + 5656 89/<- %edx 4/r32/esp + 5657 (flush _test-output-buffered-file) + 5658 (flush _test-error-buffered-file) + 5659 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5665 # check output + 5666 (check-stream-equal _test-output-stream "" "F - test-array-size-in-hex: output should be empty") + 5667 (check-next-stream-line-equal _test-error-stream "literal integers are always hex in Mu; start '10' with a '0x' to be unambiguous, converting it to hexadecimal as necessary." "F - test-array-size-in-hex: error message") + 5668 # check that stop(1) was called + 5669 (check-ints-equal *(edx+4) 2 "F - test-array-size-in-hex: exit status") + 5670 # don't restore from ebp + 5671 81 0/subop/add %esp 8/imm32 + 5672 # . epilogue + 5673 5d/pop-to-ebp + 5674 c3/return + 5675 + 5676 test-array-size-with-metadata: + 5677 # . prologue + 5678 55/push-ebp + 5679 89/<- %ebp 4/r32/esp + 5680 # setup + 5681 (clear-stream _test-input-stream) + 5682 (clear-stream $_test-input-buffered-file->buffer) + 5683 (clear-stream _test-output-stream) + 5684 (clear-stream $_test-output-buffered-file->buffer) + 5685 # + 5686 (write _test-input-stream "fn foo {\n") + 5687 (write _test-input-stream " var x: (array int 3/bar)\n") + 5688 (write _test-input-stream "}\n") + 5689 # convert + 5690 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5691 (flush _test-output-buffered-file) + 5692 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5698 # no errors + 5699 # . epilogue + 5700 89/<- %esp 5/r32/ebp + 5701 5d/pop-to-ebp + 5702 c3/return + 5703 + 5704 test-convert-function-with-populate: + 5705 # . prologue + 5706 55/push-ebp + 5707 89/<- %ebp 4/r32/esp + 5708 # setup + 5709 (clear-stream _test-input-stream) + 5710 (clear-stream $_test-input-buffered-file->buffer) + 5711 (clear-stream _test-output-stream) + 5712 (clear-stream $_test-output-buffered-file->buffer) + 5713 # + 5714 (write _test-input-stream "fn foo {\n") + 5715 (write _test-input-stream " var x/ecx: (addr handle array int) <- copy 0\n") + 5716 (write _test-input-stream " populate x, 7\n") + 5717 (write _test-input-stream "}\n") + 5718 # convert + 5719 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5720 (flush _test-output-buffered-file) + 5721 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5727 # check output + 5728 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-populate/0") + 5729 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-populate/1") + 5730 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-populate/2") + 5731 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-populate/3") + 5732 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-populate/4") + 5733 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-populate/5") + 5734 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-populate/6") + 5735 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-populate/7") + 5736 (check-next-stream-line-equal _test-output-stream " (allocate-array2 Heap 0x00000004 7 %ecx)" "F - test-convert-function-with-populate/8") # 4 = size-of(int) + 5737 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-populate/9") + 5738 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-populate/10") + 5739 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-populate/11") + 5740 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-populate/12") + 5741 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-populate/13") + 5742 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-populate/14") + 5743 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-populate/15") + 5744 # . epilogue + 5745 89/<- %esp 5/r32/ebp + 5746 5d/pop-to-ebp + 5747 c3/return + 5748 + 5749 # special-case for size(byte) when allocating array + 5750 test-convert-function-with-local-array-of-bytes-in-mem: + 5751 # . prologue + 5752 55/push-ebp + 5753 89/<- %ebp 4/r32/esp + 5754 # setup + 5755 (clear-stream _test-input-stream) + 5756 (clear-stream $_test-input-buffered-file->buffer) + 5757 (clear-stream _test-output-stream) + 5758 (clear-stream $_test-output-buffered-file->buffer) + 5759 # + 5760 (write _test-input-stream "fn foo {\n") + 5761 (write _test-input-stream " var x: (array byte 3)\n") + 5762 (write _test-input-stream "}\n") + 5763 # convert + 5764 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5765 (flush _test-output-buffered-file) + 5766 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5772 # check output + 5773 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-of-bytes-in-mem/0") + 5774 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-of-bytes-in-mem/1") + 5775 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/2") + 5776 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-of-bytes-in-mem/3") + 5777 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-of-bytes-in-mem/4") + 5778 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-of-bytes-in-mem/5") + 5779 # define x + 5780 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x00000003)" "F - test-convert-function-with-local-array-of-bytes-in-mem/7") + 5781 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/8") + 5782 # reclaim x + 5783 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000007/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/9") + 5784 # + 5785 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-of-bytes-in-mem/10") + 5786 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-of-bytes-in-mem/11") + 5787 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-of-bytes-in-mem/12") + 5788 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/13") + 5789 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/14") + 5790 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-of-bytes-in-mem/15") + 5791 # . epilogue + 5792 89/<- %esp 5/r32/ebp + 5793 5d/pop-to-ebp + 5794 c3/return + 5795 + 5796 test-convert-address: + 5797 # . prologue + 5798 55/push-ebp + 5799 89/<- %ebp 4/r32/esp + 5800 # setup + 5801 (clear-stream _test-input-stream) + 5802 (clear-stream $_test-input-buffered-file->buffer) + 5803 (clear-stream _test-output-stream) + 5804 (clear-stream $_test-output-buffered-file->buffer) + 5805 # + 5806 (write _test-input-stream "fn foo {\n") + 5807 (write _test-input-stream " var a: int\n") + 5808 (write _test-input-stream " var b/eax: (addr int) <- address a\n") + 5809 (write _test-input-stream "}\n") + 5810 # convert + 5811 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5812 (flush _test-output-buffered-file) + 5813 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5819 # check output + 5820 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0") + 5821 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1") + 5822 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2") + 5823 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3") + 5824 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4") + 5825 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5") + 5826 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6") + 5827 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7") + 5828 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8") + 5829 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9") + 5830 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10") + 5831 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11") + 5832 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12") + 5833 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13") + 5834 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14") + 5835 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15") + 5836 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16") + 5837 # . epilogue + 5838 89/<- %esp 5/r32/ebp + 5839 5d/pop-to-ebp + 5840 c3/return + 5841 + 5842 test-convert-floating-point-convert: + 5843 # . prologue + 5844 55/push-ebp + 5845 89/<- %ebp 4/r32/esp + 5846 # setup + 5847 (clear-stream _test-input-stream) + 5848 (clear-stream $_test-input-buffered-file->buffer) + 5849 (clear-stream _test-output-stream) + 5850 (clear-stream $_test-output-buffered-file->buffer) + 5851 # + 5852 (write _test-input-stream "fn foo {\n") + 5853 (write _test-input-stream " var a/eax: int <- copy 0\n") + 5854 (write _test-input-stream " var b/xmm1: float <- convert a\n") + 5855 (write _test-input-stream "}\n") + 5856 # convert + 5857 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5858 (flush _test-output-buffered-file) + 5859 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5865 # check output + 5866 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-floating-point-convert/0") + 5867 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-convert/1") + 5868 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-convert/2") + 5869 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-convert/3") + 5870 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-convert/4") + 5871 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-floating-point-convert/5") + 5872 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-convert/6") + 5873 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-convert/7") + 5874 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-convert/8") + 5875 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-convert/9") + 5876 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-floating-point-convert/10") + 5877 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-convert/11") + 5878 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-floating-point-convert/12") + 5879 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-convert/13") + 5880 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-convert/14") + 5881 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-floating-point-convert/15") + 5882 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-convert/16") + 5883 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-convert/17") + 5884 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-convert/18") + 5885 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-convert/19") + 5886 # . epilogue + 5887 89/<- %esp 5/r32/ebp + 5888 5d/pop-to-ebp + 5889 c3/return + 5890 + 5891 test-convert-floating-point-convert-2: + 5892 # . prologue + 5893 55/push-ebp + 5894 89/<- %ebp 4/r32/esp + 5895 # setup + 5896 (clear-stream _test-input-stream) + 5897 (clear-stream $_test-input-buffered-file->buffer) + 5898 (clear-stream _test-output-stream) + 5899 (clear-stream $_test-output-buffered-file->buffer) + 5900 # + 5901 (write _test-input-stream "fn foo {\n") + 5902 (write _test-input-stream " var a/eax: int <- copy 0\n") + 5903 (write _test-input-stream " var b/xmm1: float <- convert a\n") + 5904 (write _test-input-stream " a <- convert b\n") + 5905 (write _test-input-stream "}\n") + 5906 # convert + 5907 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5908 (flush _test-output-buffered-file) + 5909 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5915 # check output + 5916 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-floating-point-convert-2/0") + 5917 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-convert-2/1") + 5918 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-convert-2/2") + 5919 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-convert-2/3") + 5920 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-convert-2/4") + 5921 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-floating-point-convert-2/5") + 5922 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-convert-2/6") + 5923 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-convert-2/7") + 5924 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-convert-2/8") + 5925 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-convert-2/9") + 5926 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-floating-point-convert-2/10") + 5927 (check-next-stream-line-equal _test-output-stream " f3 0f 2d/convert-to-int %xmm1 0x00000000/r32" "F - test-convert-floating-point-convert-2/11") + 5928 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-convert-2/12") + 5929 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-floating-point-convert-2/13") + 5930 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-convert-2/14") + 5931 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-convert-2/15") + 5932 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-floating-point-convert-2/16") + 5933 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-convert-2/17") + 5934 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-convert-2/18") + 5935 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-convert-2/19") + 5936 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-convert-2/20") + 5937 # . epilogue + 5938 89/<- %esp 5/r32/ebp + 5939 5d/pop-to-ebp + 5940 c3/return + 5941 + 5942 test-convert-floating-point-operation: + 5943 # . prologue + 5944 55/push-ebp + 5945 89/<- %ebp 4/r32/esp + 5946 # setup + 5947 (clear-stream _test-input-stream) + 5948 (clear-stream $_test-input-buffered-file->buffer) + 5949 (clear-stream _test-output-stream) + 5950 (clear-stream $_test-output-buffered-file->buffer) + 5951 # + 5952 (write _test-input-stream "fn f {\n") + 5953 (write _test-input-stream " var m: float\n") + 5954 (write _test-input-stream " var x/xmm1: float <- copy m\n") + 5955 (write _test-input-stream " var y/xmm5: float <- copy m\n") + 5956 (write _test-input-stream " x <- copy y\n") + 5957 (write _test-input-stream " copy-to m, y\n") + 5958 (write _test-input-stream " x <- add y\n") + 5959 (write _test-input-stream " x <- add m\n") + 5960 (write _test-input-stream " x <- subtract y\n") + 5961 (write _test-input-stream " x <- subtract m\n") + 5962 (write _test-input-stream " x <- multiply y\n") + 5963 (write _test-input-stream " x <- multiply m\n") + 5964 (write _test-input-stream " x <- divide y\n") + 5965 (write _test-input-stream " x <- divide m\n") + 5966 (write _test-input-stream " x <- reciprocal y\n") + 5967 (write _test-input-stream " x <- reciprocal m\n") + 5968 (write _test-input-stream " x <- square-root y\n") + 5969 (write _test-input-stream " x <- square-root m\n") + 5970 (write _test-input-stream " x <- inverse-square-root y\n") + 5971 (write _test-input-stream " x <- inverse-square-root m\n") + 5972 (write _test-input-stream " x <- max y\n") + 5973 (write _test-input-stream " x <- max m\n") + 5974 (write _test-input-stream " x <- min y\n") + 5975 (write _test-input-stream " x <- min m\n") + 5976 (write _test-input-stream " compare x, y\n") + 5977 (write _test-input-stream " compare x, m\n") + 5978 (write _test-input-stream "}\n") + 5979 # convert + 5980 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5981 (flush _test-output-buffered-file) + 5982 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5988 # check output + 5989 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-floating-point-operation/0") + 5990 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-operation/1") + 5991 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-operation/2") + 5992 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-operation/3") + 5993 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-operation/4") + 5994 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-floating-point-operation/5") + 5995 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-floating-point-operation/6") + 5996 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-operation/7") + 5997 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-operation/8") + 5998 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/9") + 5999 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-operation/10") + 6000 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 5/x32" "F - test-convert-floating-point-operation/11") + 6001 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000005/x32" "F - test-convert-floating-point-operation/12") + 6002 (check-next-stream-line-equal _test-output-stream " f3 0f 11/copy %xmm1 0x00000005/x32" "F - test-convert-floating-point-operation/13") + 6003 (check-next-stream-line-equal _test-output-stream " f3 0f 11/copy *(ebp+0xfffffffc) 0x00000005/x32" "F - test-convert-floating-point-operation/14") + 6004 (check-next-stream-line-equal _test-output-stream " f3 0f 58/add %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/15") + 6005 (check-next-stream-line-equal _test-output-stream " f3 0f 58/add *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/16") + 6006 (check-next-stream-line-equal _test-output-stream " f3 0f 5c/subtract %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/17") + 6007 (check-next-stream-line-equal _test-output-stream " f3 0f 5c/subtract *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/18") + 6008 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/19") + 6009 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/20") + 6010 (check-next-stream-line-equal _test-output-stream " f3 0f 5e/divide %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/21") + 6011 (check-next-stream-line-equal _test-output-stream " f3 0f 5e/divide *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/22") + 6012 (check-next-stream-line-equal _test-output-stream " f3 0f 53/reciprocal %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/23") + 6013 (check-next-stream-line-equal _test-output-stream " f3 0f 53/reciprocal *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/24") + 6014 (check-next-stream-line-equal _test-output-stream " f3 0f 51/square-root %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/25") + 6015 (check-next-stream-line-equal _test-output-stream " f3 0f 51/square-root *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/26") + 6016 (check-next-stream-line-equal _test-output-stream " f3 0f 52/inverse-square-root %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/27") + 6017 (check-next-stream-line-equal _test-output-stream " f3 0f 52/inverse-square-root *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/28") + 6018 (check-next-stream-line-equal _test-output-stream " f3 0f 5f/max %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/29") + 6019 (check-next-stream-line-equal _test-output-stream " f3 0f 5f/max *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/30") + 6020 (check-next-stream-line-equal _test-output-stream " f3 0f 5d/min %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/31") + 6021 (check-next-stream-line-equal _test-output-stream " f3 0f 5d/min *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/32") + 6022 (check-next-stream-line-equal _test-output-stream " 0f 2f/compare %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/33") + 6023 (check-next-stream-line-equal _test-output-stream " 0f 2f/compare *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/34") + 6024 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 5/x32" "F - test-convert-floating-point-operation/35") + 6025 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-operation/36") + 6026 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-operation/37") + 6027 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-operation/38") + 6028 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-floating-point-operation/39") + 6029 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-operation/40") + 6030 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-floating-point-operation/41") + 6031 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-operation/42") + 6032 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-operation/43") + 6033 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-operation/44") + 6034 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-operation/45") + 6035 # . epilogue + 6036 89/<- %esp 5/r32/ebp + 6037 5d/pop-to-ebp + 6038 c3/return + 6039 + 6040 test-convert-floating-point-dereferenced: + 6041 # . prologue + 6042 55/push-ebp + 6043 89/<- %ebp 4/r32/esp + 6044 # setup + 6045 (clear-stream _test-input-stream) + 6046 (clear-stream $_test-input-buffered-file->buffer) + 6047 (clear-stream _test-output-stream) + 6048 (clear-stream $_test-output-buffered-file->buffer) + 6049 # + 6050 (write _test-input-stream "fn f {\n") + 6051 (write _test-input-stream " var m: float\n") + 6052 (write _test-input-stream " var x/xmm1: float <- copy m\n") + 6053 (write _test-input-stream " var y/eax: (addr float) <- copy 0\n") + 6054 (write _test-input-stream " x <- multiply *y\n") + 6055 (write _test-input-stream "}\n") + 6056 # convert + 6057 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6058 (flush _test-output-buffered-file) + 6059 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6065 # check output + 6066 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-floating-point-dereferenced/0") + 6067 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-dereferenced/1") + 6068 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-dereferenced/2") + 6069 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-dereferenced/3") + 6070 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-dereferenced/4") + 6071 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-floating-point-dereferenced/5") + 6072 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-floating-point-dereferenced/6") + 6073 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-dereferenced/7") + 6074 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-dereferenced/8") + 6075 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-dereferenced/9") + 6076 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-dereferenced/10") + 6077 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-dereferenced/11") + 6078 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply *eax 0x00000001/x32" "F - test-convert-floating-point-dereferenced/12") + 6079 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-dereferenced/13") + 6080 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-dereferenced/14") + 6081 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/15") + 6082 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-floating-point-dereferenced/16") + 6083 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-dereferenced/17") + 6084 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-floating-point-dereferenced/18") + 6085 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-dereferenced/19") + 6086 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-dereferenced/20") + 6087 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-dereferenced/21") + 6088 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-dereferenced/22") + 6089 # . epilogue + 6090 89/<- %esp 5/r32/ebp + 6091 5d/pop-to-ebp + 6092 c3/return + 6093 + 6094 test-convert-length-of-array: + 6095 # . prologue + 6096 55/push-ebp + 6097 89/<- %ebp 4/r32/esp + 6098 # setup + 6099 (clear-stream _test-input-stream) + 6100 (clear-stream $_test-input-buffered-file->buffer) + 6101 (clear-stream _test-output-stream) + 6102 (clear-stream $_test-output-buffered-file->buffer) + 6103 # + 6104 (write _test-input-stream "fn foo a: (addr array int) {\n") + 6105 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n") + 6106 (write _test-input-stream " var c/eax: int <- length b\n") + 6107 (write _test-input-stream "}\n") + 6108 # convert + 6109 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6110 (flush _test-output-buffered-file) + 6111 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6117 # check output + 6118 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0") + 6119 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1") + 6120 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2") + 6121 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3") + 6122 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4") + 6123 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") + 6124 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") + 6125 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") + 6126 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") + 6127 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9") + 6128 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") + 6129 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") + 6130 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") + 6131 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") + 6132 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") + 6133 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") + 6134 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") + 6135 # . epilogue + 6136 89/<- %esp 5/r32/ebp + 6137 5d/pop-to-ebp + 6138 c3/return + 6139 + 6140 # special-case for size(byte) when computing array length + 6141 test-convert-length-of-array-of-bytes: + 6142 # . prologue + 6143 55/push-ebp + 6144 89/<- %ebp 4/r32/esp + 6145 # setup + 6146 (clear-stream _test-input-stream) + 6147 (clear-stream $_test-input-buffered-file->buffer) + 6148 (clear-stream _test-output-stream) + 6149 (clear-stream $_test-output-buffered-file->buffer) + 6150 # + 6151 (write _test-input-stream "fn foo a: (addr array byte) {\n") + 6152 (write _test-input-stream " var b/eax: (addr array byte) <- copy a\n") + 6153 (write _test-input-stream " var c/eax: int <- length b\n") + 6154 (write _test-input-stream "}\n") + 6155 # convert + 6156 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6157 (flush _test-output-buffered-file) + 6158 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6164 # check output + 6165 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-bytes/0") + 6166 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-bytes/1") + 6167 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-bytes/2") + 6168 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-bytes/3") + 6169 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-bytes/4") + 6170 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-bytes/5") + 6171 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-bytes/6") + 6172 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/7") + 6173 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/8") + 6174 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-bytes/9") + 6175 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-bytes/10") + 6176 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-bytes/11") + 6177 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-bytes/12") + 6178 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-bytes/13") + 6179 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-bytes/14") + 6180 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-bytes/15") + 6181 # . epilogue + 6182 89/<- %esp 5/r32/ebp + 6183 5d/pop-to-ebp + 6184 c3/return + 6185 + 6186 test-convert-length-of-array-on-stack: + 6187 # . prologue + 6188 55/push-ebp + 6189 89/<- %ebp 4/r32/esp + 6190 # setup + 6191 (clear-stream _test-input-stream) + 6192 (clear-stream $_test-input-buffered-file->buffer) + 6193 (clear-stream _test-output-stream) + 6194 (clear-stream $_test-output-buffered-file->buffer) + 6195 # + 6196 (write _test-input-stream "fn foo {\n") + 6197 (write _test-input-stream " var a: (array int 3)\n") + 6198 (write _test-input-stream " var b/eax: int <- length a\n") + 6199 (write _test-input-stream "}\n") + 6200 # convert + 6201 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6202 (flush _test-output-buffered-file) + 6203 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6209 # check output + 6210 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0") + 6211 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1") + 6212 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2") + 6213 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3") + 6214 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4") + 6215 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5") + 6216 # define x + 6217 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6") + 6218 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") + 6219 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") + 6220 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") + 6221 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10") + 6222 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") + 6223 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") + 6224 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") + 6225 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") + 6226 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") + 6227 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") + 6228 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") + 6229 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") + 6230 # . epilogue + 6231 89/<- %esp 5/r32/ebp + 6232 5d/pop-to-ebp + 6233 c3/return + 6234 + 6235 test-reg-var-def-with-read-of-same-register: + 6236 # . prologue + 6237 55/push-ebp + 6238 89/<- %ebp 4/r32/esp + 6239 # setup + 6240 (clear-stream _test-input-stream) + 6241 (clear-stream $_test-input-buffered-file->buffer) + 6242 (clear-stream _test-output-stream) + 6243 (clear-stream $_test-output-buffered-file->buffer) + 6244 (clear-stream _test-error-stream) + 6245 (clear-stream $_test-error-buffered-file->buffer) + 6246 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu + 6247 68/push 0/imm32 + 6248 68/push 0/imm32 + 6249 89/<- %edx 4/r32/esp + 6250 (tailor-exit-descriptor %edx 0x10) + 6251 # + 6252 (write _test-input-stream "fn foo {\n") + 6253 (write _test-input-stream " var x/eax: int <- copy 3\n") + 6254 (write _test-input-stream " var y/eax: int <- add x\n") + 6255 (write _test-input-stream "}\n") + 6256 # convert + 6257 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6258 # registers except esp could be clobbered at this point (though they shouldn't be) + 6259 # restore ed + 6260 89/<- %edx 4/r32/esp + 6261 (flush _test-output-buffered-file) + 6262 (flush _test-error-buffered-file) + 6263 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6269 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6275 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty") + 6276 # check output + 6277 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0") + 6278 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1") + 6279 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2") + 6280 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3") + 6281 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4") + 6282 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5") + 6283 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6") + 6284 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-reg-var-def-with-read-of-same-register/7") + 6285 (check-next-stream-line-equal _test-output-stream " 01/add-to %eax 0x00000000/r32" "F - test-reg-var-def-with-read-of-same-register/8") + 6286 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/9") + 6287 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/10") + 6288 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/11") + 6289 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/12") + 6290 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/13") + 6291 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/14") + 6292 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/15") + 6293 # don't restore from ebp + 6294 81 0/subop/add %esp 8/imm32 + 6295 # . epilogue + 6296 5d/pop-to-ebp + 6297 c3/return + 6298 + 6299 test-convert-index-into-array: + 6300 # . prologue + 6301 55/push-ebp + 6302 89/<- %ebp 4/r32/esp + 6303 # setup + 6304 (clear-stream _test-input-stream) + 6305 (clear-stream $_test-input-buffered-file->buffer) + 6306 (clear-stream _test-output-stream) + 6307 (clear-stream $_test-output-buffered-file->buffer) + 6308 # + 6309 (write _test-input-stream "fn foo {\n") + 6310 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 6311 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 6312 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 6313 (write _test-input-stream "}\n") + 6314 # convert + 6315 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6316 (flush _test-output-buffered-file) + 6317 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6323 # check output + 6324 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") + 6325 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") + 6326 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") + 6327 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") + 6328 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") + 6329 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") + 6330 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") + 6331 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") + 6332 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") + 6333 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") + 6334 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000004 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array/10") + 6335 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array/11") + 6336 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array/12") + 6337 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/13") + 6338 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/14") + 6339 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/15") + 6340 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/16") + 6341 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/17") + 6342 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/18") + 6343 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/19") + 6344 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/20") + 6345 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/21") + 6346 # . epilogue + 6347 89/<- %esp 5/r32/ebp + 6348 5d/pop-to-ebp + 6349 c3/return + 6350 + 6351 test-convert-index-into-array-of-bytes: + 6352 # . prologue + 6353 55/push-ebp + 6354 89/<- %ebp 4/r32/esp + 6355 # setup + 6356 (clear-stream _test-input-stream) + 6357 (clear-stream $_test-input-buffered-file->buffer) + 6358 (clear-stream _test-output-stream) + 6359 (clear-stream $_test-output-buffered-file->buffer) + 6360 # + 6361 (write _test-input-stream "fn foo {\n") + 6362 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 6363 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 6364 (write _test-input-stream " var x/eax: (addr byte) <- index arr, idx\n") + 6365 (write _test-input-stream "}\n") + 6366 # convert + 6367 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6368 (flush _test-output-buffered-file) + 6369 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6375 # check output + 6376 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes/0") + 6377 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1") + 6378 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2") + 6379 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3") + 6380 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4") + 6381 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5") + 6382 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6") + 6383 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7") + 6384 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8") + 6385 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9") + 6386 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000001 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes/10") + 6387 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes/11") + 6388 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes/12") + 6389 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000000 + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes/13") + 6390 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/14") + 6391 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/15") + 6392 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/16") + 6393 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/17") + 6394 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/18") + 6395 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/19") + 6396 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/20") + 6397 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/21") + 6398 # . epilogue + 6399 89/<- %esp 5/r32/ebp + 6400 5d/pop-to-ebp + 6401 c3/return + 6402 + 6403 test-convert-index-into-array-with-literal: + 6404 # . prologue + 6405 55/push-ebp + 6406 89/<- %ebp 4/r32/esp + 6407 # setup + 6408 (clear-stream _test-input-stream) + 6409 (clear-stream $_test-input-buffered-file->buffer) + 6410 (clear-stream _test-output-stream) + 6411 (clear-stream $_test-output-buffered-file->buffer) + 6412 # + 6413 (write _test-input-stream "fn foo {\n") + 6414 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 6415 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 6416 (write _test-input-stream "}\n") + 6417 # convert + 6418 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6419 (flush _test-output-buffered-file) + 6420 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6426 # check output + 6427 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") + 6428 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") + 6429 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") + 6430 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") + 6431 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") + 6432 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") + 6433 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") + 6434 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") + 6435 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000004 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-with-literal/8") + 6436 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-with-literal/9") + 6437 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-with-literal/10") + 6438 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 + 6439 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/11") + 6440 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/12") + 6441 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/13") + 6442 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/14") + 6443 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/15") + 6444 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/16") + 6445 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/17") + 6446 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/18") + 6447 # . epilogue + 6448 89/<- %esp 5/r32/ebp + 6449 5d/pop-to-ebp + 6450 c3/return + 6451 + 6452 test-convert-index-into-array-of-bytes-with-literal: + 6453 # . prologue + 6454 55/push-ebp + 6455 89/<- %ebp 4/r32/esp + 6456 # setup + 6457 (clear-stream _test-input-stream) + 6458 (clear-stream $_test-input-buffered-file->buffer) + 6459 (clear-stream _test-output-stream) + 6460 (clear-stream $_test-output-buffered-file->buffer) + 6461 # + 6462 (write _test-input-stream "fn foo {\n") + 6463 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 6464 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") + 6465 (write _test-input-stream "}\n") + 6466 # convert + 6467 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6468 (flush _test-output-buffered-file) + 6469 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6475 # check output + 6476 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0") + 6477 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1") + 6478 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2") + 6479 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3") + 6480 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4") + 6481 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5") + 6482 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6") + 6483 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-with-literal/7") + 6484 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000001 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-with-literal/8") + 6485 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-with-literal/9") + 6486 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-with-literal/10") + 6487 # 2 * 1 byte/elem + 4 bytes for size = offset 6 + 6488 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000006) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-with-literal/11") + 6489 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/12") + 6490 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/13") + 6491 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/14") + 6492 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/15") + 6493 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/16") + 6494 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/17") + 6495 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/18") + 6496 # . epilogue + 6497 89/<- %esp 5/r32/ebp + 6498 5d/pop-to-ebp + 6499 c3/return + 6500 + 6501 test-convert-index-into-array-on-stack: + 6502 # . prologue + 6503 55/push-ebp + 6504 89/<- %ebp 4/r32/esp + 6505 # setup + 6506 (clear-stream _test-input-stream) + 6507 (clear-stream $_test-input-buffered-file->buffer) + 6508 (clear-stream _test-output-stream) + 6509 (clear-stream $_test-output-buffered-file->buffer) + 6510 # + 6511 (write _test-input-stream "fn foo {\n") + 6512 (write _test-input-stream " var arr: (array int 3)\n") + 6513 (write _test-input-stream " var idx/eax: int <- copy 2\n") + 6514 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 6515 (write _test-input-stream "}\n") + 6516 # convert + 6517 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6518 (flush _test-output-buffered-file) + 6519 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6525 # check output + 6526 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") + 6527 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") + 6528 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") + 6529 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") + 6530 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") + 6531 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") + 6532 # var arr + 6533 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") + 6534 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") + 6535 # var idx + 6536 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") + 6537 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") + 6538 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %eax 0x00000004 *(ebp+0xfffffff0) \"foo\" \"arr\")" "F - test-convert-index-into-array-on-stack/10") + 6539 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc + 6540 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + eax<<0x00000002 + 0xfffffff4) 0x00000000/r32" "F - test-convert-index-into-array-on-stack/11") + 6541 # reclaim idx + 6542 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/12") + 6543 # reclaim arr + 6544 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/13") + 6545 # + 6546 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/14") + 6547 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/15") + 6548 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/16") + 6549 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/17") + 6550 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/18") + 6551 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/19") + 6552 # . epilogue + 6553 89/<- %esp 5/r32/ebp + 6554 5d/pop-to-ebp + 6555 c3/return + 6556 + 6557 test-convert-index-into-array-on-stack-with-literal: + 6558 # . prologue + 6559 55/push-ebp + 6560 89/<- %ebp 4/r32/esp + 6561 # setup + 6562 (clear-stream _test-input-stream) + 6563 (clear-stream $_test-input-buffered-file->buffer) + 6564 (clear-stream _test-output-stream) + 6565 (clear-stream $_test-output-buffered-file->buffer) + 6566 # + 6567 (write _test-input-stream "fn foo {\n") + 6568 (write _test-input-stream " var arr: (array int 3)\n") + 6569 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 6570 (write _test-input-stream "}\n") + 6571 # convert + 6572 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6573 (flush _test-output-buffered-file) + 6574 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6580 # check output + 6581 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") + 6582 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") + 6583 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") + 6584 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") + 6585 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") + 6586 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") + 6587 # var arr + 6588 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") + 6589 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") + 6590 # var x + 6591 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") + 6592 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000004 *(ebp+0xfffffff0) \"foo\" \"arr\")" "F - test-convert-index-into-array-on-stack-with-literal/9") + 6593 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 + 6594 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xfffffffc) 0x00000000/r32" "F - test-convert-index-into-array-on-stack-with-literal/10") + 6595 # reclaim x + 6596 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/11") + 6597 # reclaim arr + 6598 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack-with-literal/12") + 6599 # + 6600 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/13") + 6601 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/14") + 6602 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/15") + 6603 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") + 6604 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/17") + 6605 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/18") + 6606 # . epilogue + 6607 89/<- %esp 5/r32/ebp + 6608 5d/pop-to-ebp + 6609 c3/return + 6610 + 6611 test-convert-index-into-array-of-bytes-on-stack-with-literal: + 6612 # . prologue + 6613 55/push-ebp + 6614 89/<- %ebp 4/r32/esp + 6615 # setup + 6616 (clear-stream _test-input-stream) + 6617 (clear-stream $_test-input-buffered-file->buffer) + 6618 (clear-stream _test-output-stream) + 6619 (clear-stream $_test-output-buffered-file->buffer) + 6620 # + 6621 (write _test-input-stream "fn foo {\n") + 6622 (write _test-input-stream " var arr: (array byte 3)\n") + 6623 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") + 6624 (write _test-input-stream "}\n") + 6625 # convert + 6626 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6627 (flush _test-output-buffered-file) + 6628 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6634 # check output + 6635 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0") + 6636 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1") + 6637 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2") + 6638 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/3") + 6639 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4") + 6640 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5") + 6641 # var arr + 6642 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x00000003)" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/6") + 6643 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/7") + 6644 # var x + 6645 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/8") + 6646 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000001 *(ebp+0xfffffff9) \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/9") + 6647 # x is at (ebp-7) + 4 + 2 = ebp-1 + 6648 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xffffffff) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/10") + 6649 # reclaim x + 6650 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/11") + 6651 # reclaim arr + 6652 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000007/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12") + 6653 # + 6654 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13") + 6655 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14") + 6656 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/15") + 6657 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/16") + 6658 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17") + 6659 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/18") + 6660 # . epilogue + 6661 89/<- %esp 5/r32/ebp + 6662 5d/pop-to-ebp + 6663 c3/return + 6664 + 6665 test-convert-index-into-array-using-offset: + 6666 # . prologue + 6667 55/push-ebp + 6668 89/<- %ebp 4/r32/esp + 6669 # setup + 6670 (clear-stream _test-input-stream) + 6671 (clear-stream $_test-input-buffered-file->buffer) + 6672 (clear-stream _test-output-stream) + 6673 (clear-stream $_test-output-buffered-file->buffer) + 6674 # + 6675 (write _test-input-stream "fn foo {\n") + 6676 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 6677 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 6678 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 6679 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 6680 (write _test-input-stream "}\n") + 6681 # convert + 6682 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6683 (flush _test-output-buffered-file) + 6684 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6690 # check output + 6691 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") + 6692 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") + 6693 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") + 6694 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") + 6695 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") + 6696 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") + 6697 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") + 6698 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") + 6699 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") + 6700 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") + 6701 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") + 6702 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-using-offset/11") + 6703 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-using-offset/12") + 6704 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-using-offset/13") + 6705 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/15") + 6706 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/16") + 6707 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/17") + 6708 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/18") + 6709 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/19") + 6710 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/20") + 6711 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/21") + 6712 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/22") + 6713 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/23") + 6714 # . epilogue + 6715 89/<- %esp 5/r32/ebp + 6716 5d/pop-to-ebp + 6717 c3/return + 6718 + 6719 test-convert-index-into-array-of-bytes-using-offset: + 6720 # . prologue + 6721 55/push-ebp + 6722 89/<- %ebp 4/r32/esp + 6723 # setup + 6724 (clear-stream _test-input-stream) + 6725 (clear-stream $_test-input-buffered-file->buffer) + 6726 (clear-stream _test-output-stream) + 6727 (clear-stream $_test-output-buffered-file->buffer) + 6728 # + 6729 (write _test-input-stream "fn foo {\n") + 6730 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 6731 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 6732 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") + 6733 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") + 6734 (write _test-input-stream "}\n") + 6735 # convert + 6736 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6737 (flush _test-output-buffered-file) + 6738 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6744 # check output + 6745 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0") + 6746 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1") + 6747 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2") + 6748 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3") + 6749 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4") + 6750 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5") + 6751 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6") + 6752 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/7") + 6753 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8") + 6754 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/9") + 6755 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset/10") + 6756 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-using-offset/11") + 6757 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/12") + 6758 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-using-offset/13") + 6759 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset/14") + 6760 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/15") + 6761 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/16") + 6762 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/17") + 6763 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/18") + 6764 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/19") + 6765 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/20") + 6766 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/21") + 6767 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/22") + 6768 # . epilogue + 6769 89/<- %esp 5/r32/ebp + 6770 5d/pop-to-ebp + 6771 c3/return + 6772 + 6773 test-convert-index-into-array-using-offset-on-stack: + 6774 # . prologue + 6775 55/push-ebp + 6776 89/<- %ebp 4/r32/esp + 6777 # setup + 6778 (clear-stream _test-input-stream) + 6779 (clear-stream $_test-input-buffered-file->buffer) + 6780 (clear-stream _test-output-stream) + 6781 (clear-stream $_test-output-buffered-file->buffer) + 6782 # + 6783 (write _test-input-stream "fn foo {\n") + 6784 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 6785 (write _test-input-stream " var idx: int\n") + 6786 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 6787 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 6788 (write _test-input-stream "}\n") + 6789 # convert + 6790 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6791 (flush _test-output-buffered-file) + 6792 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6798 # check output + 6799 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") + 6800 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") + 6801 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") + 6802 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") + 6803 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") + 6804 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") + 6805 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") + 6806 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/7") + 6807 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") + 6808 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") + 6809 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10") + 6810 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-using-offset-on-stack/11") + 6811 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/12") + 6812 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-using-offset-on-stack/13") + 6813 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset-on-stack/14") + 6814 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/15") + 6815 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-using-offset-on-stack/16") + 6816 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/17") + 6817 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/18") + 6818 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/19") + 6819 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/20") + 6820 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/21") + 6821 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/22") + 6822 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/23") + 6823 # . epilogue + 6824 89/<- %esp 5/r32/ebp + 6825 5d/pop-to-ebp + 6826 c3/return + 6827 + 6828 test-convert-index-into-array-of-bytes-using-offset-on-stack: + 6829 # . prologue + 6830 55/push-ebp + 6831 89/<- %ebp 4/r32/esp + 6832 # setup + 6833 (clear-stream _test-input-stream) + 6834 (clear-stream $_test-input-buffered-file->buffer) + 6835 (clear-stream _test-output-stream) + 6836 (clear-stream $_test-output-buffered-file->buffer) + 6837 # + 6838 (write _test-input-stream "fn foo {\n") + 6839 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 6840 (write _test-input-stream " var idx: int\n") + 6841 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") + 6842 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") + 6843 (write _test-input-stream "}\n") + 6844 # convert + 6845 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6846 (flush _test-output-buffered-file) + 6847 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6853 # check output + 6854 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0") + 6855 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1") + 6856 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2") + 6857 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/3") + 6858 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4") + 6859 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5") + 6860 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/6") + 6861 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/7") + 6862 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/8") + 6863 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/9") + 6864 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/10") + 6865 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/11") + 6866 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/12") + 6867 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/13") + 6868 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/14") + 6869 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15") + 6870 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16") + 6871 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17") + 6872 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/18") + 6873 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/19") + 6874 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20") + 6875 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/21") + 6876 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/22") + 6877 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/23") + 6878 # . epilogue + 6879 89/<- %esp 5/r32/ebp + 6880 5d/pop-to-ebp + 6881 c3/return + 6882 + 6883 test-convert-function-and-type-definition: + 6884 # . prologue + 6885 55/push-ebp + 6886 89/<- %ebp 4/r32/esp + 6887 # setup + 6888 (clear-stream _test-input-stream) + 6889 (clear-stream $_test-input-buffered-file->buffer) + 6890 (clear-stream _test-output-stream) + 6891 (clear-stream $_test-output-buffered-file->buffer) + 6892 # + 6893 (write _test-input-stream "fn foo a: (addr t) {\n") + 6894 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") + 6895 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") + 6896 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") + 6897 (write _test-input-stream "}\n") + 6898 (write _test-input-stream "type t {\n") + 6899 (write _test-input-stream " x: int\n") + 6900 (write _test-input-stream " y: int\n") + 6901 (write _test-input-stream "}\n") + 6902 # convert + 6903 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6904 (flush _test-output-buffered-file) + 6905 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6911 # check output + 6912 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") + 6913 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") + 6914 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") + 6915 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") + 6916 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") + 6917 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") + 6918 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") + 6919 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") + 6920 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") + 6921 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-function-and-type-definition/9") + 6922 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-get-base-address/disp32" "F - test-convert-function-and-type-definition/10") + 6923 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") + 6924 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-function-and-type-definition/12") + 6925 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-get-base-address/disp32" "F - test-convert-function-and-type-definition/13") + 6926 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/14") + 6927 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/15") + 6928 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/16") + 6929 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/17") + 6930 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/18") + 6931 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/19") + 6932 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/20") + 6933 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/21") + 6934 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/22") + 6935 # . epilogue + 6936 89/<- %esp 5/r32/ebp + 6937 5d/pop-to-ebp + 6938 c3/return + 6939 + 6940 test-type-definition-with-array: + 6941 # . prologue + 6942 55/push-ebp + 6943 89/<- %ebp 4/r32/esp + 6944 # setup + 6945 (clear-stream _test-input-stream) + 6946 (clear-stream $_test-input-buffered-file->buffer) + 6947 (clear-stream _test-output-stream) + 6948 (clear-stream $_test-output-buffered-file->buffer) + 6949 (clear-stream _test-error-stream) + 6950 (clear-stream $_test-error-buffered-file->buffer) + 6951 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6952 68/push 0/imm32 + 6953 68/push 0/imm32 + 6954 89/<- %edx 4/r32/esp + 6955 (tailor-exit-descriptor %edx 0x10) + 6956 # + 6957 (write _test-input-stream "type t {\n") + 6958 (write _test-input-stream " a: (array int 3)\n") + 6959 (write _test-input-stream "}\n") + 6960 # convert + 6961 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6962 # registers except esp clobbered at this point + 6963 # restore ed + 6964 89/<- %edx 4/r32/esp + 6965 (flush _test-output-buffered-file) + 6966 (flush _test-error-buffered-file) + 6967 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6973 # check output + 6974 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-array: output should be empty") + 6975 (check-next-stream-line-equal _test-error-stream "type t: 'array' elements not allowed for now" "F - test-type-definition-with-array: error message") + 6976 # check that stop(1) was called + 6977 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-array: exit status") + 6978 # don't restore from ebp + 6979 81 0/subop/add %esp 8/imm32 + 6980 # . epilogue + 6981 5d/pop-to-ebp + 6982 c3/return + 6983 + 6984 test-type-definition-with-addr: + 6985 # . prologue + 6986 55/push-ebp + 6987 89/<- %ebp 4/r32/esp + 6988 # setup + 6989 (clear-stream _test-input-stream) + 6990 (clear-stream $_test-input-buffered-file->buffer) + 6991 (clear-stream _test-output-stream) + 6992 (clear-stream $_test-output-buffered-file->buffer) + 6993 (clear-stream _test-error-stream) + 6994 (clear-stream $_test-error-buffered-file->buffer) + 6995 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6996 68/push 0/imm32 + 6997 68/push 0/imm32 + 6998 89/<- %edx 4/r32/esp + 6999 (tailor-exit-descriptor %edx 0x10) + 7000 # + 7001 (write _test-input-stream "type t {\n") + 7002 (write _test-input-stream " a: (addr int)\n") + 7003 (write _test-input-stream "}\n") + 7004 # convert + 7005 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7006 # registers except esp clobbered at this point + 7007 # restore ed + 7008 89/<- %edx 4/r32/esp + 7009 (flush _test-output-buffered-file) + 7010 (flush _test-error-buffered-file) + 7011 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7017 # check output + 7018 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-addr: output should be empty") + 7019 (check-next-stream-line-equal _test-error-stream "type t: 'addr' elements not allowed" "F - test-type-definition-with-addr: error message") + 7020 # check that stop(1) was called + 7021 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-addr: exit status") + 7022 # don't restore from ebp + 7023 81 0/subop/add %esp 8/imm32 + 7024 # . epilogue + 7025 5d/pop-to-ebp + 7026 c3/return + 7027 + 7028 test-convert-function-with-local-var-with-user-defined-type: + 7029 # . prologue + 7030 55/push-ebp + 7031 89/<- %ebp 4/r32/esp + 7032 # setup + 7033 (clear-stream _test-input-stream) + 7034 (clear-stream $_test-input-buffered-file->buffer) + 7035 (clear-stream _test-output-stream) + 7036 (clear-stream $_test-output-buffered-file->buffer) + 7037 # + 7038 (write _test-input-stream "fn foo {\n") + 7039 (write _test-input-stream " var a: t\n") + 7040 (write _test-input-stream "}\n") + 7041 (write _test-input-stream "type t {\n") + 7042 (write _test-input-stream " x: int\n") + 7043 (write _test-input-stream " y: int\n") + 7044 (write _test-input-stream "}\n") + 7045 # convert + 7046 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7047 (flush _test-output-buffered-file) + 7048 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 7054 # check output + 7055 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") + 7056 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") + 7057 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") + 7058 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type/3") + 7059 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") + 7060 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") + 7061 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") + 7062 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") + 7063 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/8") + 7064 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") + 7065 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") + 7066 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") + 7067 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type/12") + 7068 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") + 7069 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") + 7070 # . epilogue + 7071 89/<- %esp 5/r32/ebp + 7072 5d/pop-to-ebp + 7073 c3/return + 7074 + 7075 test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type: + 7076 # . prologue + 7077 55/push-ebp + 7078 89/<- %ebp 4/r32/esp + 7079 # setup + 7080 (clear-stream _test-input-stream) + 7081 (clear-stream $_test-input-buffered-file->buffer) + 7082 (clear-stream _test-output-stream) + 7083 (clear-stream $_test-output-buffered-file->buffer) + 7084 # + 7085 (write _test-input-stream "fn foo {\n") + 7086 (write _test-input-stream " var a: t\n") + 7087 (write _test-input-stream "}\n") + 7088 (write _test-input-stream "type t {\n") + 7089 (write _test-input-stream " x: s\n") + 7090 (write _test-input-stream "}\n") + 7091 (write _test-input-stream "type s {\n") + 7092 (write _test-input-stream " z: int\n") + 7093 (write _test-input-stream "}\n") + 7094 # convert + 7095 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7096 (flush _test-output-buffered-file) + 7097 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 7103 # check output + 7104 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/0") + 7105 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/1") + 7106 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/2") + 7107 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/3") + 7108 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/4") + 7109 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/5") + 7110 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/7") + 7111 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/8") + 7112 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/9") + 7113 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/10") + 7114 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/11") + 7115 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/12") + 7116 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/13") + 7117 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/14") + 7118 # . epilogue + 7119 89/<- %esp 5/r32/ebp + 7120 5d/pop-to-ebp + 7121 c3/return + 7122 + 7123 test-convert-function-call-with-arg-of-user-defined-type: + 7124 # . prologue + 7125 55/push-ebp + 7126 89/<- %ebp 4/r32/esp + 7127 # setup + 7128 (clear-stream _test-input-stream) + 7129 (clear-stream $_test-input-buffered-file->buffer) + 7130 (clear-stream _test-output-stream) + 7131 (clear-stream $_test-output-buffered-file->buffer) + 7132 # + 7133 (write _test-input-stream "fn f {\n") + 7134 (write _test-input-stream " var a: t\n") + 7135 (write _test-input-stream " foo a\n") + 7136 (write _test-input-stream "}\n") + 7137 (write _test-input-stream "fn foo x: t {\n") + 7138 (write _test-input-stream "}\n") + 7139 (write _test-input-stream "type t {\n") + 7140 (write _test-input-stream " x: int\n") + 7141 (write _test-input-stream " y: int\n") + 7142 (write _test-input-stream "}\n") + 7143 # convert + 7144 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7145 (flush _test-output-buffered-file) + 7146 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 7152 # check output + 7153 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 7154 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 7155 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 7156 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") + 7157 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 7158 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 7159 # var a: t + 7160 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + 7161 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + 7162 # foo a + 7163 (check-next-stream-line-equal _test-output-stream " (foo *(ebp+0xfffffff8) *(ebp+0xfffffffc))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") + 7164 # + 7165 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/9") + 7166 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 7167 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 7168 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 7169 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") + 7170 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 7171 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 7172 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 7173 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 7174 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 7175 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") + 7176 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 7177 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") + 7178 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 7179 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 7180 # . epilogue + 7181 89/<- %esp 5/r32/ebp + 7182 5d/pop-to-ebp + 7183 c3/return + 7184 + 7185 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: + 7186 # . prologue + 7187 55/push-ebp + 7188 89/<- %ebp 4/r32/esp + 7189 # setup + 7190 (clear-stream _test-input-stream) + 7191 (clear-stream $_test-input-buffered-file->buffer) + 7192 (clear-stream _test-output-stream) + 7193 (clear-stream $_test-output-buffered-file->buffer) + 7194 # + 7195 (write _test-input-stream "fn f {\n") + 7196 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") + 7197 (write _test-input-stream " foo *a\n") + 7198 (write _test-input-stream "}\n") + 7199 (write _test-input-stream "fn foo x: t {\n") + 7200 (write _test-input-stream "}\n") + 7201 (write _test-input-stream "type t {\n") + 7202 (write _test-input-stream " x: int\n") + 7203 (write _test-input-stream " y: int\n") + 7204 (write _test-input-stream "}\n") + 7205 # convert + 7206 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7207 (flush _test-output-buffered-file) + 7208 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 7214 # check output + 7215 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 7216 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 7217 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 7218 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") + 7219 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 7220 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 7221 # var a + 7222 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + 7223 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + 7224 # foo a + 7225 (check-next-stream-line-equal _test-output-stream " (foo *(eax+0x00000000) *(eax+0x00000004))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") + 7226 # + 7227 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9") + 7228 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 7229 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 7230 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 7231 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") + 7232 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 7233 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 7234 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 7235 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 7236 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 7237 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") + 7238 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 7239 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") + 7240 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 7241 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 7242 # . epilogue + 7243 89/<- %esp 5/r32/ebp + 7244 5d/pop-to-ebp + 7245 c3/return + 7246 + 7247 # we don't have special support for call-by-reference; just explicitly create + 7248 # a new variable with the address of the arg + 7249 test-convert-function-call-with-arg-of-user-defined-type-by-reference: + 7250 # . prologue + 7251 55/push-ebp + 7252 89/<- %ebp 4/r32/esp + 7253 # setup + 7254 (clear-stream _test-input-stream) + 7255 (clear-stream $_test-input-buffered-file->buffer) + 7256 (clear-stream _test-output-stream) + 7257 (clear-stream $_test-output-buffered-file->buffer) + 7258 # + 7259 (write _test-input-stream "fn f {\n") + 7260 (write _test-input-stream " var a: t\n") + 7261 (write _test-input-stream " var b/eax: (addr t) <- address a\n") + 7262 (write _test-input-stream " foo b\n") + 7263 (write _test-input-stream "}\n") + 7264 (write _test-input-stream "fn foo x: (addr t) {\n") + 7265 (write _test-input-stream " var x/ecx: (addr t) <- copy x\n") + 7266 (write _test-input-stream "}\n") + 7267 (write _test-input-stream "type t {\n") + 7268 (write _test-input-stream " x: int\n") + 7269 (write _test-input-stream " y: int\n") + 7270 (write _test-input-stream "}\n") + 7271 # convert + 7272 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7273 (flush _test-output-buffered-file) + 7274 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 7280 # check output + 7281 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") + 7282 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") + 7283 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/2") + 7284 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/3") + 7285 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") + 7286 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/5") + 7287 # var a: t + 7288 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/6") + 7289 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/7") + 7290 # var b/eax: (addr t) + 7291 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/8") + 7292 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/9") + 7293 # foo a + 7294 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") + 7295 # + 7296 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/11") + 7297 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/12") + 7298 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") + 7299 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/14") + 7300 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") + 7301 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/16") + 7302 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/17") + 7303 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") + 7304 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") + 7305 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") + 7306 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/21") + 7307 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/22") + 7308 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") + 7309 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24") + 7310 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25") + 7311 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26") + 7312 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27") + 7313 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28") + 7314 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") + 7315 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30") + 7316 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") + 7317 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/32") + 7318 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/33") + 7319 # . epilogue + 7320 89/<- %esp 5/r32/ebp + 7321 5d/pop-to-ebp + 7322 c3/return + 7323 + 7324 test-convert-get-on-local-variable: + 7325 # . prologue + 7326 55/push-ebp + 7327 89/<- %ebp 4/r32/esp + 7328 # setup + 7329 (clear-stream _test-input-stream) + 7330 (clear-stream $_test-input-buffered-file->buffer) + 7331 (clear-stream _test-output-stream) + 7332 (clear-stream $_test-output-buffered-file->buffer) + 7333 # + 7334 (write _test-input-stream "fn foo {\n") + 7335 (write _test-input-stream " var a: t\n") + 7336 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 7337 (write _test-input-stream "}\n") + 7338 (write _test-input-stream "type t {\n") + 7339 (write _test-input-stream " x: int\n") + 7340 (write _test-input-stream " y: int\n") + 7341 (write _test-input-stream "}\n") + 7342 # convert + 7343 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7344 (flush _test-output-buffered-file) + 7345 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 7351 # check output + 7352 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") + 7353 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") + 7354 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") + 7355 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") + 7356 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") + 7357 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") + 7358 # var a + 7359 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") + 7360 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") + 7361 # var c + 7362 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") + 7363 # get + 7364 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") + 7365 # reclaim c + 7366 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") + 7367 # reclaim a + 7368 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") + 7369 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") + 7370 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") + 7371 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") + 7372 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") + 7373 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") + 7374 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") + 7375 # . epilogue + 7376 89/<- %esp 5/r32/ebp + 7377 5d/pop-to-ebp + 7378 c3/return + 7379 + 7380 test-convert-get-on-function-argument: + 7381 # . prologue + 7382 55/push-ebp + 7383 89/<- %ebp 4/r32/esp + 7384 # setup + 7385 (clear-stream _test-input-stream) + 7386 (clear-stream $_test-input-buffered-file->buffer) + 7387 (clear-stream _test-output-stream) + 7388 (clear-stream $_test-output-buffered-file->buffer) + 7389 # + 7390 (write _test-input-stream "fn foo a: t {\n") + 7391 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 7392 (write _test-input-stream "}\n") + 7393 (write _test-input-stream "type t {\n") + 7394 (write _test-input-stream " x: int\n") + 7395 (write _test-input-stream " y: int\n") + 7396 (write _test-input-stream "}\n") + 7397 # convert + 7398 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7399 (flush _test-output-buffered-file) + 7400 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 7406 # check output + 7407 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") + 7408 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") + 7409 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") + 7410 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") + 7411 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") + 7412 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") + 7413 # var c + 7414 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") + 7415 # get + 7416 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") + 7417 # reclaim c + 7418 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") + 7419 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") + 7420 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") + 7421 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") + 7422 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") + 7423 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") + 7424 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") + 7425 # . epilogue + 7426 89/<- %esp 5/r32/ebp + 7427 5d/pop-to-ebp + 7428 c3/return + 7429 + 7430 test-convert-get-on-function-argument-with-known-type: + 7431 # . prologue + 7432 55/push-ebp + 7433 89/<- %ebp 4/r32/esp + 7434 # setup + 7435 (clear-stream _test-input-stream) + 7436 (clear-stream $_test-input-buffered-file->buffer) + 7437 (clear-stream _test-output-stream) + 7438 (clear-stream $_test-output-buffered-file->buffer) + 7439 # + 7440 (write _test-input-stream "type t {\n") + 7441 (write _test-input-stream " x: int\n") + 7442 (write _test-input-stream " y: int\n") + 7443 (write _test-input-stream "}\n") + 7444 (write _test-input-stream "fn foo a: t {\n") + 7445 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 7446 (write _test-input-stream "}\n") + 7447 # convert + 7448 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7449 (flush _test-output-buffered-file) + 7450 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 7456 # check output + 7457 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") + 7458 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") + 7459 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") + 7460 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") + 7461 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") + 7462 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") + 7463 # var c + 7464 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") + 7465 # get + 7466 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument-with-known-type/7") + 7467 # reclaim c + 7468 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") + 7469 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") + 7470 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") + 7471 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") + 7472 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") + 7473 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") + 7474 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") + 7475 # . epilogue + 7476 89/<- %esp 5/r32/ebp + 7477 5d/pop-to-ebp + 7478 c3/return + 7479 + 7480 test-add-with-too-many-inouts: + 7481 # . prologue + 7482 55/push-ebp + 7483 89/<- %ebp 4/r32/esp + 7484 # setup + 7485 (clear-stream _test-input-stream) + 7486 (clear-stream $_test-input-buffered-file->buffer) + 7487 (clear-stream _test-output-stream) + 7488 (clear-stream $_test-output-buffered-file->buffer) + 7489 (clear-stream _test-error-stream) + 7490 (clear-stream $_test-error-buffered-file->buffer) + 7491 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7492 68/push 0/imm32 + 7493 68/push 0/imm32 + 7494 89/<- %edx 4/r32/esp + 7495 (tailor-exit-descriptor %edx 0x10) + 7496 # + 7497 (write _test-input-stream "fn foo {\n") + 7498 (write _test-input-stream " var a: int\n") + 7499 (write _test-input-stream " var b/ecx: int <- add a, 0\n") + 7500 (write _test-input-stream "}\n") + 7501 # convert + 7502 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7503 # registers except esp clobbered at this point + 7504 # restore ed + 7505 89/<- %edx 4/r32/esp + 7506 (flush _test-output-buffered-file) + 7507 (flush _test-error-buffered-file) + 7508 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7514 # check output + 7515 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts: output should be empty") + 7516 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts: error message") + 7517 # check that stop(1) was called + 7518 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status") + 7519 # don't restore from ebp + 7520 81 0/subop/add %esp 8/imm32 + 7521 # . epilogue + 7522 5d/pop-to-ebp + 7523 c3/return + 7524 + 7525 test-add-with-too-many-inouts-2: + 7526 # . prologue + 7527 55/push-ebp + 7528 89/<- %ebp 4/r32/esp + 7529 # setup + 7530 (clear-stream _test-input-stream) + 7531 (clear-stream $_test-input-buffered-file->buffer) + 7532 (clear-stream _test-output-stream) + 7533 (clear-stream $_test-output-buffered-file->buffer) + 7534 (clear-stream _test-error-stream) + 7535 (clear-stream $_test-error-buffered-file->buffer) + 7536 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7537 68/push 0/imm32 + 7538 68/push 0/imm32 + 7539 89/<- %edx 4/r32/esp + 7540 (tailor-exit-descriptor %edx 0x10) + 7541 # + 7542 (write _test-input-stream "fn foo {\n") + 7543 (write _test-input-stream " var a: int\n") + 7544 (write _test-input-stream " add-to a, 0, 1\n") + 7545 (write _test-input-stream "}\n") + 7546 # convert + 7547 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7548 # registers except esp clobbered at this point + 7549 # restore ed + 7550 89/<- %edx 4/r32/esp + 7551 (flush _test-output-buffered-file) + 7552 (flush _test-error-buffered-file) + 7553 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7559 # check output + 7560 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts-2: output should be empty") + 7561 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add-to: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts-2: error message") + 7562 # check that stop(1) was called + 7563 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status") + 7564 # don't restore from ebp + 7565 81 0/subop/add %esp 8/imm32 + 7566 # . epilogue + 7567 5d/pop-to-ebp + 7568 c3/return + 7569 + 7570 test-add-with-too-many-outputs: + 7571 # . prologue + 7572 55/push-ebp + 7573 89/<- %ebp 4/r32/esp + 7574 # setup + 7575 (clear-stream _test-input-stream) + 7576 (clear-stream $_test-input-buffered-file->buffer) + 7577 (clear-stream _test-output-stream) + 7578 (clear-stream $_test-output-buffered-file->buffer) + 7579 (clear-stream _test-error-stream) + 7580 (clear-stream $_test-error-buffered-file->buffer) + 7581 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7582 68/push 0/imm32 + 7583 68/push 0/imm32 + 7584 89/<- %edx 4/r32/esp + 7585 (tailor-exit-descriptor %edx 0x10) + 7586 # + 7587 (write _test-input-stream "fn foo {\n") + 7588 (write _test-input-stream " var a/eax: int <- copy 0\n") + 7589 (write _test-input-stream " var b/ebx: int <- copy 0\n") + 7590 (write _test-input-stream " var c/ecx: int <- copy 0\n") + 7591 (write _test-input-stream " c, b <- add a\n") + 7592 (write _test-input-stream "}\n") + 7593 # convert + 7594 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7595 # registers except esp clobbered at this point + 7596 # restore ed + 7597 89/<- %edx 4/r32/esp + 7598 (flush _test-output-buffered-file) + 7599 (flush _test-error-buffered-file) + 7600 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7606 # check output + 7607 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-outputs: output should be empty") + 7608 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many outputs; most primitives support at most one output" "F - test-add-with-too-many-outputs: error message") + 7609 # check that stop(1) was called + 7610 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status") + 7611 # don't restore from ebp + 7612 81 0/subop/add %esp 8/imm32 + 7613 # . epilogue + 7614 5d/pop-to-ebp + 7615 c3/return + 7616 + 7617 test-add-with-non-number: + 7618 # . prologue + 7619 55/push-ebp + 7620 89/<- %ebp 4/r32/esp + 7621 # setup + 7622 (clear-stream _test-input-stream) + 7623 (clear-stream $_test-input-buffered-file->buffer) + 7624 (clear-stream _test-output-stream) + 7625 (clear-stream $_test-output-buffered-file->buffer) + 7626 (clear-stream _test-error-stream) + 7627 (clear-stream $_test-error-buffered-file->buffer) + 7628 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7629 68/push 0/imm32 + 7630 68/push 0/imm32 + 7631 89/<- %edx 4/r32/esp + 7632 (tailor-exit-descriptor %edx 0x10) + 7633 # + 7634 (write _test-input-stream "fn foo {\n") + 7635 (write _test-input-stream " var a: int\n") + 7636 (write _test-input-stream " var b/ecx: (addr int) <- add a\n") + 7637 (write _test-input-stream "}\n") + 7638 # convert + 7639 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7640 # registers except esp clobbered at this point + 7641 # restore ed + 7642 89/<- %edx 4/r32/esp + 7643 (flush _test-output-buffered-file) + 7644 (flush _test-error-buffered-file) + 7645 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7651 # check output + 7652 (check-stream-equal _test-output-stream "" "F - test-add-with-non-number: output should be empty") + 7653 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: 'b' must be a non-addr non-offset scalar" "F - test-add-with-non-number: error message") + 7654 # check that stop(1) was called + 7655 (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status") + 7656 # don't restore from ebp + 7657 81 0/subop/add %esp 8/imm32 + 7658 # . epilogue 7659 5d/pop-to-ebp 7660 c3/return 7661 - 7662 test-copy-with-no-inout: + 7662 test-add-with-addr-dereferenced: 7663 # . prologue 7664 55/push-ebp 7665 89/<- %ebp 4/r32/esp @@ -7010,687 +7010,687 @@ if ('onhashchange' in window) { 7668 (clear-stream $_test-input-buffered-file->buffer) 7669 (clear-stream _test-output-stream) 7670 (clear-stream $_test-output-buffered-file->buffer) - 7671 (clear-stream _test-error-stream) - 7672 (clear-stream $_test-error-buffered-file->buffer) - 7673 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7674 68/push 0/imm32 - 7675 68/push 0/imm32 - 7676 89/<- %edx 4/r32/esp - 7677 (tailor-exit-descriptor %edx 0x10) - 7678 # - 7679 (write _test-input-stream "fn foo {\n") - 7680 (write _test-input-stream " var x/eax: boolean <- copy\n") - 7681 (write _test-input-stream "}\n") - 7682 # convert - 7683 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7684 # registers except esp clobbered at this point - 7685 # restore ed - 7686 89/<- %edx 4/r32/esp - 7687 (flush _test-output-buffered-file) - 7688 (flush _test-error-buffered-file) - 7689 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7695 # check output - 7696 (check-stream-equal _test-output-stream "" "F - test-copy-with-no-inout: output should be empty") - 7697 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' expects an inout" "F - test-copy-with-no-inout: error message") - 7698 # check that stop(1) was called - 7699 (check-ints-equal *(edx+4) 2 "F - test-copy-with-no-inout: exit status") - 7700 # don't restore from ebp - 7701 81 0/subop/add %esp 8/imm32 - 7702 # . epilogue - 7703 5d/pop-to-ebp - 7704 c3/return - 7705 - 7706 test-copy-with-multiple-inouts: - 7707 # . prologue - 7708 55/push-ebp - 7709 89/<- %ebp 4/r32/esp - 7710 # setup - 7711 (clear-stream _test-input-stream) - 7712 (clear-stream $_test-input-buffered-file->buffer) - 7713 (clear-stream _test-output-stream) - 7714 (clear-stream $_test-output-buffered-file->buffer) - 7715 (clear-stream _test-error-stream) - 7716 (clear-stream $_test-error-buffered-file->buffer) - 7717 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7718 68/push 0/imm32 - 7719 68/push 0/imm32 - 7720 89/<- %edx 4/r32/esp - 7721 (tailor-exit-descriptor %edx 0x10) - 7722 # - 7723 (write _test-input-stream "fn foo {\n") - 7724 (write _test-input-stream " var x/eax: boolean <- copy 0, 0\n") - 7725 (write _test-input-stream "}\n") - 7726 # convert - 7727 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7728 # registers except esp clobbered at this point - 7729 # restore ed - 7730 89/<- %edx 4/r32/esp - 7731 (flush _test-output-buffered-file) - 7732 (flush _test-error-buffered-file) - 7733 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7739 # check output - 7740 (check-stream-equal _test-output-stream "" "F - test-copy-with-multiple-inouts: output should be empty") - 7741 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' must have just one inout" "F - test-copy-with-multiple-inouts: error message") - 7742 # check that stop(1) was called - 7743 (check-ints-equal *(edx+4) 2 "F - test-copy-with-multiple-inouts: exit status") - 7744 # don't restore from ebp - 7745 81 0/subop/add %esp 8/imm32 - 7746 # . epilogue - 7747 5d/pop-to-ebp - 7748 c3/return - 7749 - 7750 test-copy-with-no-output: - 7751 # . prologue - 7752 55/push-ebp - 7753 89/<- %ebp 4/r32/esp - 7754 # setup - 7755 (clear-stream _test-input-stream) - 7756 (clear-stream $_test-input-buffered-file->buffer) - 7757 (clear-stream _test-output-stream) - 7758 (clear-stream $_test-output-buffered-file->buffer) - 7759 (clear-stream _test-error-stream) - 7760 (clear-stream $_test-error-buffered-file->buffer) - 7761 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7762 68/push 0/imm32 - 7763 68/push 0/imm32 - 7764 89/<- %edx 4/r32/esp - 7765 (tailor-exit-descriptor %edx 0x10) - 7766 # - 7767 (write _test-input-stream "fn foo {\n") - 7768 (write _test-input-stream " copy 0\n") - 7769 (write _test-input-stream "}\n") - 7770 # convert - 7771 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7772 # registers except esp clobbered at this point - 7773 # restore ed - 7774 89/<- %edx 4/r32/esp - 7775 (flush _test-output-buffered-file) - 7776 (flush _test-error-buffered-file) - 7777 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7783 # check output - 7784 (check-stream-equal _test-output-stream "" "F - test-copy-with-no-output: output should be empty") - 7785 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' expects an output" "F - test-copy-with-no-output: error message") - 7786 # check that stop(1) was called - 7787 (check-ints-equal *(edx+4) 2 "F - test-copy-with-no-output: exit status") - 7788 # don't restore from ebp - 7789 81 0/subop/add %esp 8/imm32 - 7790 # . epilogue - 7791 5d/pop-to-ebp - 7792 c3/return - 7793 - 7794 test-copy-with-multiple-outputs: - 7795 # . prologue - 7796 55/push-ebp - 7797 89/<- %ebp 4/r32/esp - 7798 # setup - 7799 (clear-stream _test-input-stream) - 7800 (clear-stream $_test-input-buffered-file->buffer) - 7801 (clear-stream _test-output-stream) - 7802 (clear-stream $_test-output-buffered-file->buffer) - 7803 (clear-stream _test-error-stream) - 7804 (clear-stream $_test-error-buffered-file->buffer) - 7805 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7806 68/push 0/imm32 - 7807 68/push 0/imm32 - 7808 89/<- %edx 4/r32/esp - 7809 (tailor-exit-descriptor %edx 0x10) - 7810 # - 7811 (write _test-input-stream "fn foo {\n") - 7812 (write _test-input-stream " var x/eax: boolean <- copy 0\n") - 7813 (write _test-input-stream " var y/ecx: boolean <- copy 0\n") - 7814 (write _test-input-stream " x, y <- copy 0\n") - 7815 (write _test-input-stream "}\n") - 7816 # convert - 7817 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7818 # registers except esp clobbered at this point - 7819 # restore ed - 7820 89/<- %edx 4/r32/esp - 7821 (flush _test-output-buffered-file) - 7822 (flush _test-error-buffered-file) - 7823 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7829 # check output - 7830 (check-stream-equal _test-output-stream "" "F - test-copy-with-multiple-outputs: output should be empty") - 7831 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' must have just one output" "F - test-copy-with-multiple-outputs: error message") - 7832 # check that stop(1) was called - 7833 (check-ints-equal *(edx+4) 2 "F - test-copy-with-multiple-outputs: exit status") - 7834 # don't restore from ebp - 7835 81 0/subop/add %esp 8/imm32 - 7836 # . epilogue - 7837 5d/pop-to-ebp - 7838 c3/return - 7839 - 7840 test-copy-invalid-value-to-address: - 7841 # . prologue - 7842 55/push-ebp - 7843 89/<- %ebp 4/r32/esp - 7844 # setup - 7845 (clear-stream _test-input-stream) - 7846 (clear-stream $_test-input-buffered-file->buffer) - 7847 (clear-stream _test-output-stream) - 7848 (clear-stream $_test-output-buffered-file->buffer) - 7849 (clear-stream _test-error-stream) - 7850 (clear-stream $_test-error-buffered-file->buffer) - 7851 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7852 68/push 0/imm32 - 7853 68/push 0/imm32 - 7854 89/<- %edx 4/r32/esp - 7855 (tailor-exit-descriptor %edx 0x10) - 7856 # - 7857 (write _test-input-stream "fn foo {\n") - 7858 (write _test-input-stream " var x/eax: int <- copy 0\n") - 7859 (write _test-input-stream " var y/ecx: (addr int) <- copy x\n") - 7860 (write _test-input-stream "}\n") - 7861 # convert - 7862 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7863 # registers except esp clobbered at this point - 7864 # restore ed - 7865 89/<- %edx 4/r32/esp - 7866 (flush _test-output-buffered-file) - 7867 (flush _test-error-buffered-file) - 7868 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7874 # check output - 7875 (check-stream-equal _test-output-stream "" "F - test-copy-invalid-value-to-address: output should be empty") - 7876 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'y' must be a non-addr non-offset scalar" "F - test-copy-invalid-value-to-address: error message") - 7877 # check that stop(1) was called - 7878 (check-ints-equal *(edx+4) 2 "F - test-copy-invalid-value-to-address: exit status") - 7879 # don't restore from ebp - 7880 81 0/subop/add %esp 8/imm32 - 7881 # . epilogue - 7882 5d/pop-to-ebp - 7883 c3/return - 7884 - 7885 test-copy-null-value-to-address: - 7886 # . prologue - 7887 55/push-ebp - 7888 89/<- %ebp 4/r32/esp - 7889 # setup - 7890 (clear-stream _test-input-stream) - 7891 (clear-stream $_test-input-buffered-file->buffer) - 7892 (clear-stream _test-output-stream) - 7893 (clear-stream $_test-output-buffered-file->buffer) - 7894 # - 7895 (write _test-input-stream "fn foo {\n") - 7896 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") - 7897 (write _test-input-stream "}\n") - 7898 # convert - 7899 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7900 (flush _test-output-buffered-file) - 7901 # no errors - 7902 # . epilogue - 7903 89/<- %esp 5/r32/ebp - 7904 5d/pop-to-ebp - 7905 c3/return - 7906 - 7907 test-copy-invalid-value-to-offset: - 7908 # . prologue - 7909 55/push-ebp - 7910 89/<- %ebp 4/r32/esp - 7911 # setup - 7912 (clear-stream _test-input-stream) - 7913 (clear-stream $_test-input-buffered-file->buffer) - 7914 (clear-stream _test-output-stream) - 7915 (clear-stream $_test-output-buffered-file->buffer) - 7916 (clear-stream _test-error-stream) - 7917 (clear-stream $_test-error-buffered-file->buffer) - 7918 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7919 68/push 0/imm32 - 7920 68/push 0/imm32 - 7921 89/<- %edx 4/r32/esp - 7922 (tailor-exit-descriptor %edx 0x10) - 7923 # - 7924 (write _test-input-stream "fn foo {\n") - 7925 (write _test-input-stream " var x/eax: int <- copy 0\n") - 7926 (write _test-input-stream " var y/ecx: (offset int) <- copy x\n") - 7927 (write _test-input-stream "}\n") - 7928 # convert - 7929 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 7930 # registers except esp clobbered at this point - 7931 # restore ed - 7932 89/<- %edx 4/r32/esp - 7933 (flush _test-output-buffered-file) - 7934 (flush _test-error-buffered-file) - 7935 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7941 # check output - 7942 (check-stream-equal _test-output-stream "" "F - test-copy-invalid-value-to-address: output should be empty") - 7943 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'y' must be a non-addr non-offset scalar" "F - test-copy-invalid-value-to-address: error message") - 7944 # check that stop(1) was called - 7945 (check-ints-equal *(edx+4) 2 "F - test-copy-invalid-value-to-offset: exit status") - 7946 # don't restore from ebp - 7947 81 0/subop/add %esp 8/imm32 - 7948 # . epilogue - 7949 5d/pop-to-ebp - 7950 c3/return - 7951 - 7952 test-copy-null-value-to-offset: - 7953 # . prologue - 7954 55/push-ebp - 7955 89/<- %ebp 4/r32/esp - 7956 # setup - 7957 (clear-stream _test-input-stream) - 7958 (clear-stream $_test-input-buffered-file->buffer) - 7959 (clear-stream _test-output-stream) - 7960 (clear-stream $_test-output-buffered-file->buffer) - 7961 # - 7962 (write _test-input-stream "fn foo {\n") - 7963 (write _test-input-stream " var y/ecx: (offset int) <- copy 0\n") - 7964 (write _test-input-stream "}\n") - 7965 # convert - 7966 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 7967 (flush _test-output-buffered-file) - 7968 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 7974 # no errors - 7975 # . epilogue - 7976 89/<- %esp 5/r32/ebp - 7977 5d/pop-to-ebp - 7978 c3/return - 7979 - 7980 test-copy-non-literal-to-byte: - 7981 # . prologue - 7982 55/push-ebp - 7983 89/<- %ebp 4/r32/esp - 7984 # setup - 7985 (clear-stream _test-input-stream) - 7986 (clear-stream $_test-input-buffered-file->buffer) - 7987 (clear-stream _test-output-stream) - 7988 (clear-stream $_test-output-buffered-file->buffer) - 7989 (clear-stream _test-error-stream) - 7990 (clear-stream $_test-error-buffered-file->buffer) - 7991 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 7992 68/push 0/imm32 - 7993 68/push 0/imm32 - 7994 89/<- %edx 4/r32/esp - 7995 (tailor-exit-descriptor %edx 0x10) - 7996 # - 7997 (write _test-input-stream "fn foo {\n") - 7998 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 7999 (write _test-input-stream " var y/ecx: byte <- copy x\n") - 8000 (write _test-input-stream "}\n") - 8001 # convert - 8002 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8003 # registers except esp clobbered at this point - 8004 # restore ed - 8005 89/<- %edx 4/r32/esp - 8006 (flush _test-output-buffered-file) - 8007 (flush _test-error-buffered-file) - 8008 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8014 # check output - 8015 (check-stream-equal _test-output-stream "" "F - test-copy-non-literal-to-byte: output should be empty") - 8016 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: cannot copy non-literal to 'y' of type byte; use copy-byte" "F - test-copy-non-literal-to-byte: error message") - 8017 # check that stop(1) was called - 8018 (check-ints-equal *(edx+4) 2 "F - test-copy-non-literal-to-byte: exit status") - 8019 # don't restore from ebp - 8020 81 0/subop/add %esp 8/imm32 - 8021 # . epilogue - 8022 5d/pop-to-ebp - 8023 c3/return - 8024 - 8025 test-copy-deref-address: - 8026 # . prologue - 8027 55/push-ebp - 8028 89/<- %ebp 4/r32/esp - 8029 # setup - 8030 (clear-stream _test-input-stream) - 8031 (clear-stream $_test-input-buffered-file->buffer) - 8032 (clear-stream _test-output-stream) - 8033 (clear-stream $_test-output-buffered-file->buffer) - 8034 # - 8035 (write _test-input-stream "fn foo {\n") - 8036 (write _test-input-stream " var x/eax: (addr addr int) <- copy 0\n") - 8037 (write _test-input-stream " var y/ecx: (addr int) <- copy *x\n") - 8038 (write _test-input-stream "}\n") - 8039 # convert - 8040 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 8041 (flush _test-output-buffered-file) - 8042 # no errors - 8043 # . epilogue - 8044 5d/pop-to-ebp - 8045 c3/return - 8046 - 8047 test-copy-to-non-register: - 8048 # . prologue - 8049 55/push-ebp - 8050 89/<- %ebp 4/r32/esp - 8051 # setup - 8052 (clear-stream _test-input-stream) - 8053 (clear-stream $_test-input-buffered-file->buffer) - 8054 (clear-stream _test-output-stream) - 8055 (clear-stream $_test-output-buffered-file->buffer) - 8056 (clear-stream _test-error-stream) - 8057 (clear-stream $_test-error-buffered-file->buffer) - 8058 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8059 68/push 0/imm32 - 8060 68/push 0/imm32 - 8061 89/<- %edx 4/r32/esp - 8062 (tailor-exit-descriptor %edx 0x10) - 8063 # - 8064 (write _test-input-stream "fn foo {\n") - 8065 (write _test-input-stream " var x: int\n") - 8066 (write _test-input-stream " x <- copy 0\n") - 8067 (write _test-input-stream "}\n") - 8068 # convert - 8069 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8070 # registers except esp clobbered at this point - 8071 # restore ed - 8072 89/<- %edx 4/r32/esp - 8073 (flush _test-output-buffered-file) - 8074 (flush _test-error-buffered-file) - 8075 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8081 # check output - 8082 (check-stream-equal _test-output-stream "" "F - test-copy-to-non-register: output should be empty") - 8083 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: output 'x' not in a register" "F - test-copy-to-non-register: error message") - 8084 # check that stop(1) was called - 8085 (check-ints-equal *(edx+4) 2 "F - test-copy-to-non-register: exit status") - 8086 # don't restore from ebp - 8087 81 0/subop/add %esp 8/imm32 - 8088 # . epilogue - 8089 5d/pop-to-ebp - 8090 c3/return - 8091 - 8092 test-copy-from-non-scalar-inout: - 8093 # . prologue - 8094 55/push-ebp - 8095 89/<- %ebp 4/r32/esp - 8096 # setup - 8097 (clear-stream _test-input-stream) - 8098 (clear-stream $_test-input-buffered-file->buffer) - 8099 (clear-stream _test-output-stream) - 8100 (clear-stream $_test-output-buffered-file->buffer) - 8101 (clear-stream _test-error-stream) - 8102 (clear-stream $_test-error-buffered-file->buffer) - 8103 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8104 68/push 0/imm32 - 8105 68/push 0/imm32 - 8106 89/<- %edx 4/r32/esp - 8107 (tailor-exit-descriptor %edx 0x10) - 8108 # - 8109 (write _test-input-stream "fn foo {\n") - 8110 (write _test-input-stream " var x: (handle int)\n") - 8111 (write _test-input-stream " var y/eax: int <- copy x\n") - 8112 (write _test-input-stream "}\n") - 8113 # convert - 8114 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8115 # registers except esp clobbered at this point - 8116 # restore ed - 8117 89/<- %edx 4/r32/esp - 8118 (flush _test-output-buffered-file) - 8119 (flush _test-error-buffered-file) - 8120 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8126 # check output - 8127 (check-stream-equal _test-output-stream "" "F - test-copy-from-non-scalar-inout: output should be empty") - 8128 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'x' is too large to fit in a register" "F - test-copy-from-non-scalar-inout: error message") - 8129 # check that stop(1) was called - 8130 (check-ints-equal *(edx+4) 2 "F - test-copy-from-non-scalar-inout: exit status") - 8131 # don't restore from ebp - 8132 81 0/subop/add %esp 8/imm32 - 8133 # . epilogue - 8134 5d/pop-to-ebp - 8135 c3/return - 8136 - 8137 test-copy-to-with-no-inout: - 8138 # . prologue - 8139 55/push-ebp - 8140 89/<- %ebp 4/r32/esp - 8141 # setup - 8142 (clear-stream _test-input-stream) - 8143 (clear-stream $_test-input-buffered-file->buffer) - 8144 (clear-stream _test-output-stream) - 8145 (clear-stream $_test-output-buffered-file->buffer) - 8146 (clear-stream _test-error-stream) - 8147 (clear-stream $_test-error-buffered-file->buffer) - 8148 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8149 68/push 0/imm32 - 8150 68/push 0/imm32 - 8151 89/<- %edx 4/r32/esp - 8152 (tailor-exit-descriptor %edx 0x10) - 8153 # - 8154 (write _test-input-stream "fn foo {\n") - 8155 (write _test-input-stream " copy-to\n") - 8156 (write _test-input-stream "}\n") - 8157 # convert - 8158 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8159 # registers except esp clobbered at this point - 8160 # restore ed - 8161 89/<- %edx 4/r32/esp - 8162 (flush _test-output-buffered-file) - 8163 (flush _test-error-buffered-file) - 8164 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8170 # check output - 8171 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-inout: output should be empty") - 8172 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-no-inout: error message") - 8173 # check that stop(1) was called - 8174 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-inout: exit status") - 8175 # don't restore from ebp - 8176 81 0/subop/add %esp 8/imm32 - 8177 # . epilogue - 8178 5d/pop-to-ebp - 8179 c3/return - 8180 - 8181 test-copy-to-with-no-source: - 8182 # . prologue - 8183 55/push-ebp - 8184 89/<- %ebp 4/r32/esp - 8185 # setup - 8186 (clear-stream _test-input-stream) - 8187 (clear-stream $_test-input-buffered-file->buffer) - 8188 (clear-stream _test-output-stream) - 8189 (clear-stream $_test-output-buffered-file->buffer) - 8190 (clear-stream _test-error-stream) - 8191 (clear-stream $_test-error-buffered-file->buffer) - 8192 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8193 68/push 0/imm32 - 8194 68/push 0/imm32 - 8195 89/<- %edx 4/r32/esp - 8196 (tailor-exit-descriptor %edx 0x10) - 8197 # - 8198 (write _test-input-stream "fn foo {\n") - 8199 (write _test-input-stream " var x: boolean\n") - 8200 (write _test-input-stream " copy-to x\n") - 8201 (write _test-input-stream "}\n") - 8202 # convert - 8203 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8204 # registers except esp clobbered at this point - 8205 # restore ed - 8206 89/<- %edx 4/r32/esp - 8207 (flush _test-output-buffered-file) - 8208 (flush _test-error-buffered-file) - 8209 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8215 # check output - 8216 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-source: output should be empty") - 8217 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-no-source: error message") - 8218 # check that stop(1) was called - 8219 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-source: exit status") - 8220 # don't restore from ebp - 8221 81 0/subop/add %esp 8/imm32 - 8222 # . epilogue - 8223 5d/pop-to-ebp - 8224 c3/return - 8225 - 8226 test-copy-to-with-no-register: - 8227 # . prologue - 8228 55/push-ebp - 8229 89/<- %ebp 4/r32/esp - 8230 # setup - 8231 (clear-stream _test-input-stream) - 8232 (clear-stream $_test-input-buffered-file->buffer) - 8233 (clear-stream _test-output-stream) - 8234 (clear-stream $_test-output-buffered-file->buffer) - 8235 (clear-stream _test-error-stream) - 8236 (clear-stream $_test-error-buffered-file->buffer) - 8237 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8238 68/push 0/imm32 - 8239 68/push 0/imm32 - 8240 89/<- %edx 4/r32/esp - 8241 (tailor-exit-descriptor %edx 0x10) - 8242 # - 8243 (write _test-input-stream "fn foo {\n") - 8244 (write _test-input-stream " var x: boolean\n") - 8245 (write _test-input-stream " copy-to x, x\n") - 8246 (write _test-input-stream "}\n") - 8247 # convert - 8248 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8249 # registers except esp clobbered at this point - 8250 # restore ed - 8251 89/<- %edx 4/r32/esp - 8252 (flush _test-output-buffered-file) - 8253 (flush _test-error-buffered-file) - 8254 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8260 # check output - 8261 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-register: output should be empty") - 8262 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: source (second inout) is in memory" "F - test-copy-to-with-no-register: error message") - 8263 # check that stop(1) was called - 8264 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-register: exit status") - 8265 # don't restore from ebp - 8266 81 0/subop/add %esp 8/imm32 - 8267 # . epilogue - 8268 5d/pop-to-ebp - 8269 c3/return - 8270 - 8271 test-copy-to-with-too-many-inouts: - 8272 # . prologue - 8273 55/push-ebp - 8274 89/<- %ebp 4/r32/esp - 8275 # setup - 8276 (clear-stream _test-input-stream) - 8277 (clear-stream $_test-input-buffered-file->buffer) - 8278 (clear-stream _test-output-stream) - 8279 (clear-stream $_test-output-buffered-file->buffer) - 8280 (clear-stream _test-error-stream) - 8281 (clear-stream $_test-error-buffered-file->buffer) - 8282 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8283 68/push 0/imm32 - 8284 68/push 0/imm32 - 8285 89/<- %edx 4/r32/esp - 8286 (tailor-exit-descriptor %edx 0x10) - 8287 # - 8288 (write _test-input-stream "fn foo {\n") - 8289 (write _test-input-stream " var x: boolean\n") - 8290 (write _test-input-stream " copy-to x, 0, 0\n") - 8291 (write _test-input-stream "}\n") - 8292 # convert - 8293 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8294 # registers except esp clobbered at this point - 8295 # restore ed - 8296 89/<- %edx 4/r32/esp - 8297 (flush _test-output-buffered-file) - 8298 (flush _test-error-buffered-file) - 8299 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8305 # check output - 8306 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-too-many-inouts: output should be empty") - 8307 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-too-many-inouts: error message") - 8308 # check that stop(1) was called - 8309 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-too-many-inouts: exit status") - 8310 # don't restore from ebp - 8311 81 0/subop/add %esp 8/imm32 - 8312 # . epilogue - 8313 5d/pop-to-ebp - 8314 c3/return - 8315 - 8316 test-copy-to-with-output: - 8317 # . prologue - 8318 55/push-ebp - 8319 89/<- %ebp 4/r32/esp - 8320 # setup - 8321 (clear-stream _test-input-stream) - 8322 (clear-stream $_test-input-buffered-file->buffer) - 8323 (clear-stream _test-output-stream) - 8324 (clear-stream $_test-output-buffered-file->buffer) - 8325 (clear-stream _test-error-stream) - 8326 (clear-stream $_test-error-buffered-file->buffer) - 8327 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8328 68/push 0/imm32 - 8329 68/push 0/imm32 - 8330 89/<- %edx 4/r32/esp - 8331 (tailor-exit-descriptor %edx 0x10) - 8332 # - 8333 (write _test-input-stream "fn foo {\n") - 8334 (write _test-input-stream " var x/eax: boolean <- copy 0\n") - 8335 (write _test-input-stream " var y/ecx: boolean <- copy 0\n") - 8336 (write _test-input-stream " x <- copy-to y, 0\n") - 8337 (write _test-input-stream "}\n") - 8338 # convert - 8339 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8340 # registers except esp clobbered at this point - 8341 # restore ed - 8342 89/<- %edx 4/r32/esp - 8343 (flush _test-output-buffered-file) - 8344 (flush _test-error-buffered-file) - 8345 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8351 # check output - 8352 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-output: output should be empty") - 8353 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must not have any outputs" "F - test-copy-to-with-output: error message") - 8354 # check that stop(1) was called - 8355 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-output: exit status") - 8356 # don't restore from ebp - 8357 81 0/subop/add %esp 8/imm32 - 8358 # . epilogue - 8359 5d/pop-to-ebp - 8360 c3/return - 8361 - 8362 test-copy-to-invalid-value-to-address: - 8363 # . prologue - 8364 55/push-ebp - 8365 89/<- %ebp 4/r32/esp - 8366 # setup - 8367 (clear-stream _test-input-stream) - 8368 (clear-stream $_test-input-buffered-file->buffer) - 8369 (clear-stream _test-output-stream) - 8370 (clear-stream $_test-output-buffered-file->buffer) - 8371 (clear-stream _test-error-stream) - 8372 (clear-stream $_test-error-buffered-file->buffer) - 8373 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8374 68/push 0/imm32 - 8375 68/push 0/imm32 - 8376 89/<- %edx 4/r32/esp - 8377 (tailor-exit-descriptor %edx 0x10) - 8378 # - 8379 (write _test-input-stream "fn foo {\n") - 8380 (write _test-input-stream " var x/eax: int <- copy 0\n") - 8381 (write _test-input-stream " var y: (addr int)\n") - 8382 (write _test-input-stream " copy-to y, x\n") - 8383 (write _test-input-stream "}\n") - 8384 # convert - 8385 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8386 # registers except esp clobbered at this point - 8387 # restore ed - 8388 89/<- %edx 4/r32/esp - 8389 (flush _test-output-buffered-file) - 8390 (flush _test-error-buffered-file) - 8391 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8397 # check output - 8398 (check-stream-equal _test-output-stream "" "F - test-copy-to-invalid-value-to-address: output should be empty") - 8399 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'y' must be a non-addr non-offset scalar" "F - test-copy-to-invalid-value-to-address: error message") - 8400 # check that stop(1) was called - 8401 (check-ints-equal *(edx+4) 2 "F - test-copy-to-invalid-value-to-address: exit status") - 8402 # don't restore from ebp - 8403 81 0/subop/add %esp 8/imm32 - 8404 # . epilogue - 8405 5d/pop-to-ebp - 8406 c3/return - 8407 - 8408 test-copy-to-null-value-to-address: - 8409 # . prologue - 8410 55/push-ebp - 8411 89/<- %ebp 4/r32/esp - 8412 # setup - 8413 (clear-stream _test-input-stream) - 8414 (clear-stream $_test-input-buffered-file->buffer) - 8415 (clear-stream _test-output-stream) - 8416 (clear-stream $_test-output-buffered-file->buffer) - 8417 # - 8418 (write _test-input-stream "fn foo {\n") - 8419 (write _test-input-stream " var y: (addr int)\n") - 8420 (write _test-input-stream " copy-to y, 0\n") - 8421 (write _test-input-stream "}\n") - 8422 # convert - 8423 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 8424 (flush _test-output-buffered-file) - 8425 # no errors - 8426 # . epilogue - 8427 89/<- %esp 5/r32/ebp + 7671 # + 7672 (write _test-input-stream "fn foo {\n") + 7673 (write _test-input-stream " var a/eax: (addr int) <- copy 0\n") + 7674 (write _test-input-stream " add-to *a, 1\n") + 7675 (write _test-input-stream "}\n") + 7676 # convert + 7677 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7678 (flush _test-output-buffered-file) + 7679 # no error + 7680 # . epilogue + 7681 89/<- %esp 5/r32/ebp + 7682 5d/pop-to-ebp + 7683 c3/return + 7684 + 7685 test-copy-with-no-inout: + 7686 # . prologue + 7687 55/push-ebp + 7688 89/<- %ebp 4/r32/esp + 7689 # setup + 7690 (clear-stream _test-input-stream) + 7691 (clear-stream $_test-input-buffered-file->buffer) + 7692 (clear-stream _test-output-stream) + 7693 (clear-stream $_test-output-buffered-file->buffer) + 7694 (clear-stream _test-error-stream) + 7695 (clear-stream $_test-error-buffered-file->buffer) + 7696 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7697 68/push 0/imm32 + 7698 68/push 0/imm32 + 7699 89/<- %edx 4/r32/esp + 7700 (tailor-exit-descriptor %edx 0x10) + 7701 # + 7702 (write _test-input-stream "fn foo {\n") + 7703 (write _test-input-stream " var x/eax: boolean <- copy\n") + 7704 (write _test-input-stream "}\n") + 7705 # convert + 7706 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7707 # registers except esp clobbered at this point + 7708 # restore ed + 7709 89/<- %edx 4/r32/esp + 7710 (flush _test-output-buffered-file) + 7711 (flush _test-error-buffered-file) + 7712 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7718 # check output + 7719 (check-stream-equal _test-output-stream "" "F - test-copy-with-no-inout: output should be empty") + 7720 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' expects an inout" "F - test-copy-with-no-inout: error message") + 7721 # check that stop(1) was called + 7722 (check-ints-equal *(edx+4) 2 "F - test-copy-with-no-inout: exit status") + 7723 # don't restore from ebp + 7724 81 0/subop/add %esp 8/imm32 + 7725 # . epilogue + 7726 5d/pop-to-ebp + 7727 c3/return + 7728 + 7729 test-copy-with-multiple-inouts: + 7730 # . prologue + 7731 55/push-ebp + 7732 89/<- %ebp 4/r32/esp + 7733 # setup + 7734 (clear-stream _test-input-stream) + 7735 (clear-stream $_test-input-buffered-file->buffer) + 7736 (clear-stream _test-output-stream) + 7737 (clear-stream $_test-output-buffered-file->buffer) + 7738 (clear-stream _test-error-stream) + 7739 (clear-stream $_test-error-buffered-file->buffer) + 7740 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7741 68/push 0/imm32 + 7742 68/push 0/imm32 + 7743 89/<- %edx 4/r32/esp + 7744 (tailor-exit-descriptor %edx 0x10) + 7745 # + 7746 (write _test-input-stream "fn foo {\n") + 7747 (write _test-input-stream " var x/eax: boolean <- copy 0, 0\n") + 7748 (write _test-input-stream "}\n") + 7749 # convert + 7750 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7751 # registers except esp clobbered at this point + 7752 # restore ed + 7753 89/<- %edx 4/r32/esp + 7754 (flush _test-output-buffered-file) + 7755 (flush _test-error-buffered-file) + 7756 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7762 # check output + 7763 (check-stream-equal _test-output-stream "" "F - test-copy-with-multiple-inouts: output should be empty") + 7764 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' must have just one inout" "F - test-copy-with-multiple-inouts: error message") + 7765 # check that stop(1) was called + 7766 (check-ints-equal *(edx+4) 2 "F - test-copy-with-multiple-inouts: exit status") + 7767 # don't restore from ebp + 7768 81 0/subop/add %esp 8/imm32 + 7769 # . epilogue + 7770 5d/pop-to-ebp + 7771 c3/return + 7772 + 7773 test-copy-with-no-output: + 7774 # . prologue + 7775 55/push-ebp + 7776 89/<- %ebp 4/r32/esp + 7777 # setup + 7778 (clear-stream _test-input-stream) + 7779 (clear-stream $_test-input-buffered-file->buffer) + 7780 (clear-stream _test-output-stream) + 7781 (clear-stream $_test-output-buffered-file->buffer) + 7782 (clear-stream _test-error-stream) + 7783 (clear-stream $_test-error-buffered-file->buffer) + 7784 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7785 68/push 0/imm32 + 7786 68/push 0/imm32 + 7787 89/<- %edx 4/r32/esp + 7788 (tailor-exit-descriptor %edx 0x10) + 7789 # + 7790 (write _test-input-stream "fn foo {\n") + 7791 (write _test-input-stream " copy 0\n") + 7792 (write _test-input-stream "}\n") + 7793 # convert + 7794 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7795 # registers except esp clobbered at this point + 7796 # restore ed + 7797 89/<- %edx 4/r32/esp + 7798 (flush _test-output-buffered-file) + 7799 (flush _test-error-buffered-file) + 7800 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7806 # check output + 7807 (check-stream-equal _test-output-stream "" "F - test-copy-with-no-output: output should be empty") + 7808 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' expects an output" "F - test-copy-with-no-output: error message") + 7809 # check that stop(1) was called + 7810 (check-ints-equal *(edx+4) 2 "F - test-copy-with-no-output: exit status") + 7811 # don't restore from ebp + 7812 81 0/subop/add %esp 8/imm32 + 7813 # . epilogue + 7814 5d/pop-to-ebp + 7815 c3/return + 7816 + 7817 test-copy-with-multiple-outputs: + 7818 # . prologue + 7819 55/push-ebp + 7820 89/<- %ebp 4/r32/esp + 7821 # setup + 7822 (clear-stream _test-input-stream) + 7823 (clear-stream $_test-input-buffered-file->buffer) + 7824 (clear-stream _test-output-stream) + 7825 (clear-stream $_test-output-buffered-file->buffer) + 7826 (clear-stream _test-error-stream) + 7827 (clear-stream $_test-error-buffered-file->buffer) + 7828 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7829 68/push 0/imm32 + 7830 68/push 0/imm32 + 7831 89/<- %edx 4/r32/esp + 7832 (tailor-exit-descriptor %edx 0x10) + 7833 # + 7834 (write _test-input-stream "fn foo {\n") + 7835 (write _test-input-stream " var x/eax: boolean <- copy 0\n") + 7836 (write _test-input-stream " var y/ecx: boolean <- copy 0\n") + 7837 (write _test-input-stream " x, y <- copy 0\n") + 7838 (write _test-input-stream "}\n") + 7839 # convert + 7840 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7841 # registers except esp clobbered at this point + 7842 # restore ed + 7843 89/<- %edx 4/r32/esp + 7844 (flush _test-output-buffered-file) + 7845 (flush _test-error-buffered-file) + 7846 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7852 # check output + 7853 (check-stream-equal _test-output-stream "" "F - test-copy-with-multiple-outputs: output should be empty") + 7854 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' must have just one output" "F - test-copy-with-multiple-outputs: error message") + 7855 # check that stop(1) was called + 7856 (check-ints-equal *(edx+4) 2 "F - test-copy-with-multiple-outputs: exit status") + 7857 # don't restore from ebp + 7858 81 0/subop/add %esp 8/imm32 + 7859 # . epilogue + 7860 5d/pop-to-ebp + 7861 c3/return + 7862 + 7863 test-copy-invalid-value-to-address: + 7864 # . prologue + 7865 55/push-ebp + 7866 89/<- %ebp 4/r32/esp + 7867 # setup + 7868 (clear-stream _test-input-stream) + 7869 (clear-stream $_test-input-buffered-file->buffer) + 7870 (clear-stream _test-output-stream) + 7871 (clear-stream $_test-output-buffered-file->buffer) + 7872 (clear-stream _test-error-stream) + 7873 (clear-stream $_test-error-buffered-file->buffer) + 7874 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7875 68/push 0/imm32 + 7876 68/push 0/imm32 + 7877 89/<- %edx 4/r32/esp + 7878 (tailor-exit-descriptor %edx 0x10) + 7879 # + 7880 (write _test-input-stream "fn foo {\n") + 7881 (write _test-input-stream " var x/eax: int <- copy 0\n") + 7882 (write _test-input-stream " var y/ecx: (addr int) <- copy x\n") + 7883 (write _test-input-stream "}\n") + 7884 # convert + 7885 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7886 # registers except esp clobbered at this point + 7887 # restore ed + 7888 89/<- %edx 4/r32/esp + 7889 (flush _test-output-buffered-file) + 7890 (flush _test-error-buffered-file) + 7891 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7897 # check output + 7898 (check-stream-equal _test-output-stream "" "F - test-copy-invalid-value-to-address: output should be empty") + 7899 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'y' must be a non-addr non-offset scalar" "F - test-copy-invalid-value-to-address: error message") + 7900 # check that stop(1) was called + 7901 (check-ints-equal *(edx+4) 2 "F - test-copy-invalid-value-to-address: exit status") + 7902 # don't restore from ebp + 7903 81 0/subop/add %esp 8/imm32 + 7904 # . epilogue + 7905 5d/pop-to-ebp + 7906 c3/return + 7907 + 7908 test-copy-null-value-to-address: + 7909 # . prologue + 7910 55/push-ebp + 7911 89/<- %ebp 4/r32/esp + 7912 # setup + 7913 (clear-stream _test-input-stream) + 7914 (clear-stream $_test-input-buffered-file->buffer) + 7915 (clear-stream _test-output-stream) + 7916 (clear-stream $_test-output-buffered-file->buffer) + 7917 # + 7918 (write _test-input-stream "fn foo {\n") + 7919 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") + 7920 (write _test-input-stream "}\n") + 7921 # convert + 7922 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7923 (flush _test-output-buffered-file) + 7924 # no errors + 7925 # . epilogue + 7926 89/<- %esp 5/r32/ebp + 7927 5d/pop-to-ebp + 7928 c3/return + 7929 + 7930 test-copy-invalid-value-to-offset: + 7931 # . prologue + 7932 55/push-ebp + 7933 89/<- %ebp 4/r32/esp + 7934 # setup + 7935 (clear-stream _test-input-stream) + 7936 (clear-stream $_test-input-buffered-file->buffer) + 7937 (clear-stream _test-output-stream) + 7938 (clear-stream $_test-output-buffered-file->buffer) + 7939 (clear-stream _test-error-stream) + 7940 (clear-stream $_test-error-buffered-file->buffer) + 7941 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 7942 68/push 0/imm32 + 7943 68/push 0/imm32 + 7944 89/<- %edx 4/r32/esp + 7945 (tailor-exit-descriptor %edx 0x10) + 7946 # + 7947 (write _test-input-stream "fn foo {\n") + 7948 (write _test-input-stream " var x/eax: int <- copy 0\n") + 7949 (write _test-input-stream " var y/ecx: (offset int) <- copy x\n") + 7950 (write _test-input-stream "}\n") + 7951 # convert + 7952 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 7953 # registers except esp clobbered at this point + 7954 # restore ed + 7955 89/<- %edx 4/r32/esp + 7956 (flush _test-output-buffered-file) + 7957 (flush _test-error-buffered-file) + 7958 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7964 # check output + 7965 (check-stream-equal _test-output-stream "" "F - test-copy-invalid-value-to-address: output should be empty") + 7966 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'y' must be a non-addr non-offset scalar" "F - test-copy-invalid-value-to-address: error message") + 7967 # check that stop(1) was called + 7968 (check-ints-equal *(edx+4) 2 "F - test-copy-invalid-value-to-offset: exit status") + 7969 # don't restore from ebp + 7970 81 0/subop/add %esp 8/imm32 + 7971 # . epilogue + 7972 5d/pop-to-ebp + 7973 c3/return + 7974 + 7975 test-copy-null-value-to-offset: + 7976 # . prologue + 7977 55/push-ebp + 7978 89/<- %ebp 4/r32/esp + 7979 # setup + 7980 (clear-stream _test-input-stream) + 7981 (clear-stream $_test-input-buffered-file->buffer) + 7982 (clear-stream _test-output-stream) + 7983 (clear-stream $_test-output-buffered-file->buffer) + 7984 # + 7985 (write _test-input-stream "fn foo {\n") + 7986 (write _test-input-stream " var y/ecx: (offset int) <- copy 0\n") + 7987 (write _test-input-stream "}\n") + 7988 # convert + 7989 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 7990 (flush _test-output-buffered-file) + 7991 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 7997 # no errors + 7998 # . epilogue + 7999 89/<- %esp 5/r32/ebp + 8000 5d/pop-to-ebp + 8001 c3/return + 8002 + 8003 test-copy-non-literal-to-byte: + 8004 # . prologue + 8005 55/push-ebp + 8006 89/<- %ebp 4/r32/esp + 8007 # setup + 8008 (clear-stream _test-input-stream) + 8009 (clear-stream $_test-input-buffered-file->buffer) + 8010 (clear-stream _test-output-stream) + 8011 (clear-stream $_test-output-buffered-file->buffer) + 8012 (clear-stream _test-error-stream) + 8013 (clear-stream $_test-error-buffered-file->buffer) + 8014 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8015 68/push 0/imm32 + 8016 68/push 0/imm32 + 8017 89/<- %edx 4/r32/esp + 8018 (tailor-exit-descriptor %edx 0x10) + 8019 # + 8020 (write _test-input-stream "fn foo {\n") + 8021 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 8022 (write _test-input-stream " var y/ecx: byte <- copy x\n") + 8023 (write _test-input-stream "}\n") + 8024 # convert + 8025 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8026 # registers except esp clobbered at this point + 8027 # restore ed + 8028 89/<- %edx 4/r32/esp + 8029 (flush _test-output-buffered-file) + 8030 (flush _test-error-buffered-file) + 8031 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8037 # check output + 8038 (check-stream-equal _test-output-stream "" "F - test-copy-non-literal-to-byte: output should be empty") + 8039 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: cannot copy non-literal to 'y' of type byte; use copy-byte" "F - test-copy-non-literal-to-byte: error message") + 8040 # check that stop(1) was called + 8041 (check-ints-equal *(edx+4) 2 "F - test-copy-non-literal-to-byte: exit status") + 8042 # don't restore from ebp + 8043 81 0/subop/add %esp 8/imm32 + 8044 # . epilogue + 8045 5d/pop-to-ebp + 8046 c3/return + 8047 + 8048 test-copy-deref-address: + 8049 # . prologue + 8050 55/push-ebp + 8051 89/<- %ebp 4/r32/esp + 8052 # setup + 8053 (clear-stream _test-input-stream) + 8054 (clear-stream $_test-input-buffered-file->buffer) + 8055 (clear-stream _test-output-stream) + 8056 (clear-stream $_test-output-buffered-file->buffer) + 8057 # + 8058 (write _test-input-stream "fn foo {\n") + 8059 (write _test-input-stream " var x/eax: (addr addr int) <- copy 0\n") + 8060 (write _test-input-stream " var y/ecx: (addr int) <- copy *x\n") + 8061 (write _test-input-stream "}\n") + 8062 # convert + 8063 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 8064 (flush _test-output-buffered-file) + 8065 # no errors + 8066 # . epilogue + 8067 5d/pop-to-ebp + 8068 c3/return + 8069 + 8070 test-copy-to-non-register: + 8071 # . prologue + 8072 55/push-ebp + 8073 89/<- %ebp 4/r32/esp + 8074 # setup + 8075 (clear-stream _test-input-stream) + 8076 (clear-stream $_test-input-buffered-file->buffer) + 8077 (clear-stream _test-output-stream) + 8078 (clear-stream $_test-output-buffered-file->buffer) + 8079 (clear-stream _test-error-stream) + 8080 (clear-stream $_test-error-buffered-file->buffer) + 8081 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8082 68/push 0/imm32 + 8083 68/push 0/imm32 + 8084 89/<- %edx 4/r32/esp + 8085 (tailor-exit-descriptor %edx 0x10) + 8086 # + 8087 (write _test-input-stream "fn foo {\n") + 8088 (write _test-input-stream " var x: int\n") + 8089 (write _test-input-stream " x <- copy 0\n") + 8090 (write _test-input-stream "}\n") + 8091 # convert + 8092 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8093 # registers except esp clobbered at this point + 8094 # restore ed + 8095 89/<- %edx 4/r32/esp + 8096 (flush _test-output-buffered-file) + 8097 (flush _test-error-buffered-file) + 8098 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8104 # check output + 8105 (check-stream-equal _test-output-stream "" "F - test-copy-to-non-register: output should be empty") + 8106 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: output 'x' not in a register" "F - test-copy-to-non-register: error message") + 8107 # check that stop(1) was called + 8108 (check-ints-equal *(edx+4) 2 "F - test-copy-to-non-register: exit status") + 8109 # don't restore from ebp + 8110 81 0/subop/add %esp 8/imm32 + 8111 # . epilogue + 8112 5d/pop-to-ebp + 8113 c3/return + 8114 + 8115 test-copy-from-non-scalar-inout: + 8116 # . prologue + 8117 55/push-ebp + 8118 89/<- %ebp 4/r32/esp + 8119 # setup + 8120 (clear-stream _test-input-stream) + 8121 (clear-stream $_test-input-buffered-file->buffer) + 8122 (clear-stream _test-output-stream) + 8123 (clear-stream $_test-output-buffered-file->buffer) + 8124 (clear-stream _test-error-stream) + 8125 (clear-stream $_test-error-buffered-file->buffer) + 8126 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8127 68/push 0/imm32 + 8128 68/push 0/imm32 + 8129 89/<- %edx 4/r32/esp + 8130 (tailor-exit-descriptor %edx 0x10) + 8131 # + 8132 (write _test-input-stream "fn foo {\n") + 8133 (write _test-input-stream " var x: (handle int)\n") + 8134 (write _test-input-stream " var y/eax: int <- copy x\n") + 8135 (write _test-input-stream "}\n") + 8136 # convert + 8137 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8138 # registers except esp clobbered at this point + 8139 # restore ed + 8140 89/<- %edx 4/r32/esp + 8141 (flush _test-output-buffered-file) + 8142 (flush _test-error-buffered-file) + 8143 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8149 # check output + 8150 (check-stream-equal _test-output-stream "" "F - test-copy-from-non-scalar-inout: output should be empty") + 8151 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'x' is too large to fit in a register" "F - test-copy-from-non-scalar-inout: error message") + 8152 # check that stop(1) was called + 8153 (check-ints-equal *(edx+4) 2 "F - test-copy-from-non-scalar-inout: exit status") + 8154 # don't restore from ebp + 8155 81 0/subop/add %esp 8/imm32 + 8156 # . epilogue + 8157 5d/pop-to-ebp + 8158 c3/return + 8159 + 8160 test-copy-to-with-no-inout: + 8161 # . prologue + 8162 55/push-ebp + 8163 89/<- %ebp 4/r32/esp + 8164 # setup + 8165 (clear-stream _test-input-stream) + 8166 (clear-stream $_test-input-buffered-file->buffer) + 8167 (clear-stream _test-output-stream) + 8168 (clear-stream $_test-output-buffered-file->buffer) + 8169 (clear-stream _test-error-stream) + 8170 (clear-stream $_test-error-buffered-file->buffer) + 8171 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8172 68/push 0/imm32 + 8173 68/push 0/imm32 + 8174 89/<- %edx 4/r32/esp + 8175 (tailor-exit-descriptor %edx 0x10) + 8176 # + 8177 (write _test-input-stream "fn foo {\n") + 8178 (write _test-input-stream " copy-to\n") + 8179 (write _test-input-stream "}\n") + 8180 # convert + 8181 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8182 # registers except esp clobbered at this point + 8183 # restore ed + 8184 89/<- %edx 4/r32/esp + 8185 (flush _test-output-buffered-file) + 8186 (flush _test-error-buffered-file) + 8187 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8193 # check output + 8194 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-inout: output should be empty") + 8195 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-no-inout: error message") + 8196 # check that stop(1) was called + 8197 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-inout: exit status") + 8198 # don't restore from ebp + 8199 81 0/subop/add %esp 8/imm32 + 8200 # . epilogue + 8201 5d/pop-to-ebp + 8202 c3/return + 8203 + 8204 test-copy-to-with-no-source: + 8205 # . prologue + 8206 55/push-ebp + 8207 89/<- %ebp 4/r32/esp + 8208 # setup + 8209 (clear-stream _test-input-stream) + 8210 (clear-stream $_test-input-buffered-file->buffer) + 8211 (clear-stream _test-output-stream) + 8212 (clear-stream $_test-output-buffered-file->buffer) + 8213 (clear-stream _test-error-stream) + 8214 (clear-stream $_test-error-buffered-file->buffer) + 8215 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8216 68/push 0/imm32 + 8217 68/push 0/imm32 + 8218 89/<- %edx 4/r32/esp + 8219 (tailor-exit-descriptor %edx 0x10) + 8220 # + 8221 (write _test-input-stream "fn foo {\n") + 8222 (write _test-input-stream " var x: boolean\n") + 8223 (write _test-input-stream " copy-to x\n") + 8224 (write _test-input-stream "}\n") + 8225 # convert + 8226 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8227 # registers except esp clobbered at this point + 8228 # restore ed + 8229 89/<- %edx 4/r32/esp + 8230 (flush _test-output-buffered-file) + 8231 (flush _test-error-buffered-file) + 8232 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8238 # check output + 8239 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-source: output should be empty") + 8240 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-no-source: error message") + 8241 # check that stop(1) was called + 8242 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-source: exit status") + 8243 # don't restore from ebp + 8244 81 0/subop/add %esp 8/imm32 + 8245 # . epilogue + 8246 5d/pop-to-ebp + 8247 c3/return + 8248 + 8249 test-copy-to-with-no-register: + 8250 # . prologue + 8251 55/push-ebp + 8252 89/<- %ebp 4/r32/esp + 8253 # setup + 8254 (clear-stream _test-input-stream) + 8255 (clear-stream $_test-input-buffered-file->buffer) + 8256 (clear-stream _test-output-stream) + 8257 (clear-stream $_test-output-buffered-file->buffer) + 8258 (clear-stream _test-error-stream) + 8259 (clear-stream $_test-error-buffered-file->buffer) + 8260 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8261 68/push 0/imm32 + 8262 68/push 0/imm32 + 8263 89/<- %edx 4/r32/esp + 8264 (tailor-exit-descriptor %edx 0x10) + 8265 # + 8266 (write _test-input-stream "fn foo {\n") + 8267 (write _test-input-stream " var x: boolean\n") + 8268 (write _test-input-stream " copy-to x, x\n") + 8269 (write _test-input-stream "}\n") + 8270 # convert + 8271 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8272 # registers except esp clobbered at this point + 8273 # restore ed + 8274 89/<- %edx 4/r32/esp + 8275 (flush _test-output-buffered-file) + 8276 (flush _test-error-buffered-file) + 8277 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8283 # check output + 8284 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-register: output should be empty") + 8285 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: source (second inout) is in memory" "F - test-copy-to-with-no-register: error message") + 8286 # check that stop(1) was called + 8287 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-register: exit status") + 8288 # don't restore from ebp + 8289 81 0/subop/add %esp 8/imm32 + 8290 # . epilogue + 8291 5d/pop-to-ebp + 8292 c3/return + 8293 + 8294 test-copy-to-with-too-many-inouts: + 8295 # . prologue + 8296 55/push-ebp + 8297 89/<- %ebp 4/r32/esp + 8298 # setup + 8299 (clear-stream _test-input-stream) + 8300 (clear-stream $_test-input-buffered-file->buffer) + 8301 (clear-stream _test-output-stream) + 8302 (clear-stream $_test-output-buffered-file->buffer) + 8303 (clear-stream _test-error-stream) + 8304 (clear-stream $_test-error-buffered-file->buffer) + 8305 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8306 68/push 0/imm32 + 8307 68/push 0/imm32 + 8308 89/<- %edx 4/r32/esp + 8309 (tailor-exit-descriptor %edx 0x10) + 8310 # + 8311 (write _test-input-stream "fn foo {\n") + 8312 (write _test-input-stream " var x: boolean\n") + 8313 (write _test-input-stream " copy-to x, 0, 0\n") + 8314 (write _test-input-stream "}\n") + 8315 # convert + 8316 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8317 # registers except esp clobbered at this point + 8318 # restore ed + 8319 89/<- %edx 4/r32/esp + 8320 (flush _test-output-buffered-file) + 8321 (flush _test-error-buffered-file) + 8322 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8328 # check output + 8329 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-too-many-inouts: output should be empty") + 8330 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-too-many-inouts: error message") + 8331 # check that stop(1) was called + 8332 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-too-many-inouts: exit status") + 8333 # don't restore from ebp + 8334 81 0/subop/add %esp 8/imm32 + 8335 # . epilogue + 8336 5d/pop-to-ebp + 8337 c3/return + 8338 + 8339 test-copy-to-with-output: + 8340 # . prologue + 8341 55/push-ebp + 8342 89/<- %ebp 4/r32/esp + 8343 # setup + 8344 (clear-stream _test-input-stream) + 8345 (clear-stream $_test-input-buffered-file->buffer) + 8346 (clear-stream _test-output-stream) + 8347 (clear-stream $_test-output-buffered-file->buffer) + 8348 (clear-stream _test-error-stream) + 8349 (clear-stream $_test-error-buffered-file->buffer) + 8350 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8351 68/push 0/imm32 + 8352 68/push 0/imm32 + 8353 89/<- %edx 4/r32/esp + 8354 (tailor-exit-descriptor %edx 0x10) + 8355 # + 8356 (write _test-input-stream "fn foo {\n") + 8357 (write _test-input-stream " var x/eax: boolean <- copy 0\n") + 8358 (write _test-input-stream " var y/ecx: boolean <- copy 0\n") + 8359 (write _test-input-stream " x <- copy-to y, 0\n") + 8360 (write _test-input-stream "}\n") + 8361 # convert + 8362 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8363 # registers except esp clobbered at this point + 8364 # restore ed + 8365 89/<- %edx 4/r32/esp + 8366 (flush _test-output-buffered-file) + 8367 (flush _test-error-buffered-file) + 8368 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8374 # check output + 8375 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-output: output should be empty") + 8376 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must not have any outputs" "F - test-copy-to-with-output: error message") + 8377 # check that stop(1) was called + 8378 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-output: exit status") + 8379 # don't restore from ebp + 8380 81 0/subop/add %esp 8/imm32 + 8381 # . epilogue + 8382 5d/pop-to-ebp + 8383 c3/return + 8384 + 8385 test-copy-to-invalid-value-to-address: + 8386 # . prologue + 8387 55/push-ebp + 8388 89/<- %ebp 4/r32/esp + 8389 # setup + 8390 (clear-stream _test-input-stream) + 8391 (clear-stream $_test-input-buffered-file->buffer) + 8392 (clear-stream _test-output-stream) + 8393 (clear-stream $_test-output-buffered-file->buffer) + 8394 (clear-stream _test-error-stream) + 8395 (clear-stream $_test-error-buffered-file->buffer) + 8396 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8397 68/push 0/imm32 + 8398 68/push 0/imm32 + 8399 89/<- %edx 4/r32/esp + 8400 (tailor-exit-descriptor %edx 0x10) + 8401 # + 8402 (write _test-input-stream "fn foo {\n") + 8403 (write _test-input-stream " var x/eax: int <- copy 0\n") + 8404 (write _test-input-stream " var y: (addr int)\n") + 8405 (write _test-input-stream " copy-to y, x\n") + 8406 (write _test-input-stream "}\n") + 8407 # convert + 8408 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8409 # registers except esp clobbered at this point + 8410 # restore ed + 8411 89/<- %edx 4/r32/esp + 8412 (flush _test-output-buffered-file) + 8413 (flush _test-error-buffered-file) + 8414 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8420 # check output + 8421 (check-stream-equal _test-output-stream "" "F - test-copy-to-invalid-value-to-address: output should be empty") + 8422 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'y' must be a non-addr non-offset scalar" "F - test-copy-to-invalid-value-to-address: error message") + 8423 # check that stop(1) was called + 8424 (check-ints-equal *(edx+4) 2 "F - test-copy-to-invalid-value-to-address: exit status") + 8425 # don't restore from ebp + 8426 81 0/subop/add %esp 8/imm32 + 8427 # . epilogue 8428 5d/pop-to-ebp 8429 c3/return 8430 - 8431 test-copy-to-invalid-value-to-offset: + 8431 test-copy-to-null-value-to-address: 8432 # . prologue 8433 55/push-ebp 8434 89/<- %ebp 4/r32/esp @@ -7699,62 +7699,62 @@ if ('onhashchange' in window) { 8437 (clear-stream $_test-input-buffered-file->buffer) 8438 (clear-stream _test-output-stream) 8439 (clear-stream $_test-output-buffered-file->buffer) - 8440 (clear-stream _test-error-stream) - 8441 (clear-stream $_test-error-buffered-file->buffer) - 8442 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8443 68/push 0/imm32 - 8444 68/push 0/imm32 - 8445 89/<- %edx 4/r32/esp - 8446 (tailor-exit-descriptor %edx 0x10) - 8447 # - 8448 (write _test-input-stream "fn foo {\n") - 8449 (write _test-input-stream " var x/eax: int <- copy 0\n") - 8450 (write _test-input-stream " var y: (offset int)\n") - 8451 (write _test-input-stream " copy-to y, x\n") - 8452 (write _test-input-stream "}\n") - 8453 # convert - 8454 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8455 # registers except esp clobbered at this point - 8456 # restore ed - 8457 89/<- %edx 4/r32/esp - 8458 (flush _test-output-buffered-file) - 8459 (flush _test-error-buffered-file) - 8460 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8466 # check output - 8467 (check-stream-equal _test-output-stream "" "F - test-copy-to-invalid-value-to-offset: output should be empty") - 8468 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'y' must be a non-addr non-offset scalar" "F - test-copy-to-invalid-value-to-offset: error message") - 8469 # check that stop(1) was called - 8470 (check-ints-equal *(edx+4) 2 "F - test-copy-to-invalid-value-to-offset: exit status") - 8471 # don't restore from ebp - 8472 81 0/subop/add %esp 8/imm32 - 8473 # . epilogue - 8474 5d/pop-to-ebp - 8475 c3/return - 8476 - 8477 test-copy-to-null-value-to-offset: - 8478 # . prologue - 8479 55/push-ebp - 8480 89/<- %ebp 4/r32/esp - 8481 # setup - 8482 (clear-stream _test-input-stream) - 8483 (clear-stream $_test-input-buffered-file->buffer) - 8484 (clear-stream _test-output-stream) - 8485 (clear-stream $_test-output-buffered-file->buffer) - 8486 # - 8487 (write _test-input-stream "fn foo {\n") - 8488 (write _test-input-stream " var y: (offset int)\n") - 8489 (write _test-input-stream " copy-to y, 0\n") - 8490 (write _test-input-stream "}\n") - 8491 # convert - 8492 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 8493 (flush _test-output-buffered-file) - 8494 # no errors - 8495 # . epilogue - 8496 89/<- %esp 5/r32/ebp + 8440 # + 8441 (write _test-input-stream "fn foo {\n") + 8442 (write _test-input-stream " var y: (addr int)\n") + 8443 (write _test-input-stream " copy-to y, 0\n") + 8444 (write _test-input-stream "}\n") + 8445 # convert + 8446 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 8447 (flush _test-output-buffered-file) + 8448 # no errors + 8449 # . epilogue + 8450 89/<- %esp 5/r32/ebp + 8451 5d/pop-to-ebp + 8452 c3/return + 8453 + 8454 test-copy-to-invalid-value-to-offset: + 8455 # . prologue + 8456 55/push-ebp + 8457 89/<- %ebp 4/r32/esp + 8458 # setup + 8459 (clear-stream _test-input-stream) + 8460 (clear-stream $_test-input-buffered-file->buffer) + 8461 (clear-stream _test-output-stream) + 8462 (clear-stream $_test-output-buffered-file->buffer) + 8463 (clear-stream _test-error-stream) + 8464 (clear-stream $_test-error-buffered-file->buffer) + 8465 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8466 68/push 0/imm32 + 8467 68/push 0/imm32 + 8468 89/<- %edx 4/r32/esp + 8469 (tailor-exit-descriptor %edx 0x10) + 8470 # + 8471 (write _test-input-stream "fn foo {\n") + 8472 (write _test-input-stream " var x/eax: int <- copy 0\n") + 8473 (write _test-input-stream " var y: (offset int)\n") + 8474 (write _test-input-stream " copy-to y, x\n") + 8475 (write _test-input-stream "}\n") + 8476 # convert + 8477 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8478 # registers except esp clobbered at this point + 8479 # restore ed + 8480 89/<- %edx 4/r32/esp + 8481 (flush _test-output-buffered-file) + 8482 (flush _test-error-buffered-file) + 8483 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8489 # check output + 8490 (check-stream-equal _test-output-stream "" "F - test-copy-to-invalid-value-to-offset: output should be empty") + 8491 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'y' must be a non-addr non-offset scalar" "F - test-copy-to-invalid-value-to-offset: error message") + 8492 # check that stop(1) was called + 8493 (check-ints-equal *(edx+4) 2 "F - test-copy-to-invalid-value-to-offset: exit status") + 8494 # don't restore from ebp + 8495 81 0/subop/add %esp 8/imm32 + 8496 # . epilogue 8497 5d/pop-to-ebp 8498 c3/return 8499 - 8500 test-copy-to-non-literal-to-byte: + 8500 test-copy-to-null-value-to-offset: 8501 # . prologue 8502 55/push-ebp 8503 89/<- %ebp 4/r32/esp @@ -7763,62 +7763,62 @@ if ('onhashchange' in window) { 8506 (clear-stream $_test-input-buffered-file->buffer) 8507 (clear-stream _test-output-stream) 8508 (clear-stream $_test-output-buffered-file->buffer) - 8509 (clear-stream _test-error-stream) - 8510 (clear-stream $_test-error-buffered-file->buffer) - 8511 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8512 68/push 0/imm32 - 8513 68/push 0/imm32 - 8514 89/<- %edx 4/r32/esp - 8515 (tailor-exit-descriptor %edx 0x10) - 8516 # - 8517 (write _test-input-stream "fn foo {\n") - 8518 (write _test-input-stream " var x/ecx: byte <- copy 3\n") - 8519 (write _test-input-stream " var y/eax: (addr byte) <- copy 0\n") - 8520 (write _test-input-stream " copy-to *y, x\n") - 8521 (write _test-input-stream "}\n") - 8522 # convert - 8523 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8524 # registers except esp clobbered at this point - 8525 # restore ed - 8526 89/<- %edx 4/r32/esp - 8527 (flush _test-output-buffered-file) - 8528 (flush _test-error-buffered-file) - 8529 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8535 # check output - 8536 (check-stream-equal _test-output-stream "" "F - test-copy-to-non-literal-to-byte: output should be empty") - 8537 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: cannot copy non-literal to type byte; use copy-byte-to" "F - test-copy-to-non-literal-to-byte: error message") - 8538 # check that stop(1) was called - 8539 (check-ints-equal *(edx+4) 2 "F - test-copy-to-non-literal-to-byte: exit status") - 8540 # don't restore from ebp - 8541 81 0/subop/add %esp 8/imm32 - 8542 # . epilogue - 8543 5d/pop-to-ebp - 8544 c3/return - 8545 - 8546 test-copy-to-deref-address: - 8547 # . prologue - 8548 55/push-ebp - 8549 89/<- %ebp 4/r32/esp - 8550 # setup - 8551 (clear-stream _test-input-stream) - 8552 (clear-stream $_test-input-buffered-file->buffer) - 8553 (clear-stream _test-output-stream) - 8554 (clear-stream $_test-output-buffered-file->buffer) - 8555 # - 8556 (write _test-input-stream "fn foo {\n") - 8557 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") - 8558 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n") - 8559 (write _test-input-stream " copy-to *y, x\n") - 8560 (write _test-input-stream "}\n") - 8561 # convert - 8562 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 8563 (flush _test-output-buffered-file) - 8564 # no errors + 8509 # + 8510 (write _test-input-stream "fn foo {\n") + 8511 (write _test-input-stream " var y: (offset int)\n") + 8512 (write _test-input-stream " copy-to y, 0\n") + 8513 (write _test-input-stream "}\n") + 8514 # convert + 8515 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 8516 (flush _test-output-buffered-file) + 8517 # no errors + 8518 # . epilogue + 8519 89/<- %esp 5/r32/ebp + 8520 5d/pop-to-ebp + 8521 c3/return + 8522 + 8523 test-copy-to-non-literal-to-byte: + 8524 # . prologue + 8525 55/push-ebp + 8526 89/<- %ebp 4/r32/esp + 8527 # setup + 8528 (clear-stream _test-input-stream) + 8529 (clear-stream $_test-input-buffered-file->buffer) + 8530 (clear-stream _test-output-stream) + 8531 (clear-stream $_test-output-buffered-file->buffer) + 8532 (clear-stream _test-error-stream) + 8533 (clear-stream $_test-error-buffered-file->buffer) + 8534 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8535 68/push 0/imm32 + 8536 68/push 0/imm32 + 8537 89/<- %edx 4/r32/esp + 8538 (tailor-exit-descriptor %edx 0x10) + 8539 # + 8540 (write _test-input-stream "fn foo {\n") + 8541 (write _test-input-stream " var x/ecx: byte <- copy 3\n") + 8542 (write _test-input-stream " var y/eax: (addr byte) <- copy 0\n") + 8543 (write _test-input-stream " copy-to *y, x\n") + 8544 (write _test-input-stream "}\n") + 8545 # convert + 8546 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8547 # registers except esp clobbered at this point + 8548 # restore ed + 8549 89/<- %edx 4/r32/esp + 8550 (flush _test-output-buffered-file) + 8551 (flush _test-error-buffered-file) + 8552 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8558 # check output + 8559 (check-stream-equal _test-output-stream "" "F - test-copy-to-non-literal-to-byte: output should be empty") + 8560 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: cannot copy non-literal to type byte; use copy-byte-to" "F - test-copy-to-non-literal-to-byte: error message") + 8561 # check that stop(1) was called + 8562 (check-ints-equal *(edx+4) 2 "F - test-copy-to-non-literal-to-byte: exit status") + 8563 # don't restore from ebp + 8564 81 0/subop/add %esp 8/imm32 8565 # . epilogue 8566 5d/pop-to-ebp 8567 c3/return 8568 - 8569 test-copy-to-from-non-scalar-inout: + 8569 test-copy-to-deref-address: 8570 # . prologue 8571 55/push-ebp 8572 89/<- %ebp 4/r32/esp @@ -7827,565 +7827,565 @@ if ('onhashchange' in window) { 8575 (clear-stream $_test-input-buffered-file->buffer) 8576 (clear-stream _test-output-stream) 8577 (clear-stream $_test-output-buffered-file->buffer) - 8578 (clear-stream _test-error-stream) - 8579 (clear-stream $_test-error-buffered-file->buffer) - 8580 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8581 68/push 0/imm32 - 8582 68/push 0/imm32 - 8583 89/<- %edx 4/r32/esp - 8584 (tailor-exit-descriptor %edx 0x10) - 8585 # - 8586 (write _test-input-stream "fn foo {\n") - 8587 (write _test-input-stream " var x: (handle int)\n") - 8588 (write _test-input-stream " var y: int\n") - 8589 (write _test-input-stream " copy-to y, x\n") - 8590 (write _test-input-stream "}\n") - 8591 # convert - 8592 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8593 # registers except esp clobbered at this point - 8594 # restore ed - 8595 89/<- %edx 4/r32/esp - 8596 (flush _test-output-buffered-file) - 8597 (flush _test-error-buffered-file) - 8598 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8604 # check output - 8605 (check-stream-equal _test-output-stream "" "F - test-copy-to-from-non-scalar-inout: output should be empty") - 8606 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'x' is too large to copy" "F - test-copy-to-from-non-scalar-inout: error message") - 8607 # check that stop(1) was called - 8608 (check-ints-equal *(edx+4) 2 "F - test-copy-to-from-non-scalar-inout: exit status") - 8609 # don't restore from ebp - 8610 81 0/subop/add %esp 8/imm32 - 8611 # . epilogue - 8612 5d/pop-to-ebp - 8613 c3/return - 8614 - 8615 test-copy-byte-with-no-inout: - 8616 # . prologue - 8617 55/push-ebp - 8618 89/<- %ebp 4/r32/esp - 8619 # setup - 8620 (clear-stream _test-input-stream) - 8621 (clear-stream $_test-input-buffered-file->buffer) - 8622 (clear-stream _test-output-stream) - 8623 (clear-stream $_test-output-buffered-file->buffer) - 8624 (clear-stream _test-error-stream) - 8625 (clear-stream $_test-error-buffered-file->buffer) - 8626 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8627 68/push 0/imm32 - 8628 68/push 0/imm32 - 8629 89/<- %edx 4/r32/esp - 8630 (tailor-exit-descriptor %edx 0x10) - 8631 # - 8632 (write _test-input-stream "fn foo {\n") - 8633 (write _test-input-stream " var x/eax: byte <- copy-byte\n") - 8634 (write _test-input-stream "}\n") - 8635 # convert - 8636 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8637 # registers except esp clobbered at this point - 8638 # restore ed - 8639 89/<- %edx 4/r32/esp - 8640 (flush _test-output-buffered-file) - 8641 (flush _test-error-buffered-file) - 8642 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8648 # check output - 8649 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-no-inout: output should be empty") - 8650 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' expects an inout" "F - test-copy-byte-with-no-inout: error message") - 8651 # check that stop(1) was called - 8652 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-no-inout: exit status") - 8653 # don't restore from ebp - 8654 81 0/subop/add %esp 8/imm32 - 8655 # . epilogue - 8656 5d/pop-to-ebp - 8657 c3/return - 8658 - 8659 test-copy-byte-with-multiple-inouts: - 8660 # . prologue - 8661 55/push-ebp - 8662 89/<- %ebp 4/r32/esp - 8663 # setup - 8664 (clear-stream _test-input-stream) - 8665 (clear-stream $_test-input-buffered-file->buffer) - 8666 (clear-stream _test-output-stream) - 8667 (clear-stream $_test-output-buffered-file->buffer) - 8668 (clear-stream _test-error-stream) - 8669 (clear-stream $_test-error-buffered-file->buffer) - 8670 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8671 68/push 0/imm32 - 8672 68/push 0/imm32 - 8673 89/<- %edx 4/r32/esp - 8674 (tailor-exit-descriptor %edx 0x10) - 8675 # - 8676 (write _test-input-stream "fn foo {\n") - 8677 (write _test-input-stream " var x/eax: byte <- copy-byte 0, 0\n") - 8678 (write _test-input-stream "}\n") - 8679 # convert - 8680 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8681 # registers except esp clobbered at this point - 8682 # restore ed - 8683 89/<- %edx 4/r32/esp - 8684 (flush _test-output-buffered-file) - 8685 (flush _test-error-buffered-file) - 8686 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8692 # check output - 8693 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-multiple-inouts: output should be empty") - 8694 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must have just one inout" "F - test-copy-byte-with-multiple-inouts: error message") - 8695 # check that stop(1) was called - 8696 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-multiple-inouts: exit status") - 8697 # don't restore from ebp - 8698 81 0/subop/add %esp 8/imm32 - 8699 # . epilogue - 8700 5d/pop-to-ebp - 8701 c3/return - 8702 - 8703 test-copy-byte-with-no-output: - 8704 # . prologue - 8705 55/push-ebp - 8706 89/<- %ebp 4/r32/esp - 8707 # setup - 8708 (clear-stream _test-input-stream) - 8709 (clear-stream $_test-input-buffered-file->buffer) - 8710 (clear-stream _test-output-stream) - 8711 (clear-stream $_test-output-buffered-file->buffer) - 8712 (clear-stream _test-error-stream) - 8713 (clear-stream $_test-error-buffered-file->buffer) - 8714 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8715 68/push 0/imm32 - 8716 68/push 0/imm32 - 8717 89/<- %edx 4/r32/esp - 8718 (tailor-exit-descriptor %edx 0x10) - 8719 # - 8720 (write _test-input-stream "fn foo {\n") - 8721 (write _test-input-stream " copy-byte 0\n") - 8722 (write _test-input-stream "}\n") - 8723 # convert - 8724 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8725 # registers except esp clobbered at this point - 8726 # restore ed - 8727 89/<- %edx 4/r32/esp - 8728 (flush _test-output-buffered-file) - 8729 (flush _test-error-buffered-file) - 8730 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8736 # check output - 8737 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-no-output: output should be empty") - 8738 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' expects an output" "F - test-copy-byte-with-no-output: error message") - 8739 # check that stop(1) was called - 8740 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-no-output: exit status") - 8741 # don't restore from ebp - 8742 81 0/subop/add %esp 8/imm32 - 8743 # . epilogue - 8744 5d/pop-to-ebp - 8745 c3/return - 8746 - 8747 test-copy-byte-with-multiple-outputs: - 8748 # . prologue - 8749 55/push-ebp - 8750 89/<- %ebp 4/r32/esp - 8751 # setup - 8752 (clear-stream _test-input-stream) - 8753 (clear-stream $_test-input-buffered-file->buffer) - 8754 (clear-stream _test-output-stream) - 8755 (clear-stream $_test-output-buffered-file->buffer) - 8756 (clear-stream _test-error-stream) - 8757 (clear-stream $_test-error-buffered-file->buffer) - 8758 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8759 68/push 0/imm32 - 8760 68/push 0/imm32 - 8761 89/<- %edx 4/r32/esp - 8762 (tailor-exit-descriptor %edx 0x10) - 8763 # - 8764 (write _test-input-stream "fn foo {\n") - 8765 (write _test-input-stream " var x/eax: byte <- copy 0\n") - 8766 (write _test-input-stream " var y/ecx: byte <- copy 0\n") - 8767 (write _test-input-stream " x, y <- copy-byte 0\n") - 8768 (write _test-input-stream "}\n") - 8769 # convert - 8770 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8771 # registers except esp clobbered at this point - 8772 # restore ed - 8773 89/<- %edx 4/r32/esp - 8774 (flush _test-output-buffered-file) - 8775 (flush _test-error-buffered-file) - 8776 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8782 # check output - 8783 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-multiple-outputs: output should be empty") - 8784 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must have just one output" "F - test-copy-byte-with-multiple-outputs: error message") - 8785 # check that stop(1) was called - 8786 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-multiple-outputs: exit status") - 8787 # don't restore from ebp - 8788 81 0/subop/add %esp 8/imm32 - 8789 # . epilogue - 8790 5d/pop-to-ebp - 8791 c3/return - 8792 - 8793 test-copy-byte-deref-address: - 8794 # . prologue - 8795 55/push-ebp - 8796 89/<- %ebp 4/r32/esp - 8797 # setup - 8798 (clear-stream _test-input-stream) - 8799 (clear-stream $_test-input-buffered-file->buffer) - 8800 (clear-stream _test-output-stream) - 8801 (clear-stream $_test-output-buffered-file->buffer) - 8802 # - 8803 (write _test-input-stream "fn foo {\n") - 8804 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") - 8805 (write _test-input-stream " var y/ecx: byte <- copy-byte *x\n") - 8806 (write _test-input-stream "}\n") - 8807 # convert - 8808 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 8809 (flush _test-output-buffered-file) - 8810 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8816 # not bothering checking output - 8817 (check-next-stream-line-equal _test-error-stream "" "F - test-copy-byte-deref-address: error message") - 8818 # . epilogue - 8819 5d/pop-to-ebp - 8820 c3/return - 8821 - 8822 test-copy-byte-with-invalid-output-type: - 8823 # . prologue - 8824 55/push-ebp - 8825 89/<- %ebp 4/r32/esp - 8826 # setup - 8827 (clear-stream _test-input-stream) - 8828 (clear-stream $_test-input-buffered-file->buffer) - 8829 (clear-stream _test-output-stream) - 8830 (clear-stream $_test-output-buffered-file->buffer) - 8831 (clear-stream _test-error-stream) - 8832 (clear-stream $_test-error-buffered-file->buffer) - 8833 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8834 68/push 0/imm32 - 8835 68/push 0/imm32 - 8836 89/<- %edx 4/r32/esp - 8837 (tailor-exit-descriptor %edx 0x10) - 8838 # - 8839 (write _test-input-stream "fn foo {\n") - 8840 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") - 8841 (write _test-input-stream " var y/eax: int <- copy-byte *x\n") - 8842 (write _test-input-stream "}\n") - 8843 # convert - 8844 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8845 # registers except esp clobbered at this point - 8846 # restore ed - 8847 89/<- %edx 4/r32/esp - 8848 (flush _test-output-buffered-file) - 8849 (flush _test-error-buffered-file) - 8850 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8856 # check output - 8857 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-invalid-output-type: output should be empty") - 8858 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must write to output of type byte" "F - test-copy-byte-with-invalid-output-type: error message") - 8859 # check that stop(1) was called - 8860 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-invalid-output-type: exit status") - 8861 # don't restore from ebp - 8862 81 0/subop/add %esp 8/imm32 - 8863 # . epilogue - 8864 5d/pop-to-ebp - 8865 c3/return - 8866 - 8867 test-copy-byte-from-non-scalar-inout: - 8868 # . prologue - 8869 55/push-ebp - 8870 89/<- %ebp 4/r32/esp - 8871 # setup - 8872 (clear-stream _test-input-stream) - 8873 (clear-stream $_test-input-buffered-file->buffer) - 8874 (clear-stream _test-output-stream) - 8875 (clear-stream $_test-output-buffered-file->buffer) - 8876 (clear-stream _test-error-stream) - 8877 (clear-stream $_test-error-buffered-file->buffer) - 8878 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8879 68/push 0/imm32 - 8880 68/push 0/imm32 - 8881 89/<- %edx 4/r32/esp - 8882 (tailor-exit-descriptor %edx 0x10) - 8883 # - 8884 (write _test-input-stream "fn foo {\n") - 8885 (write _test-input-stream " var x: (handle int)\n") - 8886 (write _test-input-stream " var y/eax: byte <- copy-byte x\n") - 8887 (write _test-input-stream "}\n") - 8888 # convert - 8889 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8890 # registers except esp clobbered at this point - 8891 # restore ed - 8892 89/<- %edx 4/r32/esp - 8893 (flush _test-output-buffered-file) - 8894 (flush _test-error-buffered-file) - 8895 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8901 # check output - 8902 (check-stream-equal _test-output-stream "" "F - test-copy-byte-from-non-scalar-inout: output should be empty") - 8903 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte: 'x' is too large to fit in a register" "F - test-copy-byte-from-non-scalar-inout: error message") - 8904 # check that stop(1) was called - 8905 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-from-non-scalar-inout: exit status") - 8906 # don't restore from ebp - 8907 81 0/subop/add %esp 8/imm32 - 8908 # . epilogue - 8909 5d/pop-to-ebp - 8910 c3/return - 8911 - 8912 test-copy-byte-to-with-no-inout: - 8913 # . prologue - 8914 55/push-ebp - 8915 89/<- %ebp 4/r32/esp - 8916 # setup - 8917 (clear-stream _test-input-stream) - 8918 (clear-stream $_test-input-buffered-file->buffer) - 8919 (clear-stream _test-output-stream) - 8920 (clear-stream $_test-output-buffered-file->buffer) - 8921 (clear-stream _test-error-stream) - 8922 (clear-stream $_test-error-buffered-file->buffer) - 8923 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8924 68/push 0/imm32 - 8925 68/push 0/imm32 - 8926 89/<- %edx 4/r32/esp - 8927 (tailor-exit-descriptor %edx 0x10) - 8928 # - 8929 (write _test-input-stream "fn foo {\n") - 8930 (write _test-input-stream " copy-byte-to\n") - 8931 (write _test-input-stream "}\n") - 8932 # convert - 8933 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8934 # registers except esp clobbered at this point - 8935 # restore ed - 8936 89/<- %edx 4/r32/esp - 8937 (flush _test-output-buffered-file) - 8938 (flush _test-error-buffered-file) - 8939 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8945 # check output - 8946 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-no-inout: output should be empty") - 8947 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-no-inout: error message") - 8948 # check that stop(1) was called - 8949 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-no-inout: exit status") - 8950 # don't restore from ebp - 8951 81 0/subop/add %esp 8/imm32 - 8952 # . epilogue - 8953 5d/pop-to-ebp - 8954 c3/return - 8955 - 8956 test-copy-byte-to-with-no-source: - 8957 # . prologue - 8958 55/push-ebp - 8959 89/<- %ebp 4/r32/esp - 8960 # setup - 8961 (clear-stream _test-input-stream) - 8962 (clear-stream $_test-input-buffered-file->buffer) - 8963 (clear-stream _test-output-stream) - 8964 (clear-stream $_test-output-buffered-file->buffer) - 8965 (clear-stream _test-error-stream) - 8966 (clear-stream $_test-error-buffered-file->buffer) - 8967 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 8968 68/push 0/imm32 - 8969 68/push 0/imm32 - 8970 89/<- %edx 4/r32/esp - 8971 (tailor-exit-descriptor %edx 0x10) - 8972 # - 8973 (write _test-input-stream "fn foo {\n") - 8974 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") - 8975 (write _test-input-stream " copy-byte-to *x\n") - 8976 (write _test-input-stream "}\n") - 8977 # convert - 8978 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 8979 # registers except esp clobbered at this point - 8980 # restore ed - 8981 89/<- %edx 4/r32/esp - 8982 (flush _test-output-buffered-file) - 8983 (flush _test-error-buffered-file) - 8984 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 8990 # check output - 8991 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-no-source: output should be empty") - 8992 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-no-source: error message") - 8993 # check that stop(1) was called - 8994 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-no-source: exit status") - 8995 # don't restore from ebp - 8996 81 0/subop/add %esp 8/imm32 - 8997 # . epilogue - 8998 5d/pop-to-ebp - 8999 c3/return - 9000 - 9001 test-copy-byte-to-with-too-many-inouts: - 9002 # . prologue - 9003 55/push-ebp - 9004 89/<- %ebp 4/r32/esp - 9005 # setup - 9006 (clear-stream _test-input-stream) - 9007 (clear-stream $_test-input-buffered-file->buffer) - 9008 (clear-stream _test-output-stream) - 9009 (clear-stream $_test-output-buffered-file->buffer) - 9010 (clear-stream _test-error-stream) - 9011 (clear-stream $_test-error-buffered-file->buffer) - 9012 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9013 68/push 0/imm32 - 9014 68/push 0/imm32 - 9015 89/<- %edx 4/r32/esp - 9016 (tailor-exit-descriptor %edx 0x10) - 9017 # - 9018 (write _test-input-stream "fn foo {\n") - 9019 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") - 9020 (write _test-input-stream " copy-byte-to *x, 0, 0\n") - 9021 (write _test-input-stream "}\n") - 9022 # convert - 9023 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9024 # registers except esp clobbered at this point - 9025 # restore ed - 9026 89/<- %edx 4/r32/esp - 9027 (flush _test-output-buffered-file) - 9028 (flush _test-error-buffered-file) - 9029 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9035 # check output - 9036 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-too-many-inouts: output should be empty") - 9037 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-too-many-inouts: error message") - 9038 # check that stop(1) was called - 9039 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-too-many-inouts: exit status") - 9040 # don't restore from ebp - 9041 81 0/subop/add %esp 8/imm32 - 9042 # . epilogue - 9043 5d/pop-to-ebp - 9044 c3/return - 9045 - 9046 test-copy-byte-to-with-output: - 9047 # . prologue - 9048 55/push-ebp - 9049 89/<- %ebp 4/r32/esp - 9050 # setup - 9051 (clear-stream _test-input-stream) - 9052 (clear-stream $_test-input-buffered-file->buffer) - 9053 (clear-stream _test-output-stream) - 9054 (clear-stream $_test-output-buffered-file->buffer) - 9055 (clear-stream _test-error-stream) - 9056 (clear-stream $_test-error-buffered-file->buffer) - 9057 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9058 68/push 0/imm32 - 9059 68/push 0/imm32 - 9060 89/<- %edx 4/r32/esp - 9061 (tailor-exit-descriptor %edx 0x10) - 9062 # - 9063 (write _test-input-stream "fn foo {\n") - 9064 (write _test-input-stream " var x/eax: byte <- copy 0\n") - 9065 (write _test-input-stream " var y/ecx: (addr byte) <- copy 0\n") - 9066 (write _test-input-stream " x <- copy-byte-to *y, 0\n") - 9067 (write _test-input-stream "}\n") - 9068 # convert - 9069 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9070 # registers except esp clobbered at this point - 9071 # restore ed - 9072 89/<- %edx 4/r32/esp - 9073 (flush _test-output-buffered-file) - 9074 (flush _test-error-buffered-file) - 9075 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9081 # check output - 9082 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-output: output should be empty") - 9083 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must not have any outputs" "F - test-copy-byte-to-with-output: error message") - 9084 # check that stop(1) was called - 9085 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-output: exit status") - 9086 # don't restore from ebp - 9087 81 0/subop/add %esp 8/imm32 - 9088 # . epilogue - 9089 5d/pop-to-ebp - 9090 c3/return - 9091 - 9092 test-copy-byte-to-with-invalid-output-type: - 9093 # . prologue - 9094 55/push-ebp - 9095 89/<- %ebp 4/r32/esp - 9096 # setup - 9097 (clear-stream _test-input-stream) - 9098 (clear-stream $_test-input-buffered-file->buffer) - 9099 (clear-stream _test-output-stream) - 9100 (clear-stream $_test-output-buffered-file->buffer) - 9101 (clear-stream _test-error-stream) - 9102 (clear-stream $_test-error-buffered-file->buffer) - 9103 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9104 68/push 0/imm32 - 9105 68/push 0/imm32 - 9106 89/<- %edx 4/r32/esp - 9107 (tailor-exit-descriptor %edx 0x10) - 9108 # - 9109 (write _test-input-stream "fn foo {\n") - 9110 (write _test-input-stream " var x/eax: byte <- copy 0\n") - 9111 (write _test-input-stream " var y: int\n") - 9112 (write _test-input-stream " copy-byte-to y, x\n") - 9113 (write _test-input-stream "}\n") - 9114 # convert - 9115 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9116 # registers except esp clobbered at this point - 9117 # restore ed - 9118 89/<- %edx 4/r32/esp - 9119 (flush _test-output-buffered-file) - 9120 (flush _test-error-buffered-file) - 9121 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9127 # check output - 9128 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-invalid-output-type: output should be empty") - 9129 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: 'y' must be a byte" "F - test-copy-byte-to-with-invalid-output-type: error message") - 9130 # check that stop(1) was called - 9131 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-invalid-output-type: exit status") - 9132 # don't restore from ebp - 9133 81 0/subop/add %esp 8/imm32 - 9134 # . epilogue - 9135 5d/pop-to-ebp - 9136 c3/return - 9137 - 9138 test-copy-byte-to-with-literal-inout: - 9139 # . prologue - 9140 55/push-ebp - 9141 89/<- %ebp 4/r32/esp - 9142 # setup - 9143 (clear-stream _test-input-stream) - 9144 (clear-stream $_test-input-buffered-file->buffer) - 9145 (clear-stream _test-output-stream) - 9146 (clear-stream $_test-output-buffered-file->buffer) - 9147 (clear-stream _test-error-stream) - 9148 (clear-stream $_test-error-buffered-file->buffer) - 9149 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9150 68/push 0/imm32 - 9151 68/push 0/imm32 - 9152 89/<- %edx 4/r32/esp - 9153 (tailor-exit-descriptor %edx 0x10) - 9154 # - 9155 (write _test-input-stream "fn foo {\n") - 9156 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") - 9157 (write _test-input-stream " copy-byte-to *x, 0\n") - 9158 (write _test-input-stream "}\n") - 9159 # convert - 9160 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9161 # registers except esp clobbered at this point - 9162 # restore ed - 9163 89/<- %edx 4/r32/esp - 9164 (flush _test-output-buffered-file) - 9165 (flush _test-error-buffered-file) - 9166 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9172 # check output - 9173 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-literal-inout: output should be empty") - 9174 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: source (second inout) must be in a register" "F - test-copy-byte-to-with-literal-inout: error message") - 9175 # check that stop(1) was called - 9176 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-literal-inout: exit status") - 9177 # don't restore from ebp - 9178 81 0/subop/add %esp 8/imm32 - 9179 # . epilogue - 9180 5d/pop-to-ebp - 9181 c3/return - 9182 - 9183 test-copy-byte-to-deref-address: - 9184 # . prologue - 9185 55/push-ebp - 9186 89/<- %ebp 4/r32/esp - 9187 # setup - 9188 (clear-stream _test-input-stream) - 9189 (clear-stream $_test-input-buffered-file->buffer) - 9190 (clear-stream _test-output-stream) - 9191 (clear-stream $_test-output-buffered-file->buffer) - 9192 # - 9193 (write _test-input-stream "fn foo {\n") - 9194 (write _test-input-stream " var x/eax: byte <- copy 0\n") - 9195 (write _test-input-stream " var y/ecx: (addr byte) <- copy 0\n") - 9196 (write _test-input-stream " copy-byte-to *y, x\n") - 9197 (write _test-input-stream "}\n") - 9198 # convert - 9199 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 9200 (flush _test-output-buffered-file) - 9201 # no errors + 8578 # + 8579 (write _test-input-stream "fn foo {\n") + 8580 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") + 8581 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n") + 8582 (write _test-input-stream " copy-to *y, x\n") + 8583 (write _test-input-stream "}\n") + 8584 # convert + 8585 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 8586 (flush _test-output-buffered-file) + 8587 # no errors + 8588 # . epilogue + 8589 5d/pop-to-ebp + 8590 c3/return + 8591 + 8592 test-copy-to-from-non-scalar-inout: + 8593 # . prologue + 8594 55/push-ebp + 8595 89/<- %ebp 4/r32/esp + 8596 # setup + 8597 (clear-stream _test-input-stream) + 8598 (clear-stream $_test-input-buffered-file->buffer) + 8599 (clear-stream _test-output-stream) + 8600 (clear-stream $_test-output-buffered-file->buffer) + 8601 (clear-stream _test-error-stream) + 8602 (clear-stream $_test-error-buffered-file->buffer) + 8603 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8604 68/push 0/imm32 + 8605 68/push 0/imm32 + 8606 89/<- %edx 4/r32/esp + 8607 (tailor-exit-descriptor %edx 0x10) + 8608 # + 8609 (write _test-input-stream "fn foo {\n") + 8610 (write _test-input-stream " var x: (handle int)\n") + 8611 (write _test-input-stream " var y: int\n") + 8612 (write _test-input-stream " copy-to y, x\n") + 8613 (write _test-input-stream "}\n") + 8614 # convert + 8615 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8616 # registers except esp clobbered at this point + 8617 # restore ed + 8618 89/<- %edx 4/r32/esp + 8619 (flush _test-output-buffered-file) + 8620 (flush _test-error-buffered-file) + 8621 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8627 # check output + 8628 (check-stream-equal _test-output-stream "" "F - test-copy-to-from-non-scalar-inout: output should be empty") + 8629 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'x' is too large to copy" "F - test-copy-to-from-non-scalar-inout: error message") + 8630 # check that stop(1) was called + 8631 (check-ints-equal *(edx+4) 2 "F - test-copy-to-from-non-scalar-inout: exit status") + 8632 # don't restore from ebp + 8633 81 0/subop/add %esp 8/imm32 + 8634 # . epilogue + 8635 5d/pop-to-ebp + 8636 c3/return + 8637 + 8638 test-copy-byte-with-no-inout: + 8639 # . prologue + 8640 55/push-ebp + 8641 89/<- %ebp 4/r32/esp + 8642 # setup + 8643 (clear-stream _test-input-stream) + 8644 (clear-stream $_test-input-buffered-file->buffer) + 8645 (clear-stream _test-output-stream) + 8646 (clear-stream $_test-output-buffered-file->buffer) + 8647 (clear-stream _test-error-stream) + 8648 (clear-stream $_test-error-buffered-file->buffer) + 8649 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8650 68/push 0/imm32 + 8651 68/push 0/imm32 + 8652 89/<- %edx 4/r32/esp + 8653 (tailor-exit-descriptor %edx 0x10) + 8654 # + 8655 (write _test-input-stream "fn foo {\n") + 8656 (write _test-input-stream " var x/eax: byte <- copy-byte\n") + 8657 (write _test-input-stream "}\n") + 8658 # convert + 8659 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8660 # registers except esp clobbered at this point + 8661 # restore ed + 8662 89/<- %edx 4/r32/esp + 8663 (flush _test-output-buffered-file) + 8664 (flush _test-error-buffered-file) + 8665 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8671 # check output + 8672 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-no-inout: output should be empty") + 8673 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' expects an inout" "F - test-copy-byte-with-no-inout: error message") + 8674 # check that stop(1) was called + 8675 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-no-inout: exit status") + 8676 # don't restore from ebp + 8677 81 0/subop/add %esp 8/imm32 + 8678 # . epilogue + 8679 5d/pop-to-ebp + 8680 c3/return + 8681 + 8682 test-copy-byte-with-multiple-inouts: + 8683 # . prologue + 8684 55/push-ebp + 8685 89/<- %ebp 4/r32/esp + 8686 # setup + 8687 (clear-stream _test-input-stream) + 8688 (clear-stream $_test-input-buffered-file->buffer) + 8689 (clear-stream _test-output-stream) + 8690 (clear-stream $_test-output-buffered-file->buffer) + 8691 (clear-stream _test-error-stream) + 8692 (clear-stream $_test-error-buffered-file->buffer) + 8693 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8694 68/push 0/imm32 + 8695 68/push 0/imm32 + 8696 89/<- %edx 4/r32/esp + 8697 (tailor-exit-descriptor %edx 0x10) + 8698 # + 8699 (write _test-input-stream "fn foo {\n") + 8700 (write _test-input-stream " var x/eax: byte <- copy-byte 0, 0\n") + 8701 (write _test-input-stream "}\n") + 8702 # convert + 8703 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8704 # registers except esp clobbered at this point + 8705 # restore ed + 8706 89/<- %edx 4/r32/esp + 8707 (flush _test-output-buffered-file) + 8708 (flush _test-error-buffered-file) + 8709 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8715 # check output + 8716 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-multiple-inouts: output should be empty") + 8717 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must have just one inout" "F - test-copy-byte-with-multiple-inouts: error message") + 8718 # check that stop(1) was called + 8719 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-multiple-inouts: exit status") + 8720 # don't restore from ebp + 8721 81 0/subop/add %esp 8/imm32 + 8722 # . epilogue + 8723 5d/pop-to-ebp + 8724 c3/return + 8725 + 8726 test-copy-byte-with-no-output: + 8727 # . prologue + 8728 55/push-ebp + 8729 89/<- %ebp 4/r32/esp + 8730 # setup + 8731 (clear-stream _test-input-stream) + 8732 (clear-stream $_test-input-buffered-file->buffer) + 8733 (clear-stream _test-output-stream) + 8734 (clear-stream $_test-output-buffered-file->buffer) + 8735 (clear-stream _test-error-stream) + 8736 (clear-stream $_test-error-buffered-file->buffer) + 8737 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8738 68/push 0/imm32 + 8739 68/push 0/imm32 + 8740 89/<- %edx 4/r32/esp + 8741 (tailor-exit-descriptor %edx 0x10) + 8742 # + 8743 (write _test-input-stream "fn foo {\n") + 8744 (write _test-input-stream " copy-byte 0\n") + 8745 (write _test-input-stream "}\n") + 8746 # convert + 8747 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8748 # registers except esp clobbered at this point + 8749 # restore ed + 8750 89/<- %edx 4/r32/esp + 8751 (flush _test-output-buffered-file) + 8752 (flush _test-error-buffered-file) + 8753 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8759 # check output + 8760 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-no-output: output should be empty") + 8761 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' expects an output" "F - test-copy-byte-with-no-output: error message") + 8762 # check that stop(1) was called + 8763 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-no-output: exit status") + 8764 # don't restore from ebp + 8765 81 0/subop/add %esp 8/imm32 + 8766 # . epilogue + 8767 5d/pop-to-ebp + 8768 c3/return + 8769 + 8770 test-copy-byte-with-multiple-outputs: + 8771 # . prologue + 8772 55/push-ebp + 8773 89/<- %ebp 4/r32/esp + 8774 # setup + 8775 (clear-stream _test-input-stream) + 8776 (clear-stream $_test-input-buffered-file->buffer) + 8777 (clear-stream _test-output-stream) + 8778 (clear-stream $_test-output-buffered-file->buffer) + 8779 (clear-stream _test-error-stream) + 8780 (clear-stream $_test-error-buffered-file->buffer) + 8781 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8782 68/push 0/imm32 + 8783 68/push 0/imm32 + 8784 89/<- %edx 4/r32/esp + 8785 (tailor-exit-descriptor %edx 0x10) + 8786 # + 8787 (write _test-input-stream "fn foo {\n") + 8788 (write _test-input-stream " var x/eax: byte <- copy 0\n") + 8789 (write _test-input-stream " var y/ecx: byte <- copy 0\n") + 8790 (write _test-input-stream " x, y <- copy-byte 0\n") + 8791 (write _test-input-stream "}\n") + 8792 # convert + 8793 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8794 # registers except esp clobbered at this point + 8795 # restore ed + 8796 89/<- %edx 4/r32/esp + 8797 (flush _test-output-buffered-file) + 8798 (flush _test-error-buffered-file) + 8799 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8805 # check output + 8806 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-multiple-outputs: output should be empty") + 8807 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must have just one output" "F - test-copy-byte-with-multiple-outputs: error message") + 8808 # check that stop(1) was called + 8809 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-multiple-outputs: exit status") + 8810 # don't restore from ebp + 8811 81 0/subop/add %esp 8/imm32 + 8812 # . epilogue + 8813 5d/pop-to-ebp + 8814 c3/return + 8815 + 8816 test-copy-byte-deref-address: + 8817 # . prologue + 8818 55/push-ebp + 8819 89/<- %ebp 4/r32/esp + 8820 # setup + 8821 (clear-stream _test-input-stream) + 8822 (clear-stream $_test-input-buffered-file->buffer) + 8823 (clear-stream _test-output-stream) + 8824 (clear-stream $_test-output-buffered-file->buffer) + 8825 # + 8826 (write _test-input-stream "fn foo {\n") + 8827 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") + 8828 (write _test-input-stream " var y/ecx: byte <- copy-byte *x\n") + 8829 (write _test-input-stream "}\n") + 8830 # convert + 8831 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 8832 (flush _test-output-buffered-file) + 8833 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8839 # not bothering checking output + 8840 (check-next-stream-line-equal _test-error-stream "" "F - test-copy-byte-deref-address: error message") + 8841 # . epilogue + 8842 5d/pop-to-ebp + 8843 c3/return + 8844 + 8845 test-copy-byte-with-invalid-output-type: + 8846 # . prologue + 8847 55/push-ebp + 8848 89/<- %ebp 4/r32/esp + 8849 # setup + 8850 (clear-stream _test-input-stream) + 8851 (clear-stream $_test-input-buffered-file->buffer) + 8852 (clear-stream _test-output-stream) + 8853 (clear-stream $_test-output-buffered-file->buffer) + 8854 (clear-stream _test-error-stream) + 8855 (clear-stream $_test-error-buffered-file->buffer) + 8856 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8857 68/push 0/imm32 + 8858 68/push 0/imm32 + 8859 89/<- %edx 4/r32/esp + 8860 (tailor-exit-descriptor %edx 0x10) + 8861 # + 8862 (write _test-input-stream "fn foo {\n") + 8863 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") + 8864 (write _test-input-stream " var y/eax: int <- copy-byte *x\n") + 8865 (write _test-input-stream "}\n") + 8866 # convert + 8867 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8868 # registers except esp clobbered at this point + 8869 # restore ed + 8870 89/<- %edx 4/r32/esp + 8871 (flush _test-output-buffered-file) + 8872 (flush _test-error-buffered-file) + 8873 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8879 # check output + 8880 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-invalid-output-type: output should be empty") + 8881 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must write to output of type byte" "F - test-copy-byte-with-invalid-output-type: error message") + 8882 # check that stop(1) was called + 8883 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-invalid-output-type: exit status") + 8884 # don't restore from ebp + 8885 81 0/subop/add %esp 8/imm32 + 8886 # . epilogue + 8887 5d/pop-to-ebp + 8888 c3/return + 8889 + 8890 test-copy-byte-from-non-scalar-inout: + 8891 # . prologue + 8892 55/push-ebp + 8893 89/<- %ebp 4/r32/esp + 8894 # setup + 8895 (clear-stream _test-input-stream) + 8896 (clear-stream $_test-input-buffered-file->buffer) + 8897 (clear-stream _test-output-stream) + 8898 (clear-stream $_test-output-buffered-file->buffer) + 8899 (clear-stream _test-error-stream) + 8900 (clear-stream $_test-error-buffered-file->buffer) + 8901 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8902 68/push 0/imm32 + 8903 68/push 0/imm32 + 8904 89/<- %edx 4/r32/esp + 8905 (tailor-exit-descriptor %edx 0x10) + 8906 # + 8907 (write _test-input-stream "fn foo {\n") + 8908 (write _test-input-stream " var x: (handle int)\n") + 8909 (write _test-input-stream " var y/eax: byte <- copy-byte x\n") + 8910 (write _test-input-stream "}\n") + 8911 # convert + 8912 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8913 # registers except esp clobbered at this point + 8914 # restore ed + 8915 89/<- %edx 4/r32/esp + 8916 (flush _test-output-buffered-file) + 8917 (flush _test-error-buffered-file) + 8918 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8924 # check output + 8925 (check-stream-equal _test-output-stream "" "F - test-copy-byte-from-non-scalar-inout: output should be empty") + 8926 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte: 'x' is too large to fit in a register" "F - test-copy-byte-from-non-scalar-inout: error message") + 8927 # check that stop(1) was called + 8928 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-from-non-scalar-inout: exit status") + 8929 # don't restore from ebp + 8930 81 0/subop/add %esp 8/imm32 + 8931 # . epilogue + 8932 5d/pop-to-ebp + 8933 c3/return + 8934 + 8935 test-copy-byte-to-with-no-inout: + 8936 # . prologue + 8937 55/push-ebp + 8938 89/<- %ebp 4/r32/esp + 8939 # setup + 8940 (clear-stream _test-input-stream) + 8941 (clear-stream $_test-input-buffered-file->buffer) + 8942 (clear-stream _test-output-stream) + 8943 (clear-stream $_test-output-buffered-file->buffer) + 8944 (clear-stream _test-error-stream) + 8945 (clear-stream $_test-error-buffered-file->buffer) + 8946 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8947 68/push 0/imm32 + 8948 68/push 0/imm32 + 8949 89/<- %edx 4/r32/esp + 8950 (tailor-exit-descriptor %edx 0x10) + 8951 # + 8952 (write _test-input-stream "fn foo {\n") + 8953 (write _test-input-stream " copy-byte-to\n") + 8954 (write _test-input-stream "}\n") + 8955 # convert + 8956 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 8957 # registers except esp clobbered at this point + 8958 # restore ed + 8959 89/<- %edx 4/r32/esp + 8960 (flush _test-output-buffered-file) + 8961 (flush _test-error-buffered-file) + 8962 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 8968 # check output + 8969 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-no-inout: output should be empty") + 8970 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-no-inout: error message") + 8971 # check that stop(1) was called + 8972 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-no-inout: exit status") + 8973 # don't restore from ebp + 8974 81 0/subop/add %esp 8/imm32 + 8975 # . epilogue + 8976 5d/pop-to-ebp + 8977 c3/return + 8978 + 8979 test-copy-byte-to-with-no-source: + 8980 # . prologue + 8981 55/push-ebp + 8982 89/<- %ebp 4/r32/esp + 8983 # setup + 8984 (clear-stream _test-input-stream) + 8985 (clear-stream $_test-input-buffered-file->buffer) + 8986 (clear-stream _test-output-stream) + 8987 (clear-stream $_test-output-buffered-file->buffer) + 8988 (clear-stream _test-error-stream) + 8989 (clear-stream $_test-error-buffered-file->buffer) + 8990 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 8991 68/push 0/imm32 + 8992 68/push 0/imm32 + 8993 89/<- %edx 4/r32/esp + 8994 (tailor-exit-descriptor %edx 0x10) + 8995 # + 8996 (write _test-input-stream "fn foo {\n") + 8997 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") + 8998 (write _test-input-stream " copy-byte-to *x\n") + 8999 (write _test-input-stream "}\n") + 9000 # convert + 9001 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9002 # registers except esp clobbered at this point + 9003 # restore ed + 9004 89/<- %edx 4/r32/esp + 9005 (flush _test-output-buffered-file) + 9006 (flush _test-error-buffered-file) + 9007 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9013 # check output + 9014 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-no-source: output should be empty") + 9015 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-no-source: error message") + 9016 # check that stop(1) was called + 9017 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-no-source: exit status") + 9018 # don't restore from ebp + 9019 81 0/subop/add %esp 8/imm32 + 9020 # . epilogue + 9021 5d/pop-to-ebp + 9022 c3/return + 9023 + 9024 test-copy-byte-to-with-too-many-inouts: + 9025 # . prologue + 9026 55/push-ebp + 9027 89/<- %ebp 4/r32/esp + 9028 # setup + 9029 (clear-stream _test-input-stream) + 9030 (clear-stream $_test-input-buffered-file->buffer) + 9031 (clear-stream _test-output-stream) + 9032 (clear-stream $_test-output-buffered-file->buffer) + 9033 (clear-stream _test-error-stream) + 9034 (clear-stream $_test-error-buffered-file->buffer) + 9035 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9036 68/push 0/imm32 + 9037 68/push 0/imm32 + 9038 89/<- %edx 4/r32/esp + 9039 (tailor-exit-descriptor %edx 0x10) + 9040 # + 9041 (write _test-input-stream "fn foo {\n") + 9042 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") + 9043 (write _test-input-stream " copy-byte-to *x, 0, 0\n") + 9044 (write _test-input-stream "}\n") + 9045 # convert + 9046 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9047 # registers except esp clobbered at this point + 9048 # restore ed + 9049 89/<- %edx 4/r32/esp + 9050 (flush _test-output-buffered-file) + 9051 (flush _test-error-buffered-file) + 9052 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9058 # check output + 9059 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-too-many-inouts: output should be empty") + 9060 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-too-many-inouts: error message") + 9061 # check that stop(1) was called + 9062 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-too-many-inouts: exit status") + 9063 # don't restore from ebp + 9064 81 0/subop/add %esp 8/imm32 + 9065 # . epilogue + 9066 5d/pop-to-ebp + 9067 c3/return + 9068 + 9069 test-copy-byte-to-with-output: + 9070 # . prologue + 9071 55/push-ebp + 9072 89/<- %ebp 4/r32/esp + 9073 # setup + 9074 (clear-stream _test-input-stream) + 9075 (clear-stream $_test-input-buffered-file->buffer) + 9076 (clear-stream _test-output-stream) + 9077 (clear-stream $_test-output-buffered-file->buffer) + 9078 (clear-stream _test-error-stream) + 9079 (clear-stream $_test-error-buffered-file->buffer) + 9080 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9081 68/push 0/imm32 + 9082 68/push 0/imm32 + 9083 89/<- %edx 4/r32/esp + 9084 (tailor-exit-descriptor %edx 0x10) + 9085 # + 9086 (write _test-input-stream "fn foo {\n") + 9087 (write _test-input-stream " var x/eax: byte <- copy 0\n") + 9088 (write _test-input-stream " var y/ecx: (addr byte) <- copy 0\n") + 9089 (write _test-input-stream " x <- copy-byte-to *y, 0\n") + 9090 (write _test-input-stream "}\n") + 9091 # convert + 9092 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9093 # registers except esp clobbered at this point + 9094 # restore ed + 9095 89/<- %edx 4/r32/esp + 9096 (flush _test-output-buffered-file) + 9097 (flush _test-error-buffered-file) + 9098 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9104 # check output + 9105 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-output: output should be empty") + 9106 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must not have any outputs" "F - test-copy-byte-to-with-output: error message") + 9107 # check that stop(1) was called + 9108 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-output: exit status") + 9109 # don't restore from ebp + 9110 81 0/subop/add %esp 8/imm32 + 9111 # . epilogue + 9112 5d/pop-to-ebp + 9113 c3/return + 9114 + 9115 test-copy-byte-to-with-invalid-output-type: + 9116 # . prologue + 9117 55/push-ebp + 9118 89/<- %ebp 4/r32/esp + 9119 # setup + 9120 (clear-stream _test-input-stream) + 9121 (clear-stream $_test-input-buffered-file->buffer) + 9122 (clear-stream _test-output-stream) + 9123 (clear-stream $_test-output-buffered-file->buffer) + 9124 (clear-stream _test-error-stream) + 9125 (clear-stream $_test-error-buffered-file->buffer) + 9126 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9127 68/push 0/imm32 + 9128 68/push 0/imm32 + 9129 89/<- %edx 4/r32/esp + 9130 (tailor-exit-descriptor %edx 0x10) + 9131 # + 9132 (write _test-input-stream "fn foo {\n") + 9133 (write _test-input-stream " var x/eax: byte <- copy 0\n") + 9134 (write _test-input-stream " var y: int\n") + 9135 (write _test-input-stream " copy-byte-to y, x\n") + 9136 (write _test-input-stream "}\n") + 9137 # convert + 9138 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9139 # registers except esp clobbered at this point + 9140 # restore ed + 9141 89/<- %edx 4/r32/esp + 9142 (flush _test-output-buffered-file) + 9143 (flush _test-error-buffered-file) + 9144 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9150 # check output + 9151 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-invalid-output-type: output should be empty") + 9152 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: 'y' must be a byte" "F - test-copy-byte-to-with-invalid-output-type: error message") + 9153 # check that stop(1) was called + 9154 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-invalid-output-type: exit status") + 9155 # don't restore from ebp + 9156 81 0/subop/add %esp 8/imm32 + 9157 # . epilogue + 9158 5d/pop-to-ebp + 9159 c3/return + 9160 + 9161 test-copy-byte-to-with-literal-inout: + 9162 # . prologue + 9163 55/push-ebp + 9164 89/<- %ebp 4/r32/esp + 9165 # setup + 9166 (clear-stream _test-input-stream) + 9167 (clear-stream $_test-input-buffered-file->buffer) + 9168 (clear-stream _test-output-stream) + 9169 (clear-stream $_test-output-buffered-file->buffer) + 9170 (clear-stream _test-error-stream) + 9171 (clear-stream $_test-error-buffered-file->buffer) + 9172 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9173 68/push 0/imm32 + 9174 68/push 0/imm32 + 9175 89/<- %edx 4/r32/esp + 9176 (tailor-exit-descriptor %edx 0x10) + 9177 # + 9178 (write _test-input-stream "fn foo {\n") + 9179 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n") + 9180 (write _test-input-stream " copy-byte-to *x, 0\n") + 9181 (write _test-input-stream "}\n") + 9182 # convert + 9183 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9184 # registers except esp clobbered at this point + 9185 # restore ed + 9186 89/<- %edx 4/r32/esp + 9187 (flush _test-output-buffered-file) + 9188 (flush _test-error-buffered-file) + 9189 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9195 # check output + 9196 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-literal-inout: output should be empty") + 9197 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: source (second inout) must be in a register" "F - test-copy-byte-to-with-literal-inout: error message") + 9198 # check that stop(1) was called + 9199 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-literal-inout: exit status") + 9200 # don't restore from ebp + 9201 81 0/subop/add %esp 8/imm32 9202 # . epilogue 9203 5d/pop-to-ebp 9204 c3/return 9205 - 9206 test-copy-byte-to-from-non-scalar-inout: + 9206 test-copy-byte-to-deref-address: 9207 # . prologue 9208 55/push-ebp 9209 89/<- %ebp 4/r32/esp @@ -8394,264 +8394,264 @@ if ('onhashchange' in window) { 9212 (clear-stream $_test-input-buffered-file->buffer) 9213 (clear-stream _test-output-stream) 9214 (clear-stream $_test-output-buffered-file->buffer) - 9215 (clear-stream _test-error-stream) - 9216 (clear-stream $_test-error-buffered-file->buffer) - 9217 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9218 68/push 0/imm32 - 9219 68/push 0/imm32 - 9220 89/<- %edx 4/r32/esp - 9221 (tailor-exit-descriptor %edx 0x10) - 9222 # - 9223 (write _test-input-stream "fn foo {\n") - 9224 (write _test-input-stream " var x: (handle int)\n") - 9225 (write _test-input-stream " var y/eax: (addr byte) <- copy 0\n") - 9226 (write _test-input-stream " copy-byte-to *y, x\n") - 9227 (write _test-input-stream "}\n") - 9228 # convert - 9229 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9230 # registers except esp clobbered at this point - 9231 # restore ed - 9232 89/<- %edx 4/r32/esp - 9233 (flush _test-output-buffered-file) - 9234 (flush _test-error-buffered-file) - 9235 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9241 # check output - 9242 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-from-non-scalar-inout: output should be empty") - 9243 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: 'x' is too large to copy" "F - test-copy-byte-to-from-non-scalar-inout: error message") - 9244 # check that stop(1) was called - 9245 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-from-non-scalar-inout: exit status") - 9246 # don't restore from ebp - 9247 81 0/subop/add %esp 8/imm32 - 9248 # . epilogue - 9249 5d/pop-to-ebp - 9250 c3/return - 9251 - 9252 test-compare-with-no-inout: - 9253 # . prologue - 9254 55/push-ebp - 9255 89/<- %ebp 4/r32/esp - 9256 # setup - 9257 (clear-stream _test-input-stream) - 9258 (clear-stream $_test-input-buffered-file->buffer) - 9259 (clear-stream _test-output-stream) - 9260 (clear-stream $_test-output-buffered-file->buffer) - 9261 (clear-stream _test-error-stream) - 9262 (clear-stream $_test-error-buffered-file->buffer) - 9263 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9264 68/push 0/imm32 - 9265 68/push 0/imm32 - 9266 89/<- %edx 4/r32/esp - 9267 (tailor-exit-descriptor %edx 0x10) - 9268 # - 9269 (write _test-input-stream "fn foo {\n") - 9270 (write _test-input-stream " var x: boolean\n") - 9271 (write _test-input-stream " compare\n") - 9272 (write _test-input-stream "}\n") - 9273 # convert - 9274 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9275 # registers except esp clobbered at this point - 9276 # restore ed - 9277 89/<- %edx 4/r32/esp - 9278 (flush _test-output-buffered-file) - 9279 (flush _test-error-buffered-file) - 9280 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9286 # check output - 9287 (check-stream-equal _test-output-stream "" "F - test-compare-with-no-inout: output should be empty") - 9288 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-no-inout: error message") - 9289 # check that stop(1) was called - 9290 (check-ints-equal *(edx+4) 2 "F - test-compare-with-no-inout: exit status") - 9291 # don't restore from ebp - 9292 81 0/subop/add %esp 8/imm32 - 9293 # . epilogue - 9294 5d/pop-to-ebp - 9295 c3/return - 9296 - 9297 test-compare-with-just-one-inout: - 9298 # . prologue - 9299 55/push-ebp - 9300 89/<- %ebp 4/r32/esp - 9301 # setup - 9302 (clear-stream _test-input-stream) - 9303 (clear-stream $_test-input-buffered-file->buffer) - 9304 (clear-stream _test-output-stream) - 9305 (clear-stream $_test-output-buffered-file->buffer) - 9306 (clear-stream _test-error-stream) - 9307 (clear-stream $_test-error-buffered-file->buffer) - 9308 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9309 68/push 0/imm32 - 9310 68/push 0/imm32 - 9311 89/<- %edx 4/r32/esp - 9312 (tailor-exit-descriptor %edx 0x10) - 9313 # - 9314 (write _test-input-stream "fn foo {\n") - 9315 (write _test-input-stream " var x: boolean\n") - 9316 (write _test-input-stream " compare x\n") - 9317 (write _test-input-stream "}\n") - 9318 # convert - 9319 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9320 # registers except esp clobbered at this point - 9321 # restore ed - 9322 89/<- %edx 4/r32/esp - 9323 (flush _test-output-buffered-file) - 9324 (flush _test-error-buffered-file) - 9325 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9331 # check output - 9332 (check-stream-equal _test-output-stream "" "F - test-compare-with-just-one-inout: output should be empty") - 9333 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-just-one-inout: error message") - 9334 # check that stop(1) was called - 9335 (check-ints-equal *(edx+4) 2 "F - test-compare-with-just-one-inout: exit status") - 9336 # don't restore from ebp - 9337 81 0/subop/add %esp 8/imm32 - 9338 # . epilogue - 9339 5d/pop-to-ebp - 9340 c3/return - 9341 - 9342 test-compare-with-too-many-inouts: - 9343 # . prologue - 9344 55/push-ebp - 9345 89/<- %ebp 4/r32/esp - 9346 # setup - 9347 (clear-stream _test-input-stream) - 9348 (clear-stream $_test-input-buffered-file->buffer) - 9349 (clear-stream _test-output-stream) - 9350 (clear-stream $_test-output-buffered-file->buffer) - 9351 (clear-stream _test-error-stream) - 9352 (clear-stream $_test-error-buffered-file->buffer) - 9353 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9354 68/push 0/imm32 - 9355 68/push 0/imm32 - 9356 89/<- %edx 4/r32/esp - 9357 (tailor-exit-descriptor %edx 0x10) - 9358 # - 9359 (write _test-input-stream "fn foo {\n") - 9360 (write _test-input-stream " var x: boolean\n") - 9361 (write _test-input-stream " compare x, 0, 0\n") - 9362 (write _test-input-stream "}\n") - 9363 # convert - 9364 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9365 # registers except esp clobbered at this point - 9366 # restore ed - 9367 89/<- %edx 4/r32/esp - 9368 (flush _test-output-buffered-file) - 9369 (flush _test-error-buffered-file) - 9370 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9376 # check output - 9377 (check-stream-equal _test-output-stream "" "F - test-compare-with-too-many-inouts: output should be empty") - 9378 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-too-many-inouts: error message") - 9379 # check that stop(1) was called - 9380 (check-ints-equal *(edx+4) 2 "F - test-compare-with-too-many-inouts: exit status") - 9381 # don't restore from ebp - 9382 81 0/subop/add %esp 8/imm32 - 9383 # . epilogue - 9384 5d/pop-to-ebp - 9385 c3/return - 9386 - 9387 test-compare-with-output: - 9388 # . prologue - 9389 55/push-ebp - 9390 89/<- %ebp 4/r32/esp - 9391 # setup - 9392 (clear-stream _test-input-stream) - 9393 (clear-stream $_test-input-buffered-file->buffer) - 9394 (clear-stream _test-output-stream) - 9395 (clear-stream $_test-output-buffered-file->buffer) - 9396 (clear-stream _test-error-stream) - 9397 (clear-stream $_test-error-buffered-file->buffer) - 9398 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9399 68/push 0/imm32 - 9400 68/push 0/imm32 - 9401 89/<- %edx 4/r32/esp - 9402 (tailor-exit-descriptor %edx 0x10) - 9403 # - 9404 (write _test-input-stream "fn foo {\n") - 9405 (write _test-input-stream " var x/eax: boolean <- copy 0\n") - 9406 (write _test-input-stream " var y/ecx: boolean <- copy 0\n") - 9407 (write _test-input-stream " x <- compare y, 0\n") - 9408 (write _test-input-stream "}\n") - 9409 # convert - 9410 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9411 # registers except esp clobbered at this point - 9412 # restore ed - 9413 89/<- %edx 4/r32/esp - 9414 (flush _test-output-buffered-file) - 9415 (flush _test-error-buffered-file) - 9416 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9422 # check output - 9423 (check-stream-equal _test-output-stream "" "F - test-compare-with-output: output should be empty") - 9424 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must not have any outputs" "F - test-compare-with-output: error message") - 9425 # check that stop(1) was called - 9426 (check-ints-equal *(edx+4) 2 "F - test-compare-with-output: exit status") - 9427 # don't restore from ebp - 9428 81 0/subop/add %esp 8/imm32 - 9429 # . epilogue - 9430 5d/pop-to-ebp - 9431 c3/return - 9432 - 9433 test-compare-invalid-value-to-address: - 9434 # . prologue - 9435 55/push-ebp - 9436 89/<- %ebp 4/r32/esp - 9437 # setup - 9438 (clear-stream _test-input-stream) - 9439 (clear-stream $_test-input-buffered-file->buffer) - 9440 (clear-stream _test-output-stream) - 9441 (clear-stream $_test-output-buffered-file->buffer) - 9442 (clear-stream _test-error-stream) - 9443 (clear-stream $_test-error-buffered-file->buffer) - 9444 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9445 68/push 0/imm32 - 9446 68/push 0/imm32 - 9447 89/<- %edx 4/r32/esp - 9448 (tailor-exit-descriptor %edx 0x10) - 9449 # - 9450 (write _test-input-stream "fn foo {\n") - 9451 (write _test-input-stream " var x/eax: int <- copy 0\n") - 9452 (write _test-input-stream " var y: (addr int)\n") - 9453 (write _test-input-stream " compare y, x\n") - 9454 (write _test-input-stream "}\n") - 9455 # convert - 9456 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9457 # registers except esp clobbered at this point - 9458 # restore ed - 9459 89/<- %edx 4/r32/esp - 9460 (flush _test-output-buffered-file) - 9461 (flush _test-error-buffered-file) - 9462 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9468 # check output - 9469 (check-stream-equal _test-output-stream "" "F - test-compare-invalid-value-to-address: output should be empty") - 9470 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: 'y' must be a non-addr non-offset scalar" "F - test-compare-invalid-value-to-address: error message") - 9471 # check that stop(1) was called - 9472 (check-ints-equal *(edx+4) 2 "F - test-compare-invalid-value-to-address: exit status") - 9473 # don't restore from ebp - 9474 81 0/subop/add %esp 8/imm32 - 9475 # . epilogue - 9476 5d/pop-to-ebp - 9477 c3/return - 9478 - 9479 test-compare-address: - 9480 # . prologue - 9481 55/push-ebp - 9482 89/<- %ebp 4/r32/esp - 9483 # setup - 9484 (clear-stream _test-input-stream) - 9485 (clear-stream $_test-input-buffered-file->buffer) - 9486 (clear-stream _test-output-stream) - 9487 (clear-stream $_test-output-buffered-file->buffer) - 9488 # - 9489 (write _test-input-stream "fn foo {\n") - 9490 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") - 9491 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") - 9492 (write _test-input-stream " compare y, x\n") - 9493 (write _test-input-stream "}\n") - 9494 # convert - 9495 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 9496 (flush _test-output-buffered-file) - 9497 # no errors + 9215 # + 9216 (write _test-input-stream "fn foo {\n") + 9217 (write _test-input-stream " var x/eax: byte <- copy 0\n") + 9218 (write _test-input-stream " var y/ecx: (addr byte) <- copy 0\n") + 9219 (write _test-input-stream " copy-byte-to *y, x\n") + 9220 (write _test-input-stream "}\n") + 9221 # convert + 9222 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 9223 (flush _test-output-buffered-file) + 9224 # no errors + 9225 # . epilogue + 9226 5d/pop-to-ebp + 9227 c3/return + 9228 + 9229 test-copy-byte-to-from-non-scalar-inout: + 9230 # . prologue + 9231 55/push-ebp + 9232 89/<- %ebp 4/r32/esp + 9233 # setup + 9234 (clear-stream _test-input-stream) + 9235 (clear-stream $_test-input-buffered-file->buffer) + 9236 (clear-stream _test-output-stream) + 9237 (clear-stream $_test-output-buffered-file->buffer) + 9238 (clear-stream _test-error-stream) + 9239 (clear-stream $_test-error-buffered-file->buffer) + 9240 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9241 68/push 0/imm32 + 9242 68/push 0/imm32 + 9243 89/<- %edx 4/r32/esp + 9244 (tailor-exit-descriptor %edx 0x10) + 9245 # + 9246 (write _test-input-stream "fn foo {\n") + 9247 (write _test-input-stream " var x: (handle int)\n") + 9248 (write _test-input-stream " var y/eax: (addr byte) <- copy 0\n") + 9249 (write _test-input-stream " copy-byte-to *y, x\n") + 9250 (write _test-input-stream "}\n") + 9251 # convert + 9252 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9253 # registers except esp clobbered at this point + 9254 # restore ed + 9255 89/<- %edx 4/r32/esp + 9256 (flush _test-output-buffered-file) + 9257 (flush _test-error-buffered-file) + 9258 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9264 # check output + 9265 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-from-non-scalar-inout: output should be empty") + 9266 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: 'x' is too large to copy" "F - test-copy-byte-to-from-non-scalar-inout: error message") + 9267 # check that stop(1) was called + 9268 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-from-non-scalar-inout: exit status") + 9269 # don't restore from ebp + 9270 81 0/subop/add %esp 8/imm32 + 9271 # . epilogue + 9272 5d/pop-to-ebp + 9273 c3/return + 9274 + 9275 test-compare-with-no-inout: + 9276 # . prologue + 9277 55/push-ebp + 9278 89/<- %ebp 4/r32/esp + 9279 # setup + 9280 (clear-stream _test-input-stream) + 9281 (clear-stream $_test-input-buffered-file->buffer) + 9282 (clear-stream _test-output-stream) + 9283 (clear-stream $_test-output-buffered-file->buffer) + 9284 (clear-stream _test-error-stream) + 9285 (clear-stream $_test-error-buffered-file->buffer) + 9286 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9287 68/push 0/imm32 + 9288 68/push 0/imm32 + 9289 89/<- %edx 4/r32/esp + 9290 (tailor-exit-descriptor %edx 0x10) + 9291 # + 9292 (write _test-input-stream "fn foo {\n") + 9293 (write _test-input-stream " var x: boolean\n") + 9294 (write _test-input-stream " compare\n") + 9295 (write _test-input-stream "}\n") + 9296 # convert + 9297 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9298 # registers except esp clobbered at this point + 9299 # restore ed + 9300 89/<- %edx 4/r32/esp + 9301 (flush _test-output-buffered-file) + 9302 (flush _test-error-buffered-file) + 9303 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9309 # check output + 9310 (check-stream-equal _test-output-stream "" "F - test-compare-with-no-inout: output should be empty") + 9311 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-no-inout: error message") + 9312 # check that stop(1) was called + 9313 (check-ints-equal *(edx+4) 2 "F - test-compare-with-no-inout: exit status") + 9314 # don't restore from ebp + 9315 81 0/subop/add %esp 8/imm32 + 9316 # . epilogue + 9317 5d/pop-to-ebp + 9318 c3/return + 9319 + 9320 test-compare-with-just-one-inout: + 9321 # . prologue + 9322 55/push-ebp + 9323 89/<- %ebp 4/r32/esp + 9324 # setup + 9325 (clear-stream _test-input-stream) + 9326 (clear-stream $_test-input-buffered-file->buffer) + 9327 (clear-stream _test-output-stream) + 9328 (clear-stream $_test-output-buffered-file->buffer) + 9329 (clear-stream _test-error-stream) + 9330 (clear-stream $_test-error-buffered-file->buffer) + 9331 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9332 68/push 0/imm32 + 9333 68/push 0/imm32 + 9334 89/<- %edx 4/r32/esp + 9335 (tailor-exit-descriptor %edx 0x10) + 9336 # + 9337 (write _test-input-stream "fn foo {\n") + 9338 (write _test-input-stream " var x: boolean\n") + 9339 (write _test-input-stream " compare x\n") + 9340 (write _test-input-stream "}\n") + 9341 # convert + 9342 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9343 # registers except esp clobbered at this point + 9344 # restore ed + 9345 89/<- %edx 4/r32/esp + 9346 (flush _test-output-buffered-file) + 9347 (flush _test-error-buffered-file) + 9348 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9354 # check output + 9355 (check-stream-equal _test-output-stream "" "F - test-compare-with-just-one-inout: output should be empty") + 9356 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-just-one-inout: error message") + 9357 # check that stop(1) was called + 9358 (check-ints-equal *(edx+4) 2 "F - test-compare-with-just-one-inout: exit status") + 9359 # don't restore from ebp + 9360 81 0/subop/add %esp 8/imm32 + 9361 # . epilogue + 9362 5d/pop-to-ebp + 9363 c3/return + 9364 + 9365 test-compare-with-too-many-inouts: + 9366 # . prologue + 9367 55/push-ebp + 9368 89/<- %ebp 4/r32/esp + 9369 # setup + 9370 (clear-stream _test-input-stream) + 9371 (clear-stream $_test-input-buffered-file->buffer) + 9372 (clear-stream _test-output-stream) + 9373 (clear-stream $_test-output-buffered-file->buffer) + 9374 (clear-stream _test-error-stream) + 9375 (clear-stream $_test-error-buffered-file->buffer) + 9376 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9377 68/push 0/imm32 + 9378 68/push 0/imm32 + 9379 89/<- %edx 4/r32/esp + 9380 (tailor-exit-descriptor %edx 0x10) + 9381 # + 9382 (write _test-input-stream "fn foo {\n") + 9383 (write _test-input-stream " var x: boolean\n") + 9384 (write _test-input-stream " compare x, 0, 0\n") + 9385 (write _test-input-stream "}\n") + 9386 # convert + 9387 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9388 # registers except esp clobbered at this point + 9389 # restore ed + 9390 89/<- %edx 4/r32/esp + 9391 (flush _test-output-buffered-file) + 9392 (flush _test-error-buffered-file) + 9393 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9399 # check output + 9400 (check-stream-equal _test-output-stream "" "F - test-compare-with-too-many-inouts: output should be empty") + 9401 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-too-many-inouts: error message") + 9402 # check that stop(1) was called + 9403 (check-ints-equal *(edx+4) 2 "F - test-compare-with-too-many-inouts: exit status") + 9404 # don't restore from ebp + 9405 81 0/subop/add %esp 8/imm32 + 9406 # . epilogue + 9407 5d/pop-to-ebp + 9408 c3/return + 9409 + 9410 test-compare-with-output: + 9411 # . prologue + 9412 55/push-ebp + 9413 89/<- %ebp 4/r32/esp + 9414 # setup + 9415 (clear-stream _test-input-stream) + 9416 (clear-stream $_test-input-buffered-file->buffer) + 9417 (clear-stream _test-output-stream) + 9418 (clear-stream $_test-output-buffered-file->buffer) + 9419 (clear-stream _test-error-stream) + 9420 (clear-stream $_test-error-buffered-file->buffer) + 9421 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9422 68/push 0/imm32 + 9423 68/push 0/imm32 + 9424 89/<- %edx 4/r32/esp + 9425 (tailor-exit-descriptor %edx 0x10) + 9426 # + 9427 (write _test-input-stream "fn foo {\n") + 9428 (write _test-input-stream " var x/eax: boolean <- copy 0\n") + 9429 (write _test-input-stream " var y/ecx: boolean <- copy 0\n") + 9430 (write _test-input-stream " x <- compare y, 0\n") + 9431 (write _test-input-stream "}\n") + 9432 # convert + 9433 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9434 # registers except esp clobbered at this point + 9435 # restore ed + 9436 89/<- %edx 4/r32/esp + 9437 (flush _test-output-buffered-file) + 9438 (flush _test-error-buffered-file) + 9439 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9445 # check output + 9446 (check-stream-equal _test-output-stream "" "F - test-compare-with-output: output should be empty") + 9447 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must not have any outputs" "F - test-compare-with-output: error message") + 9448 # check that stop(1) was called + 9449 (check-ints-equal *(edx+4) 2 "F - test-compare-with-output: exit status") + 9450 # don't restore from ebp + 9451 81 0/subop/add %esp 8/imm32 + 9452 # . epilogue + 9453 5d/pop-to-ebp + 9454 c3/return + 9455 + 9456 test-compare-invalid-value-to-address: + 9457 # . prologue + 9458 55/push-ebp + 9459 89/<- %ebp 4/r32/esp + 9460 # setup + 9461 (clear-stream _test-input-stream) + 9462 (clear-stream $_test-input-buffered-file->buffer) + 9463 (clear-stream _test-output-stream) + 9464 (clear-stream $_test-output-buffered-file->buffer) + 9465 (clear-stream _test-error-stream) + 9466 (clear-stream $_test-error-buffered-file->buffer) + 9467 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9468 68/push 0/imm32 + 9469 68/push 0/imm32 + 9470 89/<- %edx 4/r32/esp + 9471 (tailor-exit-descriptor %edx 0x10) + 9472 # + 9473 (write _test-input-stream "fn foo {\n") + 9474 (write _test-input-stream " var x/eax: int <- copy 0\n") + 9475 (write _test-input-stream " var y: (addr int)\n") + 9476 (write _test-input-stream " compare y, x\n") + 9477 (write _test-input-stream "}\n") + 9478 # convert + 9479 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9480 # registers except esp clobbered at this point + 9481 # restore ed + 9482 89/<- %edx 4/r32/esp + 9483 (flush _test-output-buffered-file) + 9484 (flush _test-error-buffered-file) + 9485 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9491 # check output + 9492 (check-stream-equal _test-output-stream "" "F - test-compare-invalid-value-to-address: output should be empty") + 9493 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: 'y' must be a non-addr non-offset scalar" "F - test-compare-invalid-value-to-address: error message") + 9494 # check that stop(1) was called + 9495 (check-ints-equal *(edx+4) 2 "F - test-compare-invalid-value-to-address: exit status") + 9496 # don't restore from ebp + 9497 81 0/subop/add %esp 8/imm32 9498 # . epilogue 9499 5d/pop-to-ebp 9500 c3/return 9501 - 9502 test-compare-deref-address: + 9502 test-compare-address: 9503 # . prologue 9504 55/push-ebp 9505 89/<- %ebp 4/r32/esp @@ -8663,18 +8663,18 @@ if ('onhashchange' in window) { 9511 # 9512 (write _test-input-stream "fn foo {\n") 9513 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") - 9514 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n") - 9515 (write _test-input-stream " compare *y, x\n") + 9514 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") + 9515 (write _test-input-stream " compare y, x\n") 9516 (write _test-input-stream "}\n") 9517 # convert - 9518 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 9518 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 9519 (flush _test-output-buffered-file) 9520 # no errors 9521 # . epilogue 9522 5d/pop-to-ebp 9523 c3/return 9524 - 9525 test-compare-two-vars-in-memory: + 9525 test-compare-deref-address: 9526 # . prologue 9527 55/push-ebp 9528 89/<- %ebp 4/r32/esp @@ -8683,404 +8683,404 @@ if ('onhashchange' in window) { 9531 (clear-stream $_test-input-buffered-file->buffer) 9532 (clear-stream _test-output-stream) 9533 (clear-stream $_test-output-buffered-file->buffer) - 9534 (clear-stream _test-error-stream) - 9535 (clear-stream $_test-error-buffered-file->buffer) - 9536 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9537 68/push 0/imm32 - 9538 68/push 0/imm32 - 9539 89/<- %edx 4/r32/esp - 9540 (tailor-exit-descriptor %edx 0x10) - 9541 # - 9542 (write _test-input-stream "fn foo {\n") - 9543 (write _test-input-stream " var x: boolean\n") - 9544 (write _test-input-stream " compare x, x\n") - 9545 (write _test-input-stream "}\n") - 9546 # convert - 9547 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9548 # registers except esp clobbered at this point - 9549 # restore ed - 9550 89/<- %edx 4/r32/esp - 9551 (flush _test-output-buffered-file) - 9552 (flush _test-error-buffered-file) - 9553 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9559 # check output - 9560 (check-stream-equal _test-output-stream "" "F - test-compare-two-vars-in-memory: output should be empty") - 9561 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: both inouts are in memory" "F - test-compare-two-vars-in-memory: error message") - 9562 # check that stop(1) was called - 9563 (check-ints-equal *(edx+4) 2 "F - test-compare-two-vars-in-memory: exit status") - 9564 # don't restore from ebp - 9565 81 0/subop/add %esp 8/imm32 - 9566 # . epilogue - 9567 5d/pop-to-ebp - 9568 c3/return - 9569 - 9570 test-compare-non-scalar: - 9571 # . prologue - 9572 55/push-ebp - 9573 89/<- %ebp 4/r32/esp - 9574 # setup - 9575 (clear-stream _test-input-stream) - 9576 (clear-stream $_test-input-buffered-file->buffer) - 9577 (clear-stream _test-output-stream) - 9578 (clear-stream $_test-output-buffered-file->buffer) - 9579 (clear-stream _test-error-stream) - 9580 (clear-stream $_test-error-buffered-file->buffer) - 9581 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9582 68/push 0/imm32 - 9583 68/push 0/imm32 - 9584 89/<- %edx 4/r32/esp - 9585 (tailor-exit-descriptor %edx 0x10) - 9586 # - 9587 (write _test-input-stream "fn foo {\n") - 9588 (write _test-input-stream " var x: (handle int)\n") - 9589 (write _test-input-stream " var y: int\n") - 9590 (write _test-input-stream " compare y, x\n") - 9591 (write _test-input-stream "}\n") - 9592 # convert - 9593 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9594 # registers except esp clobbered at this point - 9595 # restore ed - 9596 89/<- %edx 4/r32/esp - 9597 (flush _test-output-buffered-file) - 9598 (flush _test-error-buffered-file) - 9599 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9605 # check output - 9606 (check-stream-equal _test-output-stream "" "F - test-compare-non-scalar: output should be empty") - 9607 #? (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: 'x' is too large to compare" "F - test-compare-non-scalar: error message") - 9608 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: both inouts are in memory" "F - test-compare-non-scalar: error message") - 9609 # check that stop(1) was called - 9610 (check-ints-equal *(edx+4) 2 "F - test-compare-non-scalar: exit status") - 9611 # don't restore from ebp - 9612 81 0/subop/add %esp 8/imm32 - 9613 # . epilogue - 9614 5d/pop-to-ebp - 9615 c3/return - 9616 - 9617 test-compare-with-string-literal: - 9618 # . prologue - 9619 55/push-ebp - 9620 89/<- %ebp 4/r32/esp - 9621 # setup - 9622 (clear-stream _test-input-stream) - 9623 (clear-stream $_test-input-buffered-file->buffer) - 9624 (clear-stream _test-output-stream) - 9625 (clear-stream $_test-output-buffered-file->buffer) - 9626 (clear-stream _test-error-stream) - 9627 (clear-stream $_test-error-buffered-file->buffer) - 9628 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9629 68/push 0/imm32 - 9630 68/push 0/imm32 - 9631 89/<- %edx 4/r32/esp - 9632 (tailor-exit-descriptor %edx 0x10) - 9633 # - 9634 (write _test-input-stream "fn foo {\n") - 9635 (write _test-input-stream " var x/eax: (addr array byte) <- copy 0\n") - 9636 (write _test-input-stream " compare x, \"abc\"\n") - 9637 (write _test-input-stream "}\n") - 9638 # convert - 9639 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9640 # registers except esp clobbered at this point - 9641 # restore ed - 9642 89/<- %edx 4/r32/esp - 9643 (flush _test-output-buffered-file) - 9644 (flush _test-error-buffered-file) - 9645 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9651 # check output - 9652 (check-stream-equal _test-output-stream "" "F - test-compare-with-string-literal: output should be empty") - 9653 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: string literal \"abc\" is not supported; use the string-equal? function" "F - test-compare-with-string-literal: error message") - 9654 # check that stop(1) was called - 9655 (check-ints-equal *(edx+4) 2 "F - test-compare-with-string-literal: exit status") - 9656 # don't restore from ebp - 9657 81 0/subop/add %esp 8/imm32 - 9658 # . epilogue - 9659 5d/pop-to-ebp - 9660 c3/return - 9661 - 9662 test-address-with-no-inout: - 9663 # . prologue - 9664 55/push-ebp - 9665 89/<- %ebp 4/r32/esp - 9666 # setup - 9667 (clear-stream _test-input-stream) - 9668 (clear-stream $_test-input-buffered-file->buffer) - 9669 (clear-stream _test-output-stream) - 9670 (clear-stream $_test-output-buffered-file->buffer) - 9671 (clear-stream _test-error-stream) - 9672 (clear-stream $_test-error-buffered-file->buffer) - 9673 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9674 68/push 0/imm32 - 9675 68/push 0/imm32 - 9676 89/<- %edx 4/r32/esp - 9677 (tailor-exit-descriptor %edx 0x10) - 9678 # - 9679 (write _test-input-stream "fn foo {\n") - 9680 (write _test-input-stream " var x/eax: boolean <- address\n") - 9681 (write _test-input-stream "}\n") - 9682 # convert - 9683 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9684 # registers except esp clobbered at this point - 9685 # restore ed - 9686 89/<- %edx 4/r32/esp - 9687 (flush _test-output-buffered-file) - 9688 (flush _test-error-buffered-file) - 9689 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9695 # check output - 9696 (check-stream-equal _test-output-stream "" "F - test-address-with-no-inout: output should be empty") - 9697 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' expects an inout" "F - test-address-with-no-inout: error message") - 9698 # check that stop(1) was called - 9699 (check-ints-equal *(edx+4) 2 "F - test-address-with-no-inout: exit status") - 9700 # don't restore from ebp - 9701 81 0/subop/add %esp 8/imm32 - 9702 # . epilogue - 9703 5d/pop-to-ebp - 9704 c3/return - 9705 - 9706 test-address-with-multiple-inouts: - 9707 # . prologue - 9708 55/push-ebp - 9709 89/<- %ebp 4/r32/esp - 9710 # setup - 9711 (clear-stream _test-input-stream) - 9712 (clear-stream $_test-input-buffered-file->buffer) - 9713 (clear-stream _test-output-stream) - 9714 (clear-stream $_test-output-buffered-file->buffer) - 9715 (clear-stream _test-error-stream) - 9716 (clear-stream $_test-error-buffered-file->buffer) - 9717 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9718 68/push 0/imm32 - 9719 68/push 0/imm32 - 9720 89/<- %edx 4/r32/esp - 9721 (tailor-exit-descriptor %edx 0x10) - 9722 # - 9723 (write _test-input-stream "fn foo {\n") - 9724 (write _test-input-stream " var x/eax: boolean <- address 0, 0\n") - 9725 (write _test-input-stream "}\n") - 9726 # convert - 9727 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9728 # registers except esp clobbered at this point - 9729 # restore ed - 9730 89/<- %edx 4/r32/esp - 9731 (flush _test-output-buffered-file) - 9732 (flush _test-error-buffered-file) - 9733 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9739 # check output - 9740 (check-stream-equal _test-output-stream "" "F - test-address-with-multiple-inouts: output should be empty") - 9741 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' must have just one inout" "F - test-address-with-multiple-inouts: error message") - 9742 # check that stop(1) was called - 9743 (check-ints-equal *(edx+4) 2 "F - test-address-with-multiple-inouts: exit status") - 9744 # don't restore from ebp - 9745 81 0/subop/add %esp 8/imm32 - 9746 # . epilogue - 9747 5d/pop-to-ebp - 9748 c3/return - 9749 - 9750 test-address-with-no-output: - 9751 # . prologue - 9752 55/push-ebp - 9753 89/<- %ebp 4/r32/esp - 9754 # setup - 9755 (clear-stream _test-input-stream) - 9756 (clear-stream $_test-input-buffered-file->buffer) - 9757 (clear-stream _test-output-stream) - 9758 (clear-stream $_test-output-buffered-file->buffer) - 9759 (clear-stream _test-error-stream) - 9760 (clear-stream $_test-error-buffered-file->buffer) - 9761 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9762 68/push 0/imm32 - 9763 68/push 0/imm32 - 9764 89/<- %edx 4/r32/esp - 9765 (tailor-exit-descriptor %edx 0x10) - 9766 # - 9767 (write _test-input-stream "fn foo {\n") - 9768 (write _test-input-stream " address 0\n") - 9769 (write _test-input-stream "}\n") - 9770 # convert - 9771 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9772 # registers except esp clobbered at this point - 9773 # restore ed - 9774 89/<- %edx 4/r32/esp - 9775 (flush _test-output-buffered-file) - 9776 (flush _test-error-buffered-file) - 9777 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9783 # check output - 9784 (check-stream-equal _test-output-stream "" "F - test-address-with-no-output: output should be empty") - 9785 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' expects an output" "F - test-address-with-no-output: error message") - 9786 # check that stop(1) was called - 9787 (check-ints-equal *(edx+4) 2 "F - test-address-with-no-output: exit status") - 9788 # don't restore from ebp - 9789 81 0/subop/add %esp 8/imm32 - 9790 # . epilogue - 9791 5d/pop-to-ebp - 9792 c3/return - 9793 - 9794 test-address-with-multiple-outputs: - 9795 # . prologue - 9796 55/push-ebp - 9797 89/<- %ebp 4/r32/esp - 9798 # setup - 9799 (clear-stream _test-input-stream) - 9800 (clear-stream $_test-input-buffered-file->buffer) - 9801 (clear-stream _test-output-stream) - 9802 (clear-stream $_test-output-buffered-file->buffer) - 9803 (clear-stream _test-error-stream) - 9804 (clear-stream $_test-error-buffered-file->buffer) - 9805 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9806 68/push 0/imm32 - 9807 68/push 0/imm32 - 9808 89/<- %edx 4/r32/esp - 9809 (tailor-exit-descriptor %edx 0x10) - 9810 # - 9811 (write _test-input-stream "fn foo {\n") - 9812 (write _test-input-stream " var x/eax: boolean <- copy 0\n") - 9813 (write _test-input-stream " var y/ecx: boolean <- copy 0\n") - 9814 (write _test-input-stream " x, y <- address 0\n") - 9815 (write _test-input-stream "}\n") - 9816 # convert - 9817 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9818 # registers except esp clobbered at this point - 9819 # restore ed - 9820 89/<- %edx 4/r32/esp - 9821 (flush _test-output-buffered-file) - 9822 (flush _test-error-buffered-file) - 9823 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9829 # check output - 9830 (check-stream-equal _test-output-stream "" "F - test-address-with-multiple-outputs: output should be empty") - 9831 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' must have just one output" "F - test-address-with-multiple-outputs: error message") - 9832 # check that stop(1) was called - 9833 (check-ints-equal *(edx+4) 2 "F - test-address-with-multiple-outputs: exit status") - 9834 # don't restore from ebp - 9835 81 0/subop/add %esp 8/imm32 - 9836 # . epilogue - 9837 5d/pop-to-ebp - 9838 c3/return - 9839 - 9840 # silly but it works - 9841 test-address-of-deref: - 9842 # . prologue - 9843 55/push-ebp - 9844 89/<- %ebp 4/r32/esp - 9845 # setup - 9846 (clear-stream _test-input-stream) - 9847 (clear-stream $_test-input-buffered-file->buffer) - 9848 (clear-stream _test-output-stream) - 9849 (clear-stream $_test-output-buffered-file->buffer) - 9850 # - 9851 (write _test-input-stream "fn foo {\n") - 9852 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") - 9853 (write _test-input-stream " var y/ecx: (addr int) <- address *x\n") - 9854 (write _test-input-stream "}\n") - 9855 # convert - 9856 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 9857 (flush _test-output-buffered-file) - 9858 # no errors + 9534 # + 9535 (write _test-input-stream "fn foo {\n") + 9536 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") + 9537 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n") + 9538 (write _test-input-stream " compare *y, x\n") + 9539 (write _test-input-stream "}\n") + 9540 # convert + 9541 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 9542 (flush _test-output-buffered-file) + 9543 # no errors + 9544 # . epilogue + 9545 5d/pop-to-ebp + 9546 c3/return + 9547 + 9548 test-compare-two-vars-in-memory: + 9549 # . prologue + 9550 55/push-ebp + 9551 89/<- %ebp 4/r32/esp + 9552 # setup + 9553 (clear-stream _test-input-stream) + 9554 (clear-stream $_test-input-buffered-file->buffer) + 9555 (clear-stream _test-output-stream) + 9556 (clear-stream $_test-output-buffered-file->buffer) + 9557 (clear-stream _test-error-stream) + 9558 (clear-stream $_test-error-buffered-file->buffer) + 9559 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9560 68/push 0/imm32 + 9561 68/push 0/imm32 + 9562 89/<- %edx 4/r32/esp + 9563 (tailor-exit-descriptor %edx 0x10) + 9564 # + 9565 (write _test-input-stream "fn foo {\n") + 9566 (write _test-input-stream " var x: boolean\n") + 9567 (write _test-input-stream " compare x, x\n") + 9568 (write _test-input-stream "}\n") + 9569 # convert + 9570 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9571 # registers except esp clobbered at this point + 9572 # restore ed + 9573 89/<- %edx 4/r32/esp + 9574 (flush _test-output-buffered-file) + 9575 (flush _test-error-buffered-file) + 9576 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9582 # check output + 9583 (check-stream-equal _test-output-stream "" "F - test-compare-two-vars-in-memory: output should be empty") + 9584 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: both inouts are in memory" "F - test-compare-two-vars-in-memory: error message") + 9585 # check that stop(1) was called + 9586 (check-ints-equal *(edx+4) 2 "F - test-compare-two-vars-in-memory: exit status") + 9587 # don't restore from ebp + 9588 81 0/subop/add %esp 8/imm32 + 9589 # . epilogue + 9590 5d/pop-to-ebp + 9591 c3/return + 9592 + 9593 test-compare-non-scalar: + 9594 # . prologue + 9595 55/push-ebp + 9596 89/<- %ebp 4/r32/esp + 9597 # setup + 9598 (clear-stream _test-input-stream) + 9599 (clear-stream $_test-input-buffered-file->buffer) + 9600 (clear-stream _test-output-stream) + 9601 (clear-stream $_test-output-buffered-file->buffer) + 9602 (clear-stream _test-error-stream) + 9603 (clear-stream $_test-error-buffered-file->buffer) + 9604 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9605 68/push 0/imm32 + 9606 68/push 0/imm32 + 9607 89/<- %edx 4/r32/esp + 9608 (tailor-exit-descriptor %edx 0x10) + 9609 # + 9610 (write _test-input-stream "fn foo {\n") + 9611 (write _test-input-stream " var x: (handle int)\n") + 9612 (write _test-input-stream " var y: int\n") + 9613 (write _test-input-stream " compare y, x\n") + 9614 (write _test-input-stream "}\n") + 9615 # convert + 9616 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9617 # registers except esp clobbered at this point + 9618 # restore ed + 9619 89/<- %edx 4/r32/esp + 9620 (flush _test-output-buffered-file) + 9621 (flush _test-error-buffered-file) + 9622 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9628 # check output + 9629 (check-stream-equal _test-output-stream "" "F - test-compare-non-scalar: output should be empty") + 9630 #? (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: 'x' is too large to compare" "F - test-compare-non-scalar: error message") + 9631 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: both inouts are in memory" "F - test-compare-non-scalar: error message") + 9632 # check that stop(1) was called + 9633 (check-ints-equal *(edx+4) 2 "F - test-compare-non-scalar: exit status") + 9634 # don't restore from ebp + 9635 81 0/subop/add %esp 8/imm32 + 9636 # . epilogue + 9637 5d/pop-to-ebp + 9638 c3/return + 9639 + 9640 test-compare-with-string-literal: + 9641 # . prologue + 9642 55/push-ebp + 9643 89/<- %ebp 4/r32/esp + 9644 # setup + 9645 (clear-stream _test-input-stream) + 9646 (clear-stream $_test-input-buffered-file->buffer) + 9647 (clear-stream _test-output-stream) + 9648 (clear-stream $_test-output-buffered-file->buffer) + 9649 (clear-stream _test-error-stream) + 9650 (clear-stream $_test-error-buffered-file->buffer) + 9651 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9652 68/push 0/imm32 + 9653 68/push 0/imm32 + 9654 89/<- %edx 4/r32/esp + 9655 (tailor-exit-descriptor %edx 0x10) + 9656 # + 9657 (write _test-input-stream "fn foo {\n") + 9658 (write _test-input-stream " var x/eax: (addr array byte) <- copy 0\n") + 9659 (write _test-input-stream " compare x, \"abc\"\n") + 9660 (write _test-input-stream "}\n") + 9661 # convert + 9662 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9663 # registers except esp clobbered at this point + 9664 # restore ed + 9665 89/<- %edx 4/r32/esp + 9666 (flush _test-output-buffered-file) + 9667 (flush _test-error-buffered-file) + 9668 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9674 # check output + 9675 (check-stream-equal _test-output-stream "" "F - test-compare-with-string-literal: output should be empty") + 9676 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: string literal \"abc\" is not supported; use the string-equal? function" "F - test-compare-with-string-literal: error message") + 9677 # check that stop(1) was called + 9678 (check-ints-equal *(edx+4) 2 "F - test-compare-with-string-literal: exit status") + 9679 # don't restore from ebp + 9680 81 0/subop/add %esp 8/imm32 + 9681 # . epilogue + 9682 5d/pop-to-ebp + 9683 c3/return + 9684 + 9685 test-address-with-no-inout: + 9686 # . prologue + 9687 55/push-ebp + 9688 89/<- %ebp 4/r32/esp + 9689 # setup + 9690 (clear-stream _test-input-stream) + 9691 (clear-stream $_test-input-buffered-file->buffer) + 9692 (clear-stream _test-output-stream) + 9693 (clear-stream $_test-output-buffered-file->buffer) + 9694 (clear-stream _test-error-stream) + 9695 (clear-stream $_test-error-buffered-file->buffer) + 9696 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9697 68/push 0/imm32 + 9698 68/push 0/imm32 + 9699 89/<- %edx 4/r32/esp + 9700 (tailor-exit-descriptor %edx 0x10) + 9701 # + 9702 (write _test-input-stream "fn foo {\n") + 9703 (write _test-input-stream " var x/eax: boolean <- address\n") + 9704 (write _test-input-stream "}\n") + 9705 # convert + 9706 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9707 # registers except esp clobbered at this point + 9708 # restore ed + 9709 89/<- %edx 4/r32/esp + 9710 (flush _test-output-buffered-file) + 9711 (flush _test-error-buffered-file) + 9712 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9718 # check output + 9719 (check-stream-equal _test-output-stream "" "F - test-address-with-no-inout: output should be empty") + 9720 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' expects an inout" "F - test-address-with-no-inout: error message") + 9721 # check that stop(1) was called + 9722 (check-ints-equal *(edx+4) 2 "F - test-address-with-no-inout: exit status") + 9723 # don't restore from ebp + 9724 81 0/subop/add %esp 8/imm32 + 9725 # . epilogue + 9726 5d/pop-to-ebp + 9727 c3/return + 9728 + 9729 test-address-with-multiple-inouts: + 9730 # . prologue + 9731 55/push-ebp + 9732 89/<- %ebp 4/r32/esp + 9733 # setup + 9734 (clear-stream _test-input-stream) + 9735 (clear-stream $_test-input-buffered-file->buffer) + 9736 (clear-stream _test-output-stream) + 9737 (clear-stream $_test-output-buffered-file->buffer) + 9738 (clear-stream _test-error-stream) + 9739 (clear-stream $_test-error-buffered-file->buffer) + 9740 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9741 68/push 0/imm32 + 9742 68/push 0/imm32 + 9743 89/<- %edx 4/r32/esp + 9744 (tailor-exit-descriptor %edx 0x10) + 9745 # + 9746 (write _test-input-stream "fn foo {\n") + 9747 (write _test-input-stream " var x/eax: boolean <- address 0, 0\n") + 9748 (write _test-input-stream "}\n") + 9749 # convert + 9750 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9751 # registers except esp clobbered at this point + 9752 # restore ed + 9753 89/<- %edx 4/r32/esp + 9754 (flush _test-output-buffered-file) + 9755 (flush _test-error-buffered-file) + 9756 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9762 # check output + 9763 (check-stream-equal _test-output-stream "" "F - test-address-with-multiple-inouts: output should be empty") + 9764 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' must have just one inout" "F - test-address-with-multiple-inouts: error message") + 9765 # check that stop(1) was called + 9766 (check-ints-equal *(edx+4) 2 "F - test-address-with-multiple-inouts: exit status") + 9767 # don't restore from ebp + 9768 81 0/subop/add %esp 8/imm32 + 9769 # . epilogue + 9770 5d/pop-to-ebp + 9771 c3/return + 9772 + 9773 test-address-with-no-output: + 9774 # . prologue + 9775 55/push-ebp + 9776 89/<- %ebp 4/r32/esp + 9777 # setup + 9778 (clear-stream _test-input-stream) + 9779 (clear-stream $_test-input-buffered-file->buffer) + 9780 (clear-stream _test-output-stream) + 9781 (clear-stream $_test-output-buffered-file->buffer) + 9782 (clear-stream _test-error-stream) + 9783 (clear-stream $_test-error-buffered-file->buffer) + 9784 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9785 68/push 0/imm32 + 9786 68/push 0/imm32 + 9787 89/<- %edx 4/r32/esp + 9788 (tailor-exit-descriptor %edx 0x10) + 9789 # + 9790 (write _test-input-stream "fn foo {\n") + 9791 (write _test-input-stream " address 0\n") + 9792 (write _test-input-stream "}\n") + 9793 # convert + 9794 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9795 # registers except esp clobbered at this point + 9796 # restore ed + 9797 89/<- %edx 4/r32/esp + 9798 (flush _test-output-buffered-file) + 9799 (flush _test-error-buffered-file) + 9800 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9806 # check output + 9807 (check-stream-equal _test-output-stream "" "F - test-address-with-no-output: output should be empty") + 9808 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' expects an output" "F - test-address-with-no-output: error message") + 9809 # check that stop(1) was called + 9810 (check-ints-equal *(edx+4) 2 "F - test-address-with-no-output: exit status") + 9811 # don't restore from ebp + 9812 81 0/subop/add %esp 8/imm32 + 9813 # . epilogue + 9814 5d/pop-to-ebp + 9815 c3/return + 9816 + 9817 test-address-with-multiple-outputs: + 9818 # . prologue + 9819 55/push-ebp + 9820 89/<- %ebp 4/r32/esp + 9821 # setup + 9822 (clear-stream _test-input-stream) + 9823 (clear-stream $_test-input-buffered-file->buffer) + 9824 (clear-stream _test-output-stream) + 9825 (clear-stream $_test-output-buffered-file->buffer) + 9826 (clear-stream _test-error-stream) + 9827 (clear-stream $_test-error-buffered-file->buffer) + 9828 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9829 68/push 0/imm32 + 9830 68/push 0/imm32 + 9831 89/<- %edx 4/r32/esp + 9832 (tailor-exit-descriptor %edx 0x10) + 9833 # + 9834 (write _test-input-stream "fn foo {\n") + 9835 (write _test-input-stream " var x/eax: boolean <- copy 0\n") + 9836 (write _test-input-stream " var y/ecx: boolean <- copy 0\n") + 9837 (write _test-input-stream " x, y <- address 0\n") + 9838 (write _test-input-stream "}\n") + 9839 # convert + 9840 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9841 # registers except esp clobbered at this point + 9842 # restore ed + 9843 89/<- %edx 4/r32/esp + 9844 (flush _test-output-buffered-file) + 9845 (flush _test-error-buffered-file) + 9846 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9852 # check output + 9853 (check-stream-equal _test-output-stream "" "F - test-address-with-multiple-outputs: output should be empty") + 9854 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' must have just one output" "F - test-address-with-multiple-outputs: error message") + 9855 # check that stop(1) was called + 9856 (check-ints-equal *(edx+4) 2 "F - test-address-with-multiple-outputs: exit status") + 9857 # don't restore from ebp + 9858 81 0/subop/add %esp 8/imm32 9859 # . epilogue 9860 5d/pop-to-ebp 9861 c3/return 9862 - 9863 test-address-to-non-register: - 9864 # . prologue - 9865 55/push-ebp - 9866 89/<- %ebp 4/r32/esp - 9867 # setup - 9868 (clear-stream _test-input-stream) - 9869 (clear-stream $_test-input-buffered-file->buffer) - 9870 (clear-stream _test-output-stream) - 9871 (clear-stream $_test-output-buffered-file->buffer) - 9872 (clear-stream _test-error-stream) - 9873 (clear-stream $_test-error-buffered-file->buffer) - 9874 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9875 68/push 0/imm32 - 9876 68/push 0/imm32 - 9877 89/<- %edx 4/r32/esp - 9878 (tailor-exit-descriptor %edx 0x10) - 9879 # - 9880 (write _test-input-stream "fn foo {\n") - 9881 (write _test-input-stream " var x: (addr int)\n") - 9882 (write _test-input-stream " x <- address 0\n") - 9883 (write _test-input-stream "}\n") - 9884 # convert - 9885 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9886 # registers except esp clobbered at this point - 9887 # restore ed - 9888 89/<- %edx 4/r32/esp - 9889 (flush _test-output-buffered-file) - 9890 (flush _test-error-buffered-file) - 9891 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9897 # check output - 9898 (check-stream-equal _test-output-stream "" "F - test-address-to-non-register: output should be empty") - 9899 (check-next-stream-line-equal _test-error-stream "fn foo: stmt address: output 'x' not in a register" "F - test-address-to-non-register: error message") - 9900 # check that stop(1) was called - 9901 (check-ints-equal *(edx+4) 2 "F - test-address-to-non-register: exit status") - 9902 # don't restore from ebp - 9903 81 0/subop/add %esp 8/imm32 - 9904 # . epilogue - 9905 5d/pop-to-ebp - 9906 c3/return - 9907 - 9908 test-address-with-wrong-type: - 9909 # . prologue - 9910 55/push-ebp - 9911 89/<- %ebp 4/r32/esp - 9912 # setup - 9913 (clear-stream _test-input-stream) - 9914 (clear-stream $_test-input-buffered-file->buffer) - 9915 (clear-stream _test-output-stream) - 9916 (clear-stream $_test-output-buffered-file->buffer) - 9917 (clear-stream _test-error-stream) - 9918 (clear-stream $_test-error-buffered-file->buffer) - 9919 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 9920 68/push 0/imm32 - 9921 68/push 0/imm32 - 9922 89/<- %edx 4/r32/esp - 9923 (tailor-exit-descriptor %edx 0x10) - 9924 # - 9925 (write _test-input-stream "fn foo {\n") - 9926 (write _test-input-stream " var x: int\n") - 9927 (write _test-input-stream " var y/eax: (addr boolean) <- address x\n") - 9928 (write _test-input-stream "}\n") - 9929 # convert - 9930 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 9931 # registers except esp clobbered at this point - 9932 # restore ed - 9933 89/<- %edx 4/r32/esp - 9934 (flush _test-output-buffered-file) - 9935 (flush _test-error-buffered-file) - 9936 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 9942 # check output - 9943 (check-stream-equal _test-output-stream "" "F - test-address-with-wrong-type: output should be empty") - 9944 (check-next-stream-line-equal _test-error-stream "fn foo: stmt address: output 'y' cannot hold address of 'x'" "F - test-address-with-wrong-type: error message") - 9945 # check that stop(1) was called - 9946 (check-ints-equal *(edx+4) 2 "F - test-address-with-wrong-type: exit status") - 9947 # don't restore from ebp - 9948 81 0/subop/add %esp 8/imm32 - 9949 # . epilogue - 9950 5d/pop-to-ebp - 9951 c3/return - 9952 - 9953 test-address-with-right-type-for-array: - 9954 # . prologue - 9955 55/push-ebp - 9956 89/<- %ebp 4/r32/esp - 9957 # setup - 9958 (clear-stream _test-input-stream) - 9959 (clear-stream $_test-input-buffered-file->buffer) - 9960 (clear-stream _test-output-stream) - 9961 (clear-stream $_test-output-buffered-file->buffer) - 9962 # - 9963 (write _test-input-stream "fn foo {\n") - 9964 (write _test-input-stream " var x: (array int 3)\n") - 9965 (write _test-input-stream " var y/eax: (addr array int) <- address x\n") - 9966 (write _test-input-stream "}\n") - 9967 # convert - 9968 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 9969 (flush _test-output-buffered-file) - 9970 # no errors - 9971 # . epilogue - 9972 89/<- %esp 5/r32/ebp + 9863 # silly but it works + 9864 test-address-of-deref: + 9865 # . prologue + 9866 55/push-ebp + 9867 89/<- %ebp 4/r32/esp + 9868 # setup + 9869 (clear-stream _test-input-stream) + 9870 (clear-stream $_test-input-buffered-file->buffer) + 9871 (clear-stream _test-output-stream) + 9872 (clear-stream $_test-output-buffered-file->buffer) + 9873 # + 9874 (write _test-input-stream "fn foo {\n") + 9875 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") + 9876 (write _test-input-stream " var y/ecx: (addr int) <- address *x\n") + 9877 (write _test-input-stream "}\n") + 9878 # convert + 9879 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 9880 (flush _test-output-buffered-file) + 9881 # no errors + 9882 # . epilogue + 9883 5d/pop-to-ebp + 9884 c3/return + 9885 + 9886 test-address-to-non-register: + 9887 # . prologue + 9888 55/push-ebp + 9889 89/<- %ebp 4/r32/esp + 9890 # setup + 9891 (clear-stream _test-input-stream) + 9892 (clear-stream $_test-input-buffered-file->buffer) + 9893 (clear-stream _test-output-stream) + 9894 (clear-stream $_test-output-buffered-file->buffer) + 9895 (clear-stream _test-error-stream) + 9896 (clear-stream $_test-error-buffered-file->buffer) + 9897 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9898 68/push 0/imm32 + 9899 68/push 0/imm32 + 9900 89/<- %edx 4/r32/esp + 9901 (tailor-exit-descriptor %edx 0x10) + 9902 # + 9903 (write _test-input-stream "fn foo {\n") + 9904 (write _test-input-stream " var x: (addr int)\n") + 9905 (write _test-input-stream " x <- address 0\n") + 9906 (write _test-input-stream "}\n") + 9907 # convert + 9908 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9909 # registers except esp clobbered at this point + 9910 # restore ed + 9911 89/<- %edx 4/r32/esp + 9912 (flush _test-output-buffered-file) + 9913 (flush _test-error-buffered-file) + 9914 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9920 # check output + 9921 (check-stream-equal _test-output-stream "" "F - test-address-to-non-register: output should be empty") + 9922 (check-next-stream-line-equal _test-error-stream "fn foo: stmt address: output 'x' not in a register" "F - test-address-to-non-register: error message") + 9923 # check that stop(1) was called + 9924 (check-ints-equal *(edx+4) 2 "F - test-address-to-non-register: exit status") + 9925 # don't restore from ebp + 9926 81 0/subop/add %esp 8/imm32 + 9927 # . epilogue + 9928 5d/pop-to-ebp + 9929 c3/return + 9930 + 9931 test-address-with-wrong-type: + 9932 # . prologue + 9933 55/push-ebp + 9934 89/<- %ebp 4/r32/esp + 9935 # setup + 9936 (clear-stream _test-input-stream) + 9937 (clear-stream $_test-input-buffered-file->buffer) + 9938 (clear-stream _test-output-stream) + 9939 (clear-stream $_test-output-buffered-file->buffer) + 9940 (clear-stream _test-error-stream) + 9941 (clear-stream $_test-error-buffered-file->buffer) + 9942 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 9943 68/push 0/imm32 + 9944 68/push 0/imm32 + 9945 89/<- %edx 4/r32/esp + 9946 (tailor-exit-descriptor %edx 0x10) + 9947 # + 9948 (write _test-input-stream "fn foo {\n") + 9949 (write _test-input-stream " var x: int\n") + 9950 (write _test-input-stream " var y/eax: (addr boolean) <- address x\n") + 9951 (write _test-input-stream "}\n") + 9952 # convert + 9953 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 9954 # registers except esp clobbered at this point + 9955 # restore ed + 9956 89/<- %edx 4/r32/esp + 9957 (flush _test-output-buffered-file) + 9958 (flush _test-error-buffered-file) + 9959 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 9965 # check output + 9966 (check-stream-equal _test-output-stream "" "F - test-address-with-wrong-type: output should be empty") + 9967 (check-next-stream-line-equal _test-error-stream "fn foo: stmt address: output 'y' cannot hold address of 'x'" "F - test-address-with-wrong-type: error message") + 9968 # check that stop(1) was called + 9969 (check-ints-equal *(edx+4) 2 "F - test-address-with-wrong-type: exit status") + 9970 # don't restore from ebp + 9971 81 0/subop/add %esp 8/imm32 + 9972 # . epilogue 9973 5d/pop-to-ebp 9974 c3/return 9975 - 9976 test-address-with-right-type-for-stream: + 9976 test-address-with-right-type-for-array: 9977 # . prologue 9978 55/push-ebp 9979 89/<- %ebp 4/r32/esp @@ -9091,11 +9091,11 @@ if ('onhashchange' in window) { 9984 (clear-stream $_test-output-buffered-file->buffer) 9985 # 9986 (write _test-input-stream "fn foo {\n") - 9987 (write _test-input-stream " var x: (stream int 3)\n") - 9988 (write _test-input-stream " var y/eax: (addr stream int) <- address x\n") + 9987 (write _test-input-stream " var x: (array int 3)\n") + 9988 (write _test-input-stream " var y/eax: (addr array int) <- address x\n") 9989 (write _test-input-stream "}\n") 9990 # convert - 9991 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 9991 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 9992 (flush _test-output-buffered-file) 9993 # no errors 9994 # . epilogue @@ -9103,7 +9103,7 @@ if ('onhashchange' in window) { 9996 5d/pop-to-ebp 9997 c3/return 9998 - 9999 test-get-with-wrong-field: + 9999 test-address-with-right-type-for-stream: 10000 # . prologue 10001 55/push-ebp 10002 89/<- %ebp 4/r32/esp @@ -9112,3901 +9112,3901 @@ if ('onhashchange' in window) { 10005 (clear-stream $_test-input-buffered-file->buffer) 10006 (clear-stream _test-output-stream) 10007 (clear-stream $_test-output-buffered-file->buffer) -10008 (clear-stream _test-error-stream) -10009 (clear-stream $_test-error-buffered-file->buffer) -10010 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10011 68/push 0/imm32 -10012 68/push 0/imm32 -10013 89/<- %edx 4/r32/esp -10014 (tailor-exit-descriptor %edx 0x10) -10015 # -10016 (write _test-input-stream "fn foo {\n") -10017 (write _test-input-stream " var a: t\n") -10018 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") -10019 (write _test-input-stream "}\n") -10020 (write _test-input-stream "type t {\n") -10021 (write _test-input-stream " x: int\n") -10022 (write _test-input-stream "}\n") -10023 # convert -10024 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10025 # registers except esp clobbered at this point -10026 # restore ed -10027 89/<- %edx 4/r32/esp -10028 (flush _test-output-buffered-file) -10029 (flush _test-error-buffered-file) -10030 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10036 # check output -10037 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty") -10038 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'y'" "F - test-get-with-wrong-field: error message") -10039 # check that stop(1) was called -10040 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status") -10041 # don't restore from ebp -10042 81 0/subop/add %esp 8/imm32 -10043 # . epilogue -10044 5d/pop-to-ebp -10045 c3/return -10046 -10047 test-get-with-wrong-base-type: -10048 # . prologue -10049 55/push-ebp -10050 89/<- %ebp 4/r32/esp -10051 # setup -10052 (clear-stream _test-input-stream) -10053 (clear-stream $_test-input-buffered-file->buffer) -10054 (clear-stream _test-output-stream) -10055 (clear-stream $_test-output-buffered-file->buffer) -10056 (clear-stream _test-error-stream) -10057 (clear-stream $_test-error-buffered-file->buffer) -10058 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10059 68/push 0/imm32 -10060 68/push 0/imm32 -10061 89/<- %edx 4/r32/esp -10062 (tailor-exit-descriptor %edx 0x10) -10063 # -10064 (write _test-input-stream "fn foo {\n") -10065 (write _test-input-stream " var a: int\n") -10066 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") -10067 (write _test-input-stream "}\n") -10068 # convert -10069 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10070 # registers except esp clobbered at this point -10071 # restore ed -10072 89/<- %edx 4/r32/esp -10073 (flush _test-output-buffered-file) -10074 (flush _test-error-buffered-file) -10075 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10081 # check output -10082 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type: output should be empty") -10083 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' must have a 'type' definition" "F - test-get-with-wrong-base-type: error message") -10084 # check that stop(1) was called -10085 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status") -10086 # don't restore from ebp -10087 81 0/subop/add %esp 8/imm32 -10088 # . epilogue -10089 5d/pop-to-ebp -10090 c3/return -10091 -10092 test-get-with-wrong-base-type-2: -10093 # . prologue -10094 55/push-ebp -10095 89/<- %ebp 4/r32/esp -10096 # setup -10097 (clear-stream _test-input-stream) -10098 (clear-stream $_test-input-buffered-file->buffer) -10099 (clear-stream _test-output-stream) -10100 (clear-stream $_test-output-buffered-file->buffer) -10101 (clear-stream _test-error-stream) -10102 (clear-stream $_test-error-buffered-file->buffer) -10103 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10104 68/push 0/imm32 -10105 68/push 0/imm32 -10106 89/<- %edx 4/r32/esp -10107 (tailor-exit-descriptor %edx 0x10) -10108 # -10109 (write _test-input-stream "fn foo {\n") -10110 (write _test-input-stream " var a: (addr t)\n") -10111 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") -10112 (write _test-input-stream "}\n") -10113 (write _test-input-stream "type t {\n") -10114 (write _test-input-stream " x: int\n") -10115 (write _test-input-stream "}\n") -10116 # convert -10117 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10118 # registers except esp clobbered at this point -10119 # restore ed -10120 89/<- %edx 4/r32/esp -10121 (flush _test-output-buffered-file) -10122 (flush _test-error-buffered-file) -10123 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10129 # check output -10130 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-2: output should be empty") -10131 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' is an 'addr' type, and so must live in a register" "F - test-get-with-wrong-base-type-2: error message") -10132 # check that stop(1) was called -10133 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status") -10134 # don't restore from ebp -10135 81 0/subop/add %esp 8/imm32 -10136 # . epilogue -10137 5d/pop-to-ebp -10138 c3/return -10139 -10140 test-get-with-wrong-base-type-3: -10141 # . prologue -10142 55/push-ebp -10143 89/<- %ebp 4/r32/esp -10144 # setup -10145 (clear-stream _test-input-stream) -10146 (clear-stream $_test-input-buffered-file->buffer) -10147 (clear-stream _test-output-stream) -10148 (clear-stream $_test-output-buffered-file->buffer) -10149 (clear-stream _test-error-stream) -10150 (clear-stream $_test-error-buffered-file->buffer) -10151 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10152 68/push 0/imm32 -10153 68/push 0/imm32 -10154 89/<- %edx 4/r32/esp -10155 (tailor-exit-descriptor %edx 0x10) -10156 # -10157 (write _test-input-stream "fn foo {\n") -10158 (write _test-input-stream " var a: (handle int)\n") -10159 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") -10160 (write _test-input-stream "}\n") -10161 # convert -10162 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10163 # registers except esp clobbered at this point -10164 # restore ed -10165 89/<- %edx 4/r32/esp -10166 (flush _test-output-buffered-file) -10167 (flush _test-error-buffered-file) -10168 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10174 # check output -10175 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-3: output should be empty") -10176 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' must have a 'type' definition" "F - test-get-with-wrong-base-type-3: error message") -10177 # check that stop(1) was called -10178 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-3: exit status") -10179 # don't restore from ebp -10180 81 0/subop/add %esp 8/imm32 -10181 # . epilogue -10182 5d/pop-to-ebp -10183 c3/return -10184 -10185 test-get-with-wrong-offset-type: -10186 # . prologue -10187 55/push-ebp -10188 89/<- %ebp 4/r32/esp -10189 # setup -10190 (clear-stream _test-input-stream) -10191 (clear-stream $_test-input-buffered-file->buffer) -10192 (clear-stream _test-output-stream) -10193 (clear-stream $_test-output-buffered-file->buffer) -10194 (clear-stream _test-error-stream) -10195 (clear-stream $_test-error-buffered-file->buffer) -10196 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10197 68/push 0/imm32 -10198 68/push 0/imm32 -10199 89/<- %edx 4/r32/esp -10200 (tailor-exit-descriptor %edx 0x10) -10201 # -10202 (write _test-input-stream "fn foo {\n") -10203 (write _test-input-stream " var a: t\n") -10204 (write _test-input-stream " var b: int\n") -10205 (write _test-input-stream " var c/ecx: (addr int) <- get a, b\n") -10206 (write _test-input-stream "}\n") -10207 (write _test-input-stream "type t {\n") -10208 (write _test-input-stream " x: int\n") -10209 (write _test-input-stream "}\n") -10210 # convert -10211 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10212 # registers except esp clobbered at this point -10213 # restore ed -10214 89/<- %edx 4/r32/esp -10215 (flush _test-output-buffered-file) -10216 (flush _test-error-buffered-file) -10217 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10223 # check output -10224 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-offset-type: output should be empty") -10225 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'b'" "F - test-get-with-wrong-offset-type: error message") -10226 # check that stop(1) was called -10227 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: exit status") -10228 # don't restore from ebp -10229 81 0/subop/add %esp 8/imm32 -10230 # . epilogue -10231 5d/pop-to-ebp -10232 c3/return -10233 -10234 test-get-with-wrong-output-type: -10235 # . prologue -10236 55/push-ebp -10237 89/<- %ebp 4/r32/esp -10238 # setup -10239 (clear-stream _test-input-stream) -10240 (clear-stream $_test-input-buffered-file->buffer) -10241 (clear-stream _test-output-stream) -10242 (clear-stream $_test-output-buffered-file->buffer) -10243 (clear-stream _test-error-stream) -10244 (clear-stream $_test-error-buffered-file->buffer) -10245 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10246 68/push 0/imm32 -10247 68/push 0/imm32 -10248 89/<- %edx 4/r32/esp -10249 (tailor-exit-descriptor %edx 0x10) -10250 # -10251 (write _test-input-stream "fn foo {\n") -10252 (write _test-input-stream " var a: t\n") -10253 (write _test-input-stream " var c: (addr int)\n") -10254 (write _test-input-stream " c <- get a, x\n") -10255 (write _test-input-stream "}\n") -10256 (write _test-input-stream "type t {\n") -10257 (write _test-input-stream " x: int\n") -10258 (write _test-input-stream "}\n") -10259 # convert -10260 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10261 # registers except esp clobbered at this point -10262 # restore ed -10263 89/<- %edx 4/r32/esp -10264 (flush _test-output-buffered-file) -10265 (flush _test-error-buffered-file) -10266 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10272 # check output -10273 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type: output should be empty") -10274 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output 'c' is not in a register" "F - test-get-with-wrong-output-type: error message") -10275 # check that stop(1) was called -10276 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type: exit status") -10277 # don't restore from ebp -10278 81 0/subop/add %esp 8/imm32 -10279 # . epilogue -10280 5d/pop-to-ebp -10281 c3/return -10282 -10283 test-get-with-wrong-output-type-2: -10284 # . prologue -10285 55/push-ebp -10286 89/<- %ebp 4/r32/esp -10287 # setup -10288 (clear-stream _test-input-stream) -10289 (clear-stream $_test-input-buffered-file->buffer) -10290 (clear-stream _test-output-stream) -10291 (clear-stream $_test-output-buffered-file->buffer) -10292 (clear-stream _test-error-stream) -10293 (clear-stream $_test-error-buffered-file->buffer) -10294 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10295 68/push 0/imm32 -10296 68/push 0/imm32 -10297 89/<- %edx 4/r32/esp -10298 (tailor-exit-descriptor %edx 0x10) -10299 # -10300 (write _test-input-stream "fn foo {\n") -10301 (write _test-input-stream " var a: t\n") -10302 (write _test-input-stream " var c/ecx: int <- get a, x\n") -10303 (write _test-input-stream "}\n") -10304 (write _test-input-stream "type t {\n") -10305 (write _test-input-stream " x: int\n") -10306 (write _test-input-stream "}\n") -10307 # convert -10308 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10309 # registers except esp clobbered at this point -10310 # restore ed -10311 89/<- %edx 4/r32/esp -10312 (flush _test-output-buffered-file) -10313 (flush _test-error-buffered-file) -10314 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10320 # check output -10321 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-2: output should be empty") -10322 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an addr" "F - test-get-with-wrong-output-type-2: error message") -10323 # check that stop(1) was called -10324 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status") -10325 # don't restore from ebp -10326 81 0/subop/add %esp 8/imm32 -10327 # . epilogue -10328 5d/pop-to-ebp -10329 c3/return -10330 -10331 test-get-with-wrong-output-type-3: -10332 # . prologue -10333 55/push-ebp -10334 89/<- %ebp 4/r32/esp -10335 # setup -10336 (clear-stream _test-input-stream) -10337 (clear-stream $_test-input-buffered-file->buffer) -10338 (clear-stream _test-output-stream) -10339 (clear-stream $_test-output-buffered-file->buffer) -10340 (clear-stream _test-error-stream) -10341 (clear-stream $_test-error-buffered-file->buffer) -10342 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10343 68/push 0/imm32 -10344 68/push 0/imm32 -10345 89/<- %edx 4/r32/esp -10346 (tailor-exit-descriptor %edx 0x10) -10347 # -10348 (write _test-input-stream "fn foo {\n") -10349 (write _test-input-stream " var a: t\n") -10350 (write _test-input-stream " var c/ecx: (array int) <- get a, x\n") -10351 (write _test-input-stream "}\n") -10352 (write _test-input-stream "type t {\n") -10353 (write _test-input-stream " x: int\n") -10354 (write _test-input-stream "}\n") -10355 # convert -10356 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10357 # registers except esp clobbered at this point -10358 # restore ed -10359 89/<- %edx 4/r32/esp -10360 (flush _test-output-buffered-file) -10361 (flush _test-error-buffered-file) -10362 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10368 # check output -10369 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-3: output should be empty") -10370 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an addr" "F - test-get-with-wrong-output-type-3: error message") -10371 # check that stop(1) was called -10372 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status") -10373 # don't restore from ebp -10374 81 0/subop/add %esp 8/imm32 -10375 # . epilogue -10376 5d/pop-to-ebp -10377 c3/return -10378 -10379 test-get-with-wrong-output-type-4: -10380 # . prologue -10381 55/push-ebp -10382 89/<- %ebp 4/r32/esp -10383 # setup -10384 (clear-stream _test-input-stream) -10385 (clear-stream $_test-input-buffered-file->buffer) -10386 (clear-stream _test-output-stream) -10387 (clear-stream $_test-output-buffered-file->buffer) -10388 (clear-stream _test-error-stream) -10389 (clear-stream $_test-error-buffered-file->buffer) -10390 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10391 68/push 0/imm32 -10392 68/push 0/imm32 -10393 89/<- %edx 4/r32/esp -10394 (tailor-exit-descriptor %edx 0x10) -10395 # -10396 (write _test-input-stream "fn foo {\n") -10397 (write _test-input-stream " var a: t\n") -10398 (write _test-input-stream " var c/ecx: (addr boolean) <- get a, x\n") -10399 (write _test-input-stream "}\n") -10400 (write _test-input-stream "type t {\n") -10401 (write _test-input-stream " x: int\n") -10402 (write _test-input-stream "}\n") -10403 # convert -10404 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10405 # registers except esp clobbered at this point -10406 # restore ed -10407 89/<- %edx 4/r32/esp -10408 (flush _test-output-buffered-file) -10409 (flush _test-error-buffered-file) -10410 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10416 # check output -10417 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-4: output should be empty") -10418 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: wrong output type for member 'x' of type 't'" "F - test-get-with-wrong-output-type-4: error message") -10419 # check that stop(1) was called -10420 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status") -10421 # don't restore from ebp -10422 81 0/subop/add %esp 8/imm32 -10423 # . epilogue -10424 5d/pop-to-ebp -10425 c3/return -10426 -10427 test-get-with-wrong-output-type-5: -10428 # . prologue -10429 55/push-ebp -10430 89/<- %ebp 4/r32/esp -10431 # setup -10432 (clear-stream _test-input-stream) -10433 (clear-stream $_test-input-buffered-file->buffer) -10434 (clear-stream _test-output-stream) -10435 (clear-stream $_test-output-buffered-file->buffer) -10436 # -10437 (write _test-input-stream "fn foo {\n") -10438 (write _test-input-stream " var a: t\n") -10439 (write _test-input-stream " var c/ecx: (addr handle int) <- get a, x\n") -10440 (write _test-input-stream "}\n") -10441 (write _test-input-stream "type t {\n") -10442 (write _test-input-stream " x: (handle int)\n") -10443 (write _test-input-stream "}\n") -10444 # convert -10445 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -10446 (flush _test-output-buffered-file) -10447 # no errors -10448 # . epilogue -10449 89/<- %esp 5/r32/ebp -10450 5d/pop-to-ebp -10451 c3/return -10452 -10453 test-get-with-too-few-inouts: -10454 # . prologue -10455 55/push-ebp -10456 89/<- %ebp 4/r32/esp -10457 # setup -10458 (clear-stream _test-input-stream) -10459 (clear-stream $_test-input-buffered-file->buffer) -10460 (clear-stream _test-output-stream) -10461 (clear-stream $_test-output-buffered-file->buffer) -10462 (clear-stream _test-error-stream) -10463 (clear-stream $_test-error-buffered-file->buffer) -10464 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10465 68/push 0/imm32 -10466 68/push 0/imm32 -10467 89/<- %edx 4/r32/esp -10468 (tailor-exit-descriptor %edx 0x10) -10469 # -10470 (write _test-input-stream "fn foo {\n") -10471 (write _test-input-stream " var a: t\n") -10472 (write _test-input-stream " var c/ecx: (addr int) <- get a\n") -10473 (write _test-input-stream "}\n") -10474 (write _test-input-stream "type t {\n") -10475 (write _test-input-stream " x: int\n") -10476 (write _test-input-stream "}\n") -10477 # convert -10478 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10479 # registers except esp clobbered at this point -10480 # restore ed -10481 89/<- %edx 4/r32/esp -10482 (flush _test-output-buffered-file) -10483 (flush _test-error-buffered-file) -10484 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10490 # check output -10491 (check-stream-equal _test-output-stream "" "F - test-get-with-too-few-inouts: output should be empty") -10492 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too few inouts (2 required)" "F - test-get-with-too-few-inouts: error message") -10493 # check that stop(1) was called -10494 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-few-inouts: exit status") -10495 # don't restore from ebp -10496 81 0/subop/add %esp 8/imm32 -10497 # . epilogue -10498 5d/pop-to-ebp -10499 c3/return -10500 -10501 test-get-with-too-many-inouts: -10502 # . prologue -10503 55/push-ebp -10504 89/<- %ebp 4/r32/esp -10505 # setup -10506 (clear-stream _test-input-stream) -10507 (clear-stream $_test-input-buffered-file->buffer) -10508 (clear-stream _test-output-stream) -10509 (clear-stream $_test-output-buffered-file->buffer) -10510 (clear-stream _test-error-stream) -10511 (clear-stream $_test-error-buffered-file->buffer) -10512 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10513 68/push 0/imm32 -10514 68/push 0/imm32 -10515 89/<- %edx 4/r32/esp -10516 (tailor-exit-descriptor %edx 0x10) -10517 # -10518 (write _test-input-stream "fn foo {\n") -10519 (write _test-input-stream " var a: t\n") -10520 (write _test-input-stream " var c/ecx: (addr int) <- get a, x, 0\n") -10521 (write _test-input-stream "}\n") -10522 (write _test-input-stream "type t {\n") -10523 (write _test-input-stream " x: int\n") -10524 (write _test-input-stream "}\n") -10525 # convert -10526 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10527 # registers except esp clobbered at this point -10528 # restore ed -10529 89/<- %edx 4/r32/esp -10530 (flush _test-output-buffered-file) -10531 (flush _test-error-buffered-file) -10532 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10538 # check output -10539 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-inouts: output should be empty") -10540 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many inouts (2 required)" "F - test-get-with-too-many-inouts: error message") -10541 # check that stop(1) was called -10542 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-inouts: exit status") -10543 # don't restore from ebp -10544 81 0/subop/add %esp 8/imm32 -10545 # . epilogue -10546 5d/pop-to-ebp -10547 c3/return -10548 -10549 test-get-with-no-output: -10550 # . prologue -10551 55/push-ebp -10552 89/<- %ebp 4/r32/esp -10553 # setup -10554 (clear-stream _test-input-stream) -10555 (clear-stream $_test-input-buffered-file->buffer) -10556 (clear-stream _test-output-stream) -10557 (clear-stream $_test-output-buffered-file->buffer) -10558 (clear-stream _test-error-stream) -10559 (clear-stream $_test-error-buffered-file->buffer) -10560 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10561 68/push 0/imm32 -10562 68/push 0/imm32 -10563 89/<- %edx 4/r32/esp -10564 (tailor-exit-descriptor %edx 0x10) -10565 # -10566 (write _test-input-stream "fn foo {\n") -10567 (write _test-input-stream " var a: t\n") -10568 (write _test-input-stream " get a, x\n") -10569 (write _test-input-stream "}\n") -10570 (write _test-input-stream "type t {\n") -10571 (write _test-input-stream " x: int\n") -10572 (write _test-input-stream "}\n") -10573 # convert -10574 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10575 # registers except esp clobbered at this point -10576 # restore ed -10577 89/<- %edx 4/r32/esp -10578 (flush _test-output-buffered-file) -10579 (flush _test-error-buffered-file) -10580 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10586 # check output -10587 (check-stream-equal _test-output-stream "" "F - test-get-with-no-output: output should be empty") -10588 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: must have an output" "F - test-get-with-no-output: error message") -10589 # check that stop(1) was called -10590 (check-ints-equal *(edx+4) 2 "F - test-get-with-no-output: exit status") -10591 # don't restore from ebp -10592 81 0/subop/add %esp 8/imm32 -10593 # . epilogue -10594 5d/pop-to-ebp -10595 c3/return -10596 -10597 test-get-with-too-many-outputs: -10598 # . prologue -10599 55/push-ebp -10600 89/<- %ebp 4/r32/esp -10601 # setup -10602 (clear-stream _test-input-stream) -10603 (clear-stream $_test-input-buffered-file->buffer) -10604 (clear-stream _test-output-stream) -10605 (clear-stream $_test-output-buffered-file->buffer) -10606 (clear-stream _test-error-stream) -10607 (clear-stream $_test-error-buffered-file->buffer) -10608 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10609 68/push 0/imm32 -10610 68/push 0/imm32 -10611 89/<- %edx 4/r32/esp -10612 (tailor-exit-descriptor %edx 0x10) -10613 # -10614 (write _test-input-stream "fn foo {\n") -10615 (write _test-input-stream " var a: t\n") -10616 (write _test-input-stream " var b: int\n") -10617 (write _test-input-stream " var c/eax: (addr int) <- copy 0\n") -10618 (write _test-input-stream " c, b <- get a, x\n") -10619 (write _test-input-stream "}\n") -10620 (write _test-input-stream "type t {\n") -10621 (write _test-input-stream " x: int\n") -10622 (write _test-input-stream "}\n") -10623 # convert -10624 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10625 # registers except esp clobbered at this point -10626 # restore ed -10627 89/<- %edx 4/r32/esp -10628 (flush _test-output-buffered-file) -10629 (flush _test-error-buffered-file) -10630 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10636 # check output -10637 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-outputs: output should be empty") -10638 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many outputs (1 required)" "F - test-get-with-too-many-outputs: error message") -10639 # check that stop(1) was called -10640 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-outputs: exit status") -10641 # don't restore from ebp -10642 81 0/subop/add %esp 8/imm32 -10643 # . epilogue -10644 5d/pop-to-ebp -10645 c3/return -10646 -10647 test-convert-array-of-user-defined-types: -10648 # . prologue -10649 55/push-ebp -10650 89/<- %ebp 4/r32/esp -10651 # setup -10652 (clear-stream _test-input-stream) -10653 (clear-stream $_test-input-buffered-file->buffer) -10654 (clear-stream _test-output-stream) -10655 (clear-stream $_test-output-buffered-file->buffer) -10656 # -10657 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 -10658 (write _test-input-stream " x: int\n") -10659 (write _test-input-stream " y: int\n") -10660 (write _test-input-stream "}\n") -10661 (write _test-input-stream "fn foo {\n") -10662 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") -10663 (write _test-input-stream " var idx/ecx: int <- copy 3\n") -10664 (write _test-input-stream " var x/eax: (addr t) <- index arr, idx\n") -10665 (write _test-input-stream "}\n") -10666 # convert -10667 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -10668 (flush _test-output-buffered-file) -10669 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -10675 # check output -10676 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") -10677 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") -10678 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") -10679 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") -10680 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") -10681 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") -10682 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") -10683 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") -10684 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") -10685 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") -10686 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000008 *eax \"foo\" \"arr\")" "F - test-convert-array-of-user-defined-types/10") -10687 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-array-of-user-defined-types/12") -10688 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-array-of-user-defined-types/13") -10689 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000003 + 4) 0x00000000/r32" "F - test-convert-array-of-user-defined-types/14") -10690 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/15") -10691 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/16") -10692 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/17") -10693 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/18") -10694 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/19") -10695 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/20") -10696 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/21") -10697 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/22") -10698 # . epilogue -10699 89/<- %esp 5/r32/ebp -10700 5d/pop-to-ebp -10701 c3/return -10702 -10703 test-convert-length-of-array-of-user-defined-types-to-eax: -10704 # . prologue -10705 55/push-ebp -10706 89/<- %ebp 4/r32/esp -10707 # setup -10708 (clear-stream _test-input-stream) -10709 (clear-stream $_test-input-buffered-file->buffer) -10710 (clear-stream _test-output-stream) -10711 (clear-stream $_test-output-buffered-file->buffer) -10712 # -10713 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 -10714 (write _test-input-stream " x: int\n") -10715 (write _test-input-stream " y: int\n") -10716 (write _test-input-stream " z: int\n") -10717 (write _test-input-stream "}\n") -10718 (write _test-input-stream "fn foo {\n") -10719 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") -10720 (write _test-input-stream " var x/eax: int <- length arr\n") -10721 (write _test-input-stream "}\n") -10722 # convert -10723 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -10724 (flush _test-output-buffered-file) -10725 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -10731 # check output -10732 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") -10733 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") -10734 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") -10735 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/3") -10736 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") -10737 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") -10738 # var arr -10739 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/6") -10740 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/7") -10741 # length instruction -10742 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") -10743 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") -10744 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/10") -10745 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/11") -10746 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/12") -10747 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/13") -10748 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/14") -10749 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/15") -10750 # reclaim arr -10751 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/16") -10752 # -10753 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") -10754 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") -10755 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") -10756 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/20") -10757 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/21") -10758 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") -10759 # . epilogue -10760 89/<- %esp 5/r32/ebp -10761 5d/pop-to-ebp -10762 c3/return -10763 -10764 test-convert-length-of-array-of-user-defined-types-to-ecx: -10765 # . prologue -10766 55/push-ebp -10767 89/<- %ebp 4/r32/esp -10768 # setup -10769 (clear-stream _test-input-stream) -10770 (clear-stream $_test-input-buffered-file->buffer) -10771 (clear-stream _test-output-stream) -10772 (clear-stream $_test-output-buffered-file->buffer) -10773 # -10774 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 -10775 (write _test-input-stream " x: int\n") -10776 (write _test-input-stream " y: int\n") -10777 (write _test-input-stream " z: int\n") -10778 (write _test-input-stream "}\n") -10779 (write _test-input-stream "fn foo {\n") -10780 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") -10781 (write _test-input-stream " var x/ecx: int <- length arr\n") -10782 (write _test-input-stream "}\n") -10783 # convert -10784 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -10785 (flush _test-output-buffered-file) -10786 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -10792 # check output -10793 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") -10794 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") -10795 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") -10796 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/3") -10797 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") -10798 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") -10799 # var a -10800 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/6") -10801 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/7") -10802 # var x -10803 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/8") -10804 # length instruction -10805 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") -10806 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") -10807 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/11") -10808 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/12") -10809 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/13") -10810 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/14") -10811 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/15") -10812 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/16") -10813 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/17") -10814 # reclaim x -10815 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/18") -10816 # reclaim a -10817 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/19") -10818 # -10819 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") -10820 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") -10821 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") -10822 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/23") -10823 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/24") -10824 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") -10825 # . epilogue -10826 89/<- %esp 5/r32/ebp -10827 5d/pop-to-ebp -10828 c3/return -10829 -10830 test-convert-length-of-array-of-user-defined-types-to-edx: -10831 # . prologue -10832 55/push-ebp -10833 89/<- %ebp 4/r32/esp -10834 # setup -10835 (clear-stream _test-input-stream) -10836 (clear-stream $_test-input-buffered-file->buffer) -10837 (clear-stream _test-output-stream) -10838 (clear-stream $_test-output-buffered-file->buffer) -10839 # -10840 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 -10841 (write _test-input-stream " x: int\n") -10842 (write _test-input-stream " y: int\n") -10843 (write _test-input-stream " z: int\n") -10844 (write _test-input-stream "}\n") -10845 (write _test-input-stream "fn foo {\n") -10846 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") -10847 (write _test-input-stream " var x/edx: int <- length arr\n") -10848 (write _test-input-stream "}\n") -10849 # convert -10850 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -10851 (flush _test-output-buffered-file) -10852 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -10858 # check output -10859 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") -10860 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") -10861 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") -10862 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/3") -10863 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") -10864 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") -10865 # var a -10866 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/6") -10867 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/7") -10868 # var x -10869 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/8") -10870 # length instruction -10871 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") -10872 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") -10873 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/11") -10874 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/12") -10875 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/13") -10876 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/14") -10877 (check-next-stream-line-equal _test-output-stream " 89/<- %edx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/15") -10878 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/16") -10879 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/17") -10880 # reclaim x -10881 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/18") -10882 # reclaim a -10883 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/19") -10884 # -10885 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") -10886 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") -10887 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") -10888 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/23") -10889 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/24") -10890 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") -10891 # . epilogue -10892 89/<- %esp 5/r32/ebp -10893 5d/pop-to-ebp -10894 c3/return -10895 -10896 test-convert-length-of-array-of-user-defined-types: -10897 # . prologue -10898 55/push-ebp -10899 89/<- %ebp 4/r32/esp -10900 # setup -10901 (clear-stream _test-input-stream) -10902 (clear-stream $_test-input-buffered-file->buffer) -10903 (clear-stream _test-output-stream) -10904 (clear-stream $_test-output-buffered-file->buffer) -10905 # -10906 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 -10907 (write _test-input-stream " x: int\n") -10908 (write _test-input-stream " y: int\n") -10909 (write _test-input-stream " z: int\n") -10910 (write _test-input-stream "}\n") -10911 (write _test-input-stream "fn foo {\n") -10912 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") -10913 (write _test-input-stream " var x/ebx: int <- length arr\n") -10914 (write _test-input-stream "}\n") -10915 # convert -10916 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -10917 (flush _test-output-buffered-file) -10918 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -10924 # check output -10925 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") -10926 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") -10927 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") -10928 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") -10929 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") -10930 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") -10931 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") -10932 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types/7") -10933 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") -10934 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") -10935 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") -10936 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") -10937 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") -10938 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types/13") -10939 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types/14") -10940 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types/15") -10941 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") -10942 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") -10943 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") -10944 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") -10945 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") -10946 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") -10947 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") -10948 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") -10949 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") -10950 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") -10951 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") -10952 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") -10953 # . epilogue -10954 89/<- %esp 5/r32/ebp -10955 5d/pop-to-ebp -10956 c3/return -10957 -10958 test-index-with-non-array-atom-base-type: -10959 # . prologue -10960 55/push-ebp -10961 89/<- %ebp 4/r32/esp -10962 # setup -10963 (clear-stream _test-input-stream) -10964 (clear-stream $_test-input-buffered-file->buffer) -10965 (clear-stream _test-output-stream) -10966 (clear-stream $_test-output-buffered-file->buffer) -10967 (clear-stream _test-error-stream) -10968 (clear-stream $_test-error-buffered-file->buffer) -10969 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -10970 68/push 0/imm32 -10971 68/push 0/imm32 -10972 89/<- %edx 4/r32/esp -10973 (tailor-exit-descriptor %edx 0x10) -10974 # -10975 (write _test-input-stream "fn foo {\n") -10976 (write _test-input-stream " var a: int\n") -10977 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") -10978 (write _test-input-stream "}\n") -10979 # convert -10980 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -10981 # registers except esp clobbered at this point -10982 # restore ed -10983 89/<- %edx 4/r32/esp -10984 (flush _test-output-buffered-file) -10985 (flush _test-error-buffered-file) -10986 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -10992 # check output -10993 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-atom-base-type: output should be empty") -10994 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-atom-base-type: error message") -10995 # check that stop(1) was called -10996 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-atom-base-type: exit status") -10997 # don't restore from ebp -10998 81 0/subop/add %esp 8/imm32 -10999 # . epilogue -11000 5d/pop-to-ebp -11001 c3/return -11002 -11003 test-index-with-non-array-compound-base-type: -11004 # . prologue -11005 55/push-ebp -11006 89/<- %ebp 4/r32/esp -11007 # setup -11008 (clear-stream _test-input-stream) -11009 (clear-stream $_test-input-buffered-file->buffer) -11010 (clear-stream _test-output-stream) -11011 (clear-stream $_test-output-buffered-file->buffer) -11012 (clear-stream _test-error-stream) -11013 (clear-stream $_test-error-buffered-file->buffer) -11014 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11015 68/push 0/imm32 -11016 68/push 0/imm32 -11017 89/<- %edx 4/r32/esp -11018 (tailor-exit-descriptor %edx 0x10) -11019 # -11020 (write _test-input-stream "fn foo {\n") -11021 (write _test-input-stream " var a: (handle int)\n") -11022 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") -11023 (write _test-input-stream "}\n") -11024 # convert -11025 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11026 # registers except esp clobbered at this point -11027 # restore ed -11028 89/<- %edx 4/r32/esp -11029 (flush _test-output-buffered-file) -11030 (flush _test-error-buffered-file) -11031 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11037 # check output -11038 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-compound-base-type: output should be empty") -11039 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-compound-base-type: error message") -11040 # check that stop(1) was called -11041 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-compound-base-type: exit status") -11042 # don't restore from ebp -11043 81 0/subop/add %esp 8/imm32 -11044 # . epilogue -11045 5d/pop-to-ebp -11046 c3/return -11047 -11048 test-index-with-non-array-compound-base-type-2: -11049 # . prologue -11050 55/push-ebp -11051 89/<- %ebp 4/r32/esp -11052 # setup -11053 (clear-stream _test-input-stream) -11054 (clear-stream $_test-input-buffered-file->buffer) -11055 (clear-stream _test-output-stream) -11056 (clear-stream $_test-output-buffered-file->buffer) -11057 (clear-stream _test-error-stream) -11058 (clear-stream $_test-error-buffered-file->buffer) -11059 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11060 68/push 0/imm32 -11061 68/push 0/imm32 -11062 89/<- %edx 4/r32/esp -11063 (tailor-exit-descriptor %edx 0x10) -11064 # -11065 (write _test-input-stream "fn foo {\n") -11066 (write _test-input-stream " var a: (addr int)\n") -11067 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") -11068 (write _test-input-stream "}\n") -11069 # convert -11070 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11071 # registers except esp clobbered at this point -11072 # restore ed -11073 89/<- %edx 4/r32/esp -11074 (flush _test-output-buffered-file) -11075 (flush _test-error-buffered-file) -11076 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11082 # check output -11083 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-compound-base-type-2: output should be empty") -11084 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-compound-base-type-2: error message") -11085 # check that stop(1) was called -11086 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-compound-base-type-2: exit status") -11087 # don't restore from ebp -11088 81 0/subop/add %esp 8/imm32 -11089 # . epilogue -11090 5d/pop-to-ebp -11091 c3/return -11092 -11093 test-index-with-array-atom-base-type: -11094 # . prologue -11095 55/push-ebp -11096 89/<- %ebp 4/r32/esp -11097 # setup -11098 (clear-stream _test-input-stream) -11099 (clear-stream $_test-input-buffered-file->buffer) -11100 (clear-stream _test-output-stream) -11101 (clear-stream $_test-output-buffered-file->buffer) -11102 (clear-stream _test-error-stream) -11103 (clear-stream $_test-error-buffered-file->buffer) -11104 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11105 68/push 0/imm32 -11106 68/push 0/imm32 -11107 89/<- %edx 4/r32/esp -11108 (tailor-exit-descriptor %edx 0x10) -11109 # -11110 (write _test-input-stream "fn foo {\n") -11111 (write _test-input-stream " var a: array\n") -11112 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") -11113 (write _test-input-stream "}\n") -11114 # convert -11115 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11116 # registers except esp clobbered at this point -11117 # restore ed -11118 89/<- %edx 4/r32/esp -11119 (flush _test-output-buffered-file) -11120 (flush _test-error-buffered-file) -11121 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11127 # check output -11128 (check-stream-equal _test-output-stream "" "F - test-index-with-array-atom-base-type: output should be empty") -11129 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: array 'a' must specify the type of its elements" "F - test-index-with-array-atom-base-type: error message") -11130 # check that stop(1) was called -11131 (check-ints-equal *(edx+4) 2 "F - test-index-with-array-atom-base-type: exit status") -11132 # don't restore from ebp -11133 81 0/subop/add %esp 8/imm32 -11134 # . epilogue -11135 5d/pop-to-ebp -11136 c3/return -11137 -11138 test-index-with-addr-base-on-stack: -11139 # . prologue -11140 55/push-ebp -11141 89/<- %ebp 4/r32/esp -11142 # setup -11143 (clear-stream _test-input-stream) -11144 (clear-stream $_test-input-buffered-file->buffer) -11145 (clear-stream _test-output-stream) -11146 (clear-stream $_test-output-buffered-file->buffer) -11147 (clear-stream _test-error-stream) -11148 (clear-stream $_test-error-buffered-file->buffer) -11149 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11150 68/push 0/imm32 -11151 68/push 0/imm32 -11152 89/<- %edx 4/r32/esp -11153 (tailor-exit-descriptor %edx 0x10) -11154 # -11155 (write _test-input-stream "fn foo {\n") -11156 (write _test-input-stream " var a: (addr array int)\n") -11157 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") -11158 (write _test-input-stream "}\n") -11159 # convert -11160 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11161 # registers except esp clobbered at this point -11162 # restore ed -11163 89/<- %edx 4/r32/esp -11164 (flush _test-output-buffered-file) -11165 (flush _test-error-buffered-file) -11166 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11172 # check output -11173 (check-stream-equal _test-output-stream "" "F - test-index-with-addr-base-on-stack: output should be empty") -11174 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is an addr to an array, and so must live in a register" "F - test-index-with-addr-base-on-stack: error message") -11175 # check that stop(1) was called -11176 (check-ints-equal *(edx+4) 2 "F - test-index-with-addr-base-on-stack: exit status") -11177 # don't restore from ebp -11178 81 0/subop/add %esp 8/imm32 -11179 # . epilogue -11180 5d/pop-to-ebp -11181 c3/return -11182 -11183 test-index-with-wrong-index-type: -11184 # . prologue -11185 55/push-ebp -11186 89/<- %ebp 4/r32/esp -11187 # setup -11188 (clear-stream _test-input-stream) -11189 (clear-stream $_test-input-buffered-file->buffer) -11190 (clear-stream _test-output-stream) -11191 (clear-stream $_test-output-buffered-file->buffer) -11192 (clear-stream _test-error-stream) -11193 (clear-stream $_test-error-buffered-file->buffer) -11194 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11195 68/push 0/imm32 -11196 68/push 0/imm32 -11197 89/<- %edx 4/r32/esp -11198 (tailor-exit-descriptor %edx 0x10) -11199 # -11200 (write _test-input-stream "fn foo {\n") -11201 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") -11202 (write _test-input-stream " var b: boolean\n") -11203 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") -11204 (write _test-input-stream "}\n") -11205 # convert -11206 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11207 # registers except esp clobbered at this point -11208 # restore ed -11209 89/<- %edx 4/r32/esp -11210 (flush _test-output-buffered-file) -11211 (flush _test-error-buffered-file) -11212 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11218 # check output -11219 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-index-type: output should be empty") -11220 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: second argument 'b' must be an int or offset" "F - test-index-with-wrong-index-type: error message") -11221 # check that stop(1) was called -11222 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-index-type: exit status") -11223 # don't restore from ebp -11224 81 0/subop/add %esp 8/imm32 -11225 # . epilogue -11226 5d/pop-to-ebp -11227 c3/return -11228 -11229 test-index-with-offset-atom-index-type: -11230 # . prologue -11231 55/push-ebp -11232 89/<- %ebp 4/r32/esp -11233 # setup -11234 (clear-stream _test-input-stream) -11235 (clear-stream $_test-input-buffered-file->buffer) -11236 (clear-stream _test-output-stream) -11237 (clear-stream $_test-output-buffered-file->buffer) -11238 (clear-stream _test-error-stream) -11239 (clear-stream $_test-error-buffered-file->buffer) -11240 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11241 68/push 0/imm32 -11242 68/push 0/imm32 -11243 89/<- %edx 4/r32/esp -11244 (tailor-exit-descriptor %edx 0x10) -11245 # -11246 (write _test-input-stream "fn foo {\n") -11247 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") -11248 (write _test-input-stream " var b: offset\n") -11249 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") -11250 (write _test-input-stream "}\n") -11251 # convert -11252 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11253 # registers except esp clobbered at this point -11254 # restore ed -11255 89/<- %edx 4/r32/esp -11256 (flush _test-output-buffered-file) -11257 (flush _test-error-buffered-file) -11258 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11264 # check output -11265 (check-stream-equal _test-output-stream "" "F - test-index-with-offset-atom-index-type: output should be empty") -11266 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: offset 'b' must specify the type of array elements" "F - test-index-with-offset-atom-index-type: error message") -11267 # check that stop(1) was called -11268 (check-ints-equal *(edx+4) 2 "F - test-index-with-offset-atom-index-type: exit status") -11269 # don't restore from ebp -11270 81 0/subop/add %esp 8/imm32 -11271 # . epilogue -11272 5d/pop-to-ebp -11273 c3/return -11274 -11275 test-index-with-offset-on-stack: -11276 # . prologue -11277 55/push-ebp -11278 89/<- %ebp 4/r32/esp -11279 # setup -11280 (clear-stream _test-input-stream) -11281 (clear-stream $_test-input-buffered-file->buffer) -11282 (clear-stream _test-output-stream) -11283 (clear-stream $_test-output-buffered-file->buffer) -11284 (clear-stream _test-error-stream) -11285 (clear-stream $_test-error-buffered-file->buffer) -11286 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11287 68/push 0/imm32 -11288 68/push 0/imm32 -11289 89/<- %edx 4/r32/esp -11290 (tailor-exit-descriptor %edx 0x10) -11291 # -11292 (write _test-input-stream "fn foo {\n") -11293 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") -11294 (write _test-input-stream " var b: int\n") -11295 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") -11296 (write _test-input-stream "}\n") -11297 # convert -11298 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11299 # registers except esp clobbered at this point -11300 # restore ed -11301 89/<- %edx 4/r32/esp -11302 (flush _test-output-buffered-file) -11303 (flush _test-error-buffered-file) -11304 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11310 # check output -11311 (check-stream-equal _test-output-stream "" "F - test-index-with-offset-on-stack: output should be empty") -11312 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: second argument 'b' must be in a register" "F - test-index-with-offset-on-stack: error message") -11313 # check that stop(1) was called -11314 (check-ints-equal *(edx+4) 2 "F - test-index-with-offset-on-stack: exit status") -11315 # don't restore from ebp -11316 81 0/subop/add %esp 8/imm32 -11317 # . epilogue -11318 5d/pop-to-ebp -11319 c3/return -11320 -11321 test-index-needs-offset-type: -11322 # . prologue -11323 55/push-ebp -11324 89/<- %ebp 4/r32/esp -11325 # setup -11326 (clear-stream _test-input-stream) -11327 (clear-stream $_test-input-buffered-file->buffer) -11328 (clear-stream _test-output-stream) -11329 (clear-stream $_test-output-buffered-file->buffer) -11330 (clear-stream _test-error-stream) -11331 (clear-stream $_test-error-buffered-file->buffer) -11332 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11333 68/push 0/imm32 -11334 68/push 0/imm32 -11335 89/<- %edx 4/r32/esp -11336 (tailor-exit-descriptor %edx 0x10) -11337 # -11338 (write _test-input-stream "fn foo {\n") -11339 (write _test-input-stream " var a/eax: (addr array t) <- copy 0\n") -11340 (write _test-input-stream " var b/ebx: int <- copy 0\n") -11341 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") -11342 (write _test-input-stream "}\n") -11343 (write _test-input-stream "type t {\n") # size 12 is not a power of two -11344 (write _test-input-stream " x: int\n") -11345 (write _test-input-stream " y: int\n") -11346 (write _test-input-stream " z: int\n") -11347 (write _test-input-stream "}\n") -11348 # convert -11349 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11350 # registers except esp clobbered at this point -11351 # restore ed -11352 89/<- %edx 4/r32/esp -11353 (flush _test-output-buffered-file) -11354 (flush _test-error-buffered-file) -11355 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11361 # check output -11362 (check-stream-equal _test-output-stream "" "F - test-index-needs-offset-type: output should be empty") -11363 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: cannot take an int for array 'a'; create an offset instead. See mu.md for details." "F - test-index-needs-offset-type: error message") -11364 # check that stop(1) was called -11365 (check-ints-equal *(edx+4) 2 "F - test-index-needs-offset-type: exit status") -11366 # don't restore from ebp -11367 81 0/subop/add %esp 8/imm32 -11368 # . epilogue -11369 5d/pop-to-ebp -11370 c3/return -11371 -11372 test-index-with-output-not-address: -11373 # . prologue -11374 55/push-ebp -11375 89/<- %ebp 4/r32/esp -11376 # setup -11377 (clear-stream _test-input-stream) -11378 (clear-stream $_test-input-buffered-file->buffer) -11379 (clear-stream _test-output-stream) -11380 (clear-stream $_test-output-buffered-file->buffer) -11381 (clear-stream _test-error-stream) -11382 (clear-stream $_test-error-buffered-file->buffer) -11383 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11384 68/push 0/imm32 -11385 68/push 0/imm32 -11386 89/<- %edx 4/r32/esp -11387 (tailor-exit-descriptor %edx 0x10) -11388 # -11389 (write _test-input-stream "fn foo {\n") -11390 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") -11391 (write _test-input-stream " var o/edi: int <- index a, 0\n") -11392 (write _test-input-stream "}\n") -11393 # convert -11394 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11395 # registers except esp clobbered at this point -11396 # restore ed -11397 89/<- %edx 4/r32/esp -11398 (flush _test-output-buffered-file) -11399 (flush _test-error-buffered-file) -11400 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11406 # check output -11407 (check-stream-equal _test-output-stream "" "F - test-index-with-output-not-address: output should be empty") -11408 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' must be an addr" "F - test-index-with-output-not-address: error message") -11409 # check that stop(1) was called -11410 (check-ints-equal *(edx+4) 2 "F - test-index-with-output-not-address: exit status") -11411 # don't restore from ebp -11412 81 0/subop/add %esp 8/imm32 -11413 # . epilogue -11414 5d/pop-to-ebp -11415 c3/return -11416 -11417 test-index-with-output-not-address-2: -11418 # . prologue -11419 55/push-ebp -11420 89/<- %ebp 4/r32/esp -11421 # setup -11422 (clear-stream _test-input-stream) -11423 (clear-stream $_test-input-buffered-file->buffer) -11424 (clear-stream _test-output-stream) -11425 (clear-stream $_test-output-buffered-file->buffer) -11426 (clear-stream _test-error-stream) -11427 (clear-stream $_test-error-buffered-file->buffer) -11428 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11429 68/push 0/imm32 -11430 68/push 0/imm32 -11431 89/<- %edx 4/r32/esp -11432 (tailor-exit-descriptor %edx 0x10) -11433 # -11434 (write _test-input-stream "fn foo {\n") -11435 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") -11436 (write _test-input-stream " var o/edi: (int) <- index a, 0\n") -11437 (write _test-input-stream "}\n") -11438 # convert -11439 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11440 # registers except esp clobbered at this point -11441 # restore ed -11442 89/<- %edx 4/r32/esp -11443 (flush _test-output-buffered-file) -11444 (flush _test-error-buffered-file) -11445 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11451 # check output -11452 (check-stream-equal _test-output-stream "" "F - test-index-with-output-not-address-2: output should be empty") -11453 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' must be an addr" "F - test-index-with-output-not-address-2: error message") -11454 # check that stop(1) was called -11455 (check-ints-equal *(edx+4) 2 "F - test-index-with-output-not-address-2: exit status") -11456 # don't restore from ebp -11457 81 0/subop/add %esp 8/imm32 -11458 # . epilogue -11459 5d/pop-to-ebp -11460 c3/return -11461 -11462 test-index-with-wrong-output-type: -11463 # . prologue -11464 55/push-ebp -11465 89/<- %ebp 4/r32/esp -11466 # setup -11467 (clear-stream _test-input-stream) -11468 (clear-stream $_test-input-buffered-file->buffer) -11469 (clear-stream _test-output-stream) -11470 (clear-stream $_test-output-buffered-file->buffer) -11471 (clear-stream _test-error-stream) -11472 (clear-stream $_test-error-buffered-file->buffer) -11473 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11474 68/push 0/imm32 -11475 68/push 0/imm32 -11476 89/<- %edx 4/r32/esp -11477 (tailor-exit-descriptor %edx 0x10) -11478 # -11479 (write _test-input-stream "fn foo {\n") -11480 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") -11481 (write _test-input-stream " var o/edi: (addr int) <- index a, 0\n") -11482 (write _test-input-stream "}\n") -11483 # convert -11484 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11485 # registers except esp clobbered at this point -11486 # restore ed -11487 89/<- %edx 4/r32/esp -11488 (flush _test-output-buffered-file) -11489 (flush _test-error-buffered-file) -11490 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11496 # check output -11497 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-output-type: output should be empty") -11498 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' does not have the right type" "F - test-index-with-wrong-output-type: error message") -11499 # check that stop(1) was called -11500 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-output-type: exit status") -11501 # don't restore from ebp -11502 81 0/subop/add %esp 8/imm32 -11503 # . epilogue -11504 5d/pop-to-ebp -11505 c3/return -11506 -11507 test-index-with-wrong-output-compound-type: -11508 # . prologue -11509 55/push-ebp -11510 89/<- %ebp 4/r32/esp -11511 # setup -11512 (clear-stream _test-input-stream) -11513 (clear-stream $_test-input-buffered-file->buffer) -11514 (clear-stream _test-output-stream) -11515 (clear-stream $_test-output-buffered-file->buffer) -11516 (clear-stream _test-error-stream) -11517 (clear-stream $_test-error-buffered-file->buffer) -11518 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11519 68/push 0/imm32 -11520 68/push 0/imm32 -11521 89/<- %edx 4/r32/esp -11522 (tailor-exit-descriptor %edx 0x10) -11523 # -11524 (write _test-input-stream "fn foo {\n") -11525 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n") -11526 (write _test-input-stream " var o/edi: (addr handle int) <- index a, 0\n") -11527 (write _test-input-stream "}\n") -11528 # convert -11529 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11530 # registers except esp clobbered at this point -11531 # restore ed -11532 89/<- %edx 4/r32/esp -11533 (flush _test-output-buffered-file) -11534 (flush _test-error-buffered-file) -11535 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11541 # check output -11542 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-output-compound-type: output should be empty") -11543 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' does not have the right type" "F - test-index-with-wrong-output-compound-type: error message") -11544 # check that stop(1) was called -11545 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-output-compound-type: exit status") -11546 # don't restore from ebp -11547 81 0/subop/add %esp 8/imm32 -11548 # . epilogue -11549 5d/pop-to-ebp -11550 c3/return -11551 -11552 test-index-with-no-inouts: -11553 # . prologue -11554 55/push-ebp -11555 89/<- %ebp 4/r32/esp -11556 # setup -11557 (clear-stream _test-input-stream) -11558 (clear-stream $_test-input-buffered-file->buffer) -11559 (clear-stream _test-output-stream) -11560 (clear-stream $_test-output-buffered-file->buffer) -11561 (clear-stream _test-error-stream) -11562 (clear-stream $_test-error-buffered-file->buffer) -11563 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11564 68/push 0/imm32 -11565 68/push 0/imm32 -11566 89/<- %edx 4/r32/esp -11567 (tailor-exit-descriptor %edx 0x10) -11568 # -11569 (write _test-input-stream "fn foo {\n") -11570 (write _test-input-stream " var c/ecx: (addr int) <- index\n") -11571 (write _test-input-stream "}\n") -11572 # convert -11573 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11574 # registers except esp clobbered at this point -11575 # restore ed -11576 89/<- %edx 4/r32/esp -11577 (flush _test-output-buffered-file) -11578 (flush _test-error-buffered-file) -11579 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11585 # check output -11586 (check-stream-equal _test-output-stream "" "F - test-index-with-no-inouts: output should be empty") -11587 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too few inouts (2 required)" "F - test-index-with-no-inouts: error message") -11588 # check that stop(1) was called -11589 (check-ints-equal *(edx+4) 2 "F - test-index-with-no-inouts: exit status") -11590 # don't restore from ebp -11591 81 0/subop/add %esp 8/imm32 -11592 # . epilogue -11593 5d/pop-to-ebp -11594 c3/return -11595 -11596 test-index-with-too-few-inouts: -11597 # . prologue -11598 55/push-ebp -11599 89/<- %ebp 4/r32/esp -11600 # setup -11601 (clear-stream _test-input-stream) -11602 (clear-stream $_test-input-buffered-file->buffer) -11603 (clear-stream _test-output-stream) -11604 (clear-stream $_test-output-buffered-file->buffer) -11605 (clear-stream _test-error-stream) -11606 (clear-stream $_test-error-buffered-file->buffer) -11607 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11608 68/push 0/imm32 -11609 68/push 0/imm32 -11610 89/<- %edx 4/r32/esp -11611 (tailor-exit-descriptor %edx 0x10) -11612 # -11613 (write _test-input-stream "fn foo {\n") -11614 (write _test-input-stream " var a: (array int 3)\n") -11615 (write _test-input-stream " var c/ecx: (addr int) <- index a\n") -11616 (write _test-input-stream "}\n") -11617 # convert -11618 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11619 # registers except esp clobbered at this point -11620 # restore ed -11621 89/<- %edx 4/r32/esp -11622 (flush _test-output-buffered-file) -11623 (flush _test-error-buffered-file) -11624 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11630 # check output -11631 (check-stream-equal _test-output-stream "" "F - test-index-with-too-few-inouts: output should be empty") -11632 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too few inouts (2 required)" "F - test-index-with-too-few-inouts: error message") -11633 # check that stop(1) was called -11634 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-few-inouts: exit status") -11635 # don't restore from ebp -11636 81 0/subop/add %esp 8/imm32 -11637 # . epilogue -11638 5d/pop-to-ebp -11639 c3/return -11640 -11641 test-index-with-too-many-inouts: -11642 # . prologue -11643 55/push-ebp -11644 89/<- %ebp 4/r32/esp -11645 # setup -11646 (clear-stream _test-input-stream) -11647 (clear-stream $_test-input-buffered-file->buffer) -11648 (clear-stream _test-output-stream) -11649 (clear-stream $_test-output-buffered-file->buffer) -11650 (clear-stream _test-error-stream) -11651 (clear-stream $_test-error-buffered-file->buffer) -11652 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11653 68/push 0/imm32 -11654 68/push 0/imm32 -11655 89/<- %edx 4/r32/esp -11656 (tailor-exit-descriptor %edx 0x10) -11657 # -11658 (write _test-input-stream "fn foo {\n") -11659 (write _test-input-stream " var a: (array int 3)\n") -11660 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0, 0\n") -11661 (write _test-input-stream "}\n") -11662 # convert -11663 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11664 # registers except esp clobbered at this point -11665 # restore ed -11666 89/<- %edx 4/r32/esp -11667 (flush _test-output-buffered-file) -11668 (flush _test-error-buffered-file) -11669 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11675 # check output -11676 (check-stream-equal _test-output-stream "" "F - test-index-with-too-many-inouts: output should be empty") -11677 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too many inouts (2 required)" "F - test-index-with-too-many-inouts: error message") -11678 # check that stop(1) was called -11679 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-many-inouts: exit status") -11680 # don't restore from ebp -11681 81 0/subop/add %esp 8/imm32 -11682 # . epilogue -11683 5d/pop-to-ebp -11684 c3/return -11685 -11686 test-index-with-no-output: -11687 # . prologue -11688 55/push-ebp -11689 89/<- %ebp 4/r32/esp -11690 # setup -11691 (clear-stream _test-input-stream) -11692 (clear-stream $_test-input-buffered-file->buffer) -11693 (clear-stream _test-output-stream) -11694 (clear-stream $_test-output-buffered-file->buffer) -11695 (clear-stream _test-error-stream) -11696 (clear-stream $_test-error-buffered-file->buffer) -11697 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11698 68/push 0/imm32 -11699 68/push 0/imm32 -11700 89/<- %edx 4/r32/esp -11701 (tailor-exit-descriptor %edx 0x10) -11702 # -11703 (write _test-input-stream "fn foo {\n") -11704 (write _test-input-stream " var a: (array int 3)\n") -11705 (write _test-input-stream " index a, 0\n") -11706 (write _test-input-stream "}\n") -11707 # convert -11708 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11709 # registers except esp clobbered at this point -11710 # restore ed -11711 89/<- %edx 4/r32/esp -11712 (flush _test-output-buffered-file) -11713 (flush _test-error-buffered-file) -11714 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11720 # check output -11721 (check-stream-equal _test-output-stream "" "F - test-index-with-no-output: output should be empty") -11722 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: must have an output" "F - test-index-with-no-output: error message") -11723 # check that stop(1) was called -11724 (check-ints-equal *(edx+4) 2 "F - test-index-with-no-output: exit status") -11725 # don't restore from ebp -11726 81 0/subop/add %esp 8/imm32 -11727 # . epilogue -11728 5d/pop-to-ebp -11729 c3/return -11730 -11731 test-index-with-too-many-outputs: -11732 # . prologue -11733 55/push-ebp -11734 89/<- %ebp 4/r32/esp -11735 # setup -11736 (clear-stream _test-input-stream) -11737 (clear-stream $_test-input-buffered-file->buffer) -11738 (clear-stream _test-output-stream) -11739 (clear-stream $_test-output-buffered-file->buffer) -11740 (clear-stream _test-error-stream) -11741 (clear-stream $_test-error-buffered-file->buffer) -11742 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11743 68/push 0/imm32 -11744 68/push 0/imm32 -11745 89/<- %edx 4/r32/esp -11746 (tailor-exit-descriptor %edx 0x10) -11747 # -11748 (write _test-input-stream "fn foo {\n") -11749 (write _test-input-stream " var a: (array int 3)\n") -11750 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n") -11751 (write _test-input-stream " var c/ecx: (addr int) <- copy 0\n") -11752 (write _test-input-stream " b, c <- index a, 0\n") -11753 (write _test-input-stream "}\n") -11754 # convert -11755 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11756 # registers except esp clobbered at this point -11757 # restore ed -11758 89/<- %edx 4/r32/esp -11759 (flush _test-output-buffered-file) -11760 (flush _test-error-buffered-file) -11761 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11767 # check output -11768 (check-stream-equal _test-output-stream "" "F - test-index-with-too-many-outputs: output should be empty") -11769 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too many outputs (1 required)" "F - test-index-with-too-many-outputs: error message") -11770 # check that stop(1) was called -11771 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-many-outputs: exit status") -11772 # don't restore from ebp -11773 81 0/subop/add %esp 8/imm32 -11774 # . epilogue -11775 5d/pop-to-ebp -11776 c3/return -11777 -11778 test-compute-offset-with-non-array-atom-base-type: -11779 # . prologue -11780 55/push-ebp -11781 89/<- %ebp 4/r32/esp -11782 # setup -11783 (clear-stream _test-input-stream) -11784 (clear-stream $_test-input-buffered-file->buffer) -11785 (clear-stream _test-output-stream) -11786 (clear-stream $_test-output-buffered-file->buffer) -11787 (clear-stream _test-error-stream) -11788 (clear-stream $_test-error-buffered-file->buffer) -11789 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11790 68/push 0/imm32 -11791 68/push 0/imm32 -11792 89/<- %edx 4/r32/esp -11793 (tailor-exit-descriptor %edx 0x10) -11794 # -11795 (write _test-input-stream "fn foo {\n") -11796 (write _test-input-stream " var a: int\n") -11797 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n") -11798 (write _test-input-stream "}\n") -11799 # convert -11800 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11801 # registers except esp clobbered at this point -11802 # restore ed -11803 89/<- %edx 4/r32/esp -11804 (flush _test-output-buffered-file) -11805 (flush _test-error-buffered-file) -11806 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11812 # check output -11813 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-atom-base-type: output should be empty") -11814 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-atom-base-type: error message") -11815 # check that stop(1) was called -11816 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-atom-base-type: exit status") -11817 # don't restore from ebp -11818 81 0/subop/add %esp 8/imm32 -11819 # . epilogue -11820 5d/pop-to-ebp -11821 c3/return -11822 -11823 test-compute-offset-with-non-array-compound-base-type: -11824 # . prologue -11825 55/push-ebp -11826 89/<- %ebp 4/r32/esp -11827 # setup -11828 (clear-stream _test-input-stream) -11829 (clear-stream $_test-input-buffered-file->buffer) -11830 (clear-stream _test-output-stream) -11831 (clear-stream $_test-output-buffered-file->buffer) -11832 (clear-stream _test-error-stream) -11833 (clear-stream $_test-error-buffered-file->buffer) -11834 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11835 68/push 0/imm32 -11836 68/push 0/imm32 -11837 89/<- %edx 4/r32/esp -11838 (tailor-exit-descriptor %edx 0x10) -11839 # -11840 (write _test-input-stream "fn foo {\n") -11841 (write _test-input-stream " var a: (handle int)\n") -11842 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n") -11843 (write _test-input-stream "}\n") -11844 # convert -11845 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11846 # registers except esp clobbered at this point -11847 # restore ed -11848 89/<- %edx 4/r32/esp -11849 (flush _test-output-buffered-file) -11850 (flush _test-error-buffered-file) -11851 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11857 # check output -11858 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-compound-base-type: output should be empty") -11859 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-compound-base-type: error message") -11860 # check that stop(1) was called -11861 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-compound-base-type: exit status") -11862 # don't restore from ebp -11863 81 0/subop/add %esp 8/imm32 -11864 # . epilogue -11865 5d/pop-to-ebp -11866 c3/return -11867 -11868 test-compute-offset-with-non-array-compound-base-type-2: -11869 # . prologue -11870 55/push-ebp -11871 89/<- %ebp 4/r32/esp -11872 # setup -11873 (clear-stream _test-input-stream) -11874 (clear-stream $_test-input-buffered-file->buffer) -11875 (clear-stream _test-output-stream) -11876 (clear-stream $_test-output-buffered-file->buffer) -11877 (clear-stream _test-error-stream) -11878 (clear-stream $_test-error-buffered-file->buffer) -11879 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11880 68/push 0/imm32 -11881 68/push 0/imm32 -11882 89/<- %edx 4/r32/esp -11883 (tailor-exit-descriptor %edx 0x10) -11884 # -11885 (write _test-input-stream "fn foo {\n") -11886 (write _test-input-stream " var a: (addr int)\n") -11887 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n") -11888 (write _test-input-stream "}\n") -11889 # convert -11890 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11891 # registers except esp clobbered at this point -11892 # restore ed -11893 89/<- %edx 4/r32/esp -11894 (flush _test-output-buffered-file) -11895 (flush _test-error-buffered-file) -11896 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11902 # check output -11903 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-compound-base-type-2: output should be empty") -11904 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-compound-base-type-2: error message") -11905 # check that stop(1) was called -11906 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-compound-base-type-2: exit status") -11907 # don't restore from ebp -11908 81 0/subop/add %esp 8/imm32 -11909 # . epilogue -11910 5d/pop-to-ebp -11911 c3/return -11912 -11913 test-compute-offset-with-array-atom-base-type: -11914 # . prologue -11915 55/push-ebp -11916 89/<- %ebp 4/r32/esp -11917 # setup -11918 (clear-stream _test-input-stream) -11919 (clear-stream $_test-input-buffered-file->buffer) -11920 (clear-stream _test-output-stream) -11921 (clear-stream $_test-output-buffered-file->buffer) -11922 (clear-stream _test-error-stream) -11923 (clear-stream $_test-error-buffered-file->buffer) -11924 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11925 68/push 0/imm32 -11926 68/push 0/imm32 -11927 89/<- %edx 4/r32/esp -11928 (tailor-exit-descriptor %edx 0x10) -11929 # -11930 (write _test-input-stream "fn foo {\n") -11931 (write _test-input-stream " var a: array\n") -11932 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n") -11933 (write _test-input-stream "}\n") -11934 # convert -11935 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11936 # registers except esp clobbered at this point -11937 # restore ed -11938 89/<- %edx 4/r32/esp -11939 (flush _test-output-buffered-file) -11940 (flush _test-error-buffered-file) -11941 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11947 # check output -11948 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-array-atom-base-type: output should be empty") -11949 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: array 'a' must specify the type of its elements" "F - test-compute-offset-with-array-atom-base-type: error message") -11950 # check that stop(1) was called -11951 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-array-atom-base-type: exit status") -11952 # don't restore from ebp -11953 81 0/subop/add %esp 8/imm32 -11954 # . epilogue -11955 5d/pop-to-ebp -11956 c3/return -11957 -11958 test-compute-offset-with-wrong-index-type: -11959 # . prologue -11960 55/push-ebp -11961 89/<- %ebp 4/r32/esp -11962 # setup -11963 (clear-stream _test-input-stream) -11964 (clear-stream $_test-input-buffered-file->buffer) -11965 (clear-stream _test-output-stream) -11966 (clear-stream $_test-output-buffered-file->buffer) -11967 (clear-stream _test-error-stream) -11968 (clear-stream $_test-error-buffered-file->buffer) -11969 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -11970 68/push 0/imm32 -11971 68/push 0/imm32 -11972 89/<- %edx 4/r32/esp -11973 (tailor-exit-descriptor %edx 0x10) -11974 # -11975 (write _test-input-stream "fn foo {\n") -11976 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") -11977 (write _test-input-stream " var b: boolean\n") -11978 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, b\n") -11979 (write _test-input-stream "}\n") -11980 # convert -11981 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -11982 # registers except esp clobbered at this point -11983 # restore ed -11984 89/<- %edx 4/r32/esp -11985 (flush _test-output-buffered-file) -11986 (flush _test-error-buffered-file) -11987 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -11993 # check output -11994 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-index-type: output should be empty") -11995 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: second argument 'b' must be an int" "F - test-compute-offset-with-wrong-index-type: error message") -11996 # check that stop(1) was called -11997 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-index-type: exit status") -11998 # don't restore from ebp -11999 81 0/subop/add %esp 8/imm32 -12000 # . epilogue -12001 5d/pop-to-ebp -12002 c3/return -12003 -12004 test-compute-offset-with-output-not-offset: -12005 # . prologue -12006 55/push-ebp -12007 89/<- %ebp 4/r32/esp -12008 # setup -12009 (clear-stream _test-input-stream) -12010 (clear-stream $_test-input-buffered-file->buffer) -12011 (clear-stream _test-output-stream) -12012 (clear-stream $_test-output-buffered-file->buffer) -12013 (clear-stream _test-error-stream) -12014 (clear-stream $_test-error-buffered-file->buffer) -12015 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12016 68/push 0/imm32 -12017 68/push 0/imm32 -12018 89/<- %edx 4/r32/esp -12019 (tailor-exit-descriptor %edx 0x10) -12020 # -12021 (write _test-input-stream "fn foo {\n") -12022 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") -12023 (write _test-input-stream " var o/edi: int <- compute-offset a, 0\n") -12024 (write _test-input-stream "}\n") -12025 # convert -12026 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12027 # registers except esp clobbered at this point -12028 # restore ed -12029 89/<- %edx 4/r32/esp -12030 (flush _test-output-buffered-file) -12031 (flush _test-error-buffered-file) -12032 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12038 # check output -12039 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-output-not-offset: output should be empty") -12040 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' must be an offset" "F - test-compute-offset-with-output-not-offset: error message") -12041 # check that stop(1) was called -12042 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-output-not-offset: exit status") -12043 # don't restore from ebp -12044 81 0/subop/add %esp 8/imm32 -12045 # . epilogue -12046 5d/pop-to-ebp -12047 c3/return -12048 -12049 test-compute-offset-with-output-not-address-2: -12050 # . prologue -12051 55/push-ebp -12052 89/<- %ebp 4/r32/esp -12053 # setup -12054 (clear-stream _test-input-stream) -12055 (clear-stream $_test-input-buffered-file->buffer) -12056 (clear-stream _test-output-stream) -12057 (clear-stream $_test-output-buffered-file->buffer) -12058 (clear-stream _test-error-stream) -12059 (clear-stream $_test-error-buffered-file->buffer) -12060 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12061 68/push 0/imm32 -12062 68/push 0/imm32 -12063 89/<- %edx 4/r32/esp -12064 (tailor-exit-descriptor %edx 0x10) -12065 # -12066 (write _test-input-stream "fn foo {\n") -12067 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") -12068 (write _test-input-stream " var o/edi: (int) <- compute-offset a, 0\n") -12069 (write _test-input-stream "}\n") -12070 # convert -12071 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12072 # registers except esp clobbered at this point -12073 # restore ed -12074 89/<- %edx 4/r32/esp -12075 (flush _test-output-buffered-file) -12076 (flush _test-error-buffered-file) -12077 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12083 # check output -12084 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-output-not-address-2: output should be empty") -12085 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' must be an offset" "F - test-compute-offset-with-output-not-address-2: error message") -12086 # check that stop(1) was called -12087 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-output-not-address-2: exit status") -12088 # don't restore from ebp -12089 81 0/subop/add %esp 8/imm32 -12090 # . epilogue -12091 5d/pop-to-ebp -12092 c3/return -12093 -12094 test-compute-offset-with-wrong-output-type: -12095 # . prologue -12096 55/push-ebp -12097 89/<- %ebp 4/r32/esp -12098 # setup -12099 (clear-stream _test-input-stream) -12100 (clear-stream $_test-input-buffered-file->buffer) -12101 (clear-stream _test-output-stream) -12102 (clear-stream $_test-output-buffered-file->buffer) -12103 (clear-stream _test-error-stream) -12104 (clear-stream $_test-error-buffered-file->buffer) -12105 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12106 68/push 0/imm32 -12107 68/push 0/imm32 -12108 89/<- %edx 4/r32/esp -12109 (tailor-exit-descriptor %edx 0x10) -12110 # -12111 (write _test-input-stream "fn foo {\n") -12112 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") -12113 (write _test-input-stream " var o/edi: (offset int) <- compute-offset a, 0\n") -12114 (write _test-input-stream "}\n") -12115 # convert -12116 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12117 # registers except esp clobbered at this point -12118 # restore ed -12119 89/<- %edx 4/r32/esp -12120 (flush _test-output-buffered-file) -12121 (flush _test-error-buffered-file) -12122 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12128 # check output -12129 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-output-type: output should be empty") -12130 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' does not have the right type" "F - test-compute-offset-with-wrong-output-type: error message") -12131 # check that stop(1) was called -12132 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-output-type: exit status") -12133 # don't restore from ebp -12134 81 0/subop/add %esp 8/imm32 -12135 # . epilogue -12136 5d/pop-to-ebp -12137 c3/return -12138 -12139 test-compute-offset-with-wrong-output-compound-type: -12140 # . prologue -12141 55/push-ebp -12142 89/<- %ebp 4/r32/esp -12143 # setup -12144 (clear-stream _test-input-stream) -12145 (clear-stream $_test-input-buffered-file->buffer) -12146 (clear-stream _test-output-stream) -12147 (clear-stream $_test-output-buffered-file->buffer) -12148 (clear-stream _test-error-stream) -12149 (clear-stream $_test-error-buffered-file->buffer) -12150 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12151 68/push 0/imm32 -12152 68/push 0/imm32 -12153 89/<- %edx 4/r32/esp -12154 (tailor-exit-descriptor %edx 0x10) -12155 # -12156 (write _test-input-stream "fn foo {\n") -12157 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n") -12158 (write _test-input-stream " var o/edi: (offset handle int) <- compute-offset a, 0\n") -12159 (write _test-input-stream "}\n") -12160 # convert -12161 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12162 # registers except esp clobbered at this point -12163 # restore ed -12164 89/<- %edx 4/r32/esp -12165 (flush _test-output-buffered-file) -12166 (flush _test-error-buffered-file) -12167 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12173 # check output -12174 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-output-compound-type: output should be empty") -12175 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' does not have the right type" "F - test-compute-offset-with-wrong-output-compound-type: error message") -12176 # check that stop(1) was called -12177 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-output-compound-type: exit status") -12178 # don't restore from ebp -12179 81 0/subop/add %esp 8/imm32 -12180 # . epilogue -12181 5d/pop-to-ebp -12182 c3/return -12183 -12184 test-compute-offset-with-no-inouts: -12185 # . prologue -12186 55/push-ebp -12187 89/<- %ebp 4/r32/esp -12188 # setup -12189 (clear-stream _test-input-stream) -12190 (clear-stream $_test-input-buffered-file->buffer) -12191 (clear-stream _test-output-stream) -12192 (clear-stream $_test-output-buffered-file->buffer) -12193 (clear-stream _test-error-stream) -12194 (clear-stream $_test-error-buffered-file->buffer) -12195 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12196 68/push 0/imm32 -12197 68/push 0/imm32 -12198 89/<- %edx 4/r32/esp -12199 (tailor-exit-descriptor %edx 0x10) -12200 # -12201 (write _test-input-stream "fn foo {\n") -12202 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset\n") -12203 (write _test-input-stream "}\n") -12204 # convert -12205 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12206 # registers except esp clobbered at this point -12207 # restore ed -12208 89/<- %edx 4/r32/esp -12209 (flush _test-output-buffered-file) -12210 (flush _test-error-buffered-file) -12211 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12217 # check output -12218 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-no-inouts: output should be empty") -12219 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too few inouts (2 required)" "F - test-compute-offset-with-no-inouts: error message") -12220 # check that stop(1) was called -12221 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-no-inouts: exit status") -12222 # don't restore from ebp -12223 81 0/subop/add %esp 8/imm32 -12224 # . epilogue -12225 5d/pop-to-ebp -12226 c3/return -12227 -12228 test-compute-offset-with-too-few-inouts: -12229 # . prologue -12230 55/push-ebp -12231 89/<- %ebp 4/r32/esp -12232 # setup -12233 (clear-stream _test-input-stream) -12234 (clear-stream $_test-input-buffered-file->buffer) -12235 (clear-stream _test-output-stream) -12236 (clear-stream $_test-output-buffered-file->buffer) -12237 (clear-stream _test-error-stream) -12238 (clear-stream $_test-error-buffered-file->buffer) -12239 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12240 68/push 0/imm32 -12241 68/push 0/imm32 -12242 89/<- %edx 4/r32/esp -12243 (tailor-exit-descriptor %edx 0x10) -12244 # -12245 (write _test-input-stream "fn foo {\n") -12246 (write _test-input-stream " var a: (array int 3)\n") -12247 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a\n") -12248 (write _test-input-stream "}\n") -12249 # convert -12250 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12251 # registers except esp clobbered at this point -12252 # restore ed -12253 89/<- %edx 4/r32/esp -12254 (flush _test-output-buffered-file) -12255 (flush _test-error-buffered-file) -12256 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12262 # check output -12263 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-few-inouts: output should be empty") -12264 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too few inouts (2 required)" "F - test-compute-offset-with-too-few-inouts: error message") -12265 # check that stop(1) was called -12266 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-few-inouts: exit status") -12267 # don't restore from ebp -12268 81 0/subop/add %esp 8/imm32 -12269 # . epilogue -12270 5d/pop-to-ebp -12271 c3/return -12272 -12273 test-compute-offset-with-too-many-inouts: -12274 # . prologue -12275 55/push-ebp -12276 89/<- %ebp 4/r32/esp -12277 # setup -12278 (clear-stream _test-input-stream) -12279 (clear-stream $_test-input-buffered-file->buffer) -12280 (clear-stream _test-output-stream) -12281 (clear-stream $_test-output-buffered-file->buffer) -12282 (clear-stream _test-error-stream) -12283 (clear-stream $_test-error-buffered-file->buffer) -12284 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12285 68/push 0/imm32 -12286 68/push 0/imm32 -12287 89/<- %edx 4/r32/esp -12288 (tailor-exit-descriptor %edx 0x10) -12289 # -12290 (write _test-input-stream "fn foo {\n") -12291 (write _test-input-stream " var a: (array int 3)\n") -12292 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0, 0\n") -12293 (write _test-input-stream "}\n") -12294 # convert -12295 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12296 # registers except esp clobbered at this point -12297 # restore ed -12298 89/<- %edx 4/r32/esp -12299 (flush _test-output-buffered-file) -12300 (flush _test-error-buffered-file) -12301 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12307 # check output -12308 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-many-inouts: output should be empty") -12309 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too many inouts (2 required)" "F - test-compute-offset-with-too-many-inouts: error message") -12310 # check that stop(1) was called -12311 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-many-inouts: exit status") -12312 # don't restore from ebp -12313 81 0/subop/add %esp 8/imm32 -12314 # . epilogue -12315 5d/pop-to-ebp -12316 c3/return -12317 -12318 test-compute-offset-with-no-output: -12319 # . prologue -12320 55/push-ebp -12321 89/<- %ebp 4/r32/esp -12322 # setup -12323 (clear-stream _test-input-stream) -12324 (clear-stream $_test-input-buffered-file->buffer) -12325 (clear-stream _test-output-stream) -12326 (clear-stream $_test-output-buffered-file->buffer) -12327 (clear-stream _test-error-stream) -12328 (clear-stream $_test-error-buffered-file->buffer) -12329 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12330 68/push 0/imm32 -12331 68/push 0/imm32 -12332 89/<- %edx 4/r32/esp -12333 (tailor-exit-descriptor %edx 0x10) -12334 # -12335 (write _test-input-stream "fn foo {\n") -12336 (write _test-input-stream " var a: (array int 3)\n") -12337 (write _test-input-stream " compute-offset a, 0\n") -12338 (write _test-input-stream "}\n") -12339 # convert -12340 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12341 # registers except esp clobbered at this point -12342 # restore ed -12343 89/<- %edx 4/r32/esp -12344 (flush _test-output-buffered-file) -12345 (flush _test-error-buffered-file) -12346 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12352 # check output -12353 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-no-output: output should be empty") -12354 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: must have an output" "F - test-compute-offset-with-no-output: error message") -12355 # check that stop(1) was called -12356 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-no-output: exit status") -12357 # don't restore from ebp -12358 81 0/subop/add %esp 8/imm32 -12359 # . epilogue -12360 5d/pop-to-ebp -12361 c3/return -12362 -12363 test-compute-offset-with-too-many-outputs: -12364 # . prologue -12365 55/push-ebp -12366 89/<- %ebp 4/r32/esp -12367 # setup -12368 (clear-stream _test-input-stream) -12369 (clear-stream $_test-input-buffered-file->buffer) -12370 (clear-stream _test-output-stream) -12371 (clear-stream $_test-output-buffered-file->buffer) -12372 (clear-stream _test-error-stream) -12373 (clear-stream $_test-error-buffered-file->buffer) -12374 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12375 68/push 0/imm32 -12376 68/push 0/imm32 -12377 89/<- %edx 4/r32/esp -12378 (tailor-exit-descriptor %edx 0x10) -12379 # -12380 (write _test-input-stream "fn foo {\n") -12381 (write _test-input-stream " var a: (array int 3)\n") -12382 (write _test-input-stream " var b/eax: (offset int) <- compute-offset a, 0\n") -12383 (write _test-input-stream " var c/ecx: (addr int) <- copy 0\n") -12384 (write _test-input-stream " b, c <- compute-offset a, 0\n") -12385 (write _test-input-stream "}\n") -12386 # convert -12387 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12388 # registers except esp clobbered at this point -12389 # restore ed -12390 89/<- %edx 4/r32/esp -12391 (flush _test-output-buffered-file) -12392 (flush _test-error-buffered-file) -12393 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12399 # check output -12400 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-many-outputs: output should be empty") -12401 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too many outputs (1 required)" "F - test-compute-offset-with-too-many-outputs: error message") -12402 # check that stop(1) was called -12403 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-many-outputs: exit status") -12404 # don't restore from ebp -12405 81 0/subop/add %esp 8/imm32 -12406 # . epilogue -12407 5d/pop-to-ebp -12408 c3/return -12409 -12410 test-convert-read-from-stream: -12411 # . prologue -12412 55/push-ebp -12413 89/<- %ebp 4/r32/esp -12414 # setup -12415 (clear-stream _test-input-stream) -12416 (clear-stream $_test-input-buffered-file->buffer) -12417 (clear-stream _test-output-stream) -12418 (clear-stream $_test-output-buffered-file->buffer) -12419 # -12420 (write _test-input-stream "fn foo {\n") -12421 (write _test-input-stream " var s/esi: (addr stream int) <- copy 0\n") -12422 (write _test-input-stream " var o/ecx: (addr int) <- copy 0\n") -12423 (write _test-input-stream " read-from-stream s, o\n") -12424 (write _test-input-stream "}\n") -12425 # convert -12426 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -12427 # registers except esp clobbered at this point -12428 # restore ed -12429 89/<- %edx 4/r32/esp -12430 (flush _test-output-buffered-file) -12431 (flush _test-error-buffered-file) -12432 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -12438 # check output -12439 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-read-from-stream/0") -12440 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-read-from-stream/1") -12441 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-read-from-stream/2") -12442 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-read-from-stream/3") -12443 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-read-from-stream/4") -12444 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-read-from-stream/5") -12445 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-read-from-stream/6") -12446 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-read-from-stream/7") -12447 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-read-from-stream/8") -12448 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-read-from-stream/9") -12449 (check-next-stream-line-equal _test-output-stream " (read-from-stream %esi %ecx 0x00000004)" "F - test-convert-read-from-stream/10") -12450 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-read-from-stream/11") -12451 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-read-from-stream/12") -12452 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-read-from-stream/13") -12453 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-read-from-stream/14") -12454 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-read-from-stream/15") -12455 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-read-from-stream/16") -12456 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-read-from-stream/17") -12457 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-read-from-stream/18") -12458 # . epilogue -12459 89/<- %esp 5/r32/ebp -12460 5d/pop-to-ebp -12461 c3/return -12462 -12463 test-convert-read-from-stream-with-correct-payload-size: -12464 # . prologue -12465 55/push-ebp -12466 89/<- %ebp 4/r32/esp -12467 # setup -12468 (clear-stream _test-input-stream) -12469 (clear-stream $_test-input-buffered-file->buffer) -12470 (clear-stream _test-output-stream) -12471 (clear-stream $_test-output-buffered-file->buffer) -12472 # -12473 (write _test-input-stream "fn foo {\n") -12474 (write _test-input-stream " var s/esi: (addr stream handle int) <- copy 0\n") -12475 (write _test-input-stream " var o/ecx: (addr handle int) <- copy 0\n") -12476 (write _test-input-stream " read-from-stream s, o\n") -12477 (write _test-input-stream "}\n") -12478 # convert -12479 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -12480 # registers except esp clobbered at this point -12481 # restore ed -12482 89/<- %edx 4/r32/esp -12483 (flush _test-output-buffered-file) -12484 (flush _test-error-buffered-file) -12485 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -12491 # check output -12492 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-read-from-stream-with-correct-payload-size/0") -12493 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-read-from-stream-with-correct-payload-size/1") -12494 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-read-from-stream-with-correct-payload-size/2") -12495 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-read-from-stream-with-correct-payload-size/3") -12496 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-read-from-stream-with-correct-payload-size/4") -12497 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-read-from-stream-with-correct-payload-size/5") -12498 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-read-from-stream-with-correct-payload-size/6") -12499 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-read-from-stream-with-correct-payload-size/7") -12500 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-read-from-stream-with-correct-payload-size/8") -12501 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-read-from-stream-with-correct-payload-size/9") -12502 (check-next-stream-line-equal _test-output-stream " (read-from-stream %esi %ecx 0x00000008)" "F - test-convert-read-from-stream-with-correct-payload-size/10") -12503 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-read-from-stream-with-correct-payload-size/11") -12504 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-read-from-stream-with-correct-payload-size/12") -12505 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-read-from-stream-with-correct-payload-size/13") -12506 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-read-from-stream-with-correct-payload-size/14") -12507 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-read-from-stream-with-correct-payload-size/15") -12508 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-read-from-stream-with-correct-payload-size/16") -12509 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-read-from-stream-with-correct-payload-size/17") -12510 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-read-from-stream-with-correct-payload-size/18") -12511 # . epilogue -12512 89/<- %esp 5/r32/ebp -12513 5d/pop-to-ebp -12514 c3/return -12515 -12516 test-read-from-stream-with-non-stream-atom-base-type: -12517 # . prologue -12518 55/push-ebp -12519 89/<- %ebp 4/r32/esp -12520 # setup -12521 (clear-stream _test-input-stream) -12522 (clear-stream $_test-input-buffered-file->buffer) -12523 (clear-stream _test-output-stream) -12524 (clear-stream $_test-output-buffered-file->buffer) -12525 (clear-stream _test-error-stream) -12526 (clear-stream $_test-error-buffered-file->buffer) -12527 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12528 68/push 0/imm32 -12529 68/push 0/imm32 -12530 89/<- %edx 4/r32/esp -12531 (tailor-exit-descriptor %edx 0x10) -12532 # -12533 (write _test-input-stream "fn foo {\n") -12534 (write _test-input-stream " var a: int\n") -12535 (write _test-input-stream " read-from-stream a, 0\n") -12536 (write _test-input-stream "}\n") -12537 # convert -12538 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12539 # registers except esp clobbered at this point -12540 # restore ed -12541 89/<- %edx 4/r32/esp -12542 (flush _test-output-buffered-file) -12543 (flush _test-error-buffered-file) -12544 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12550 # check output -12551 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-atom-base-type: output should be empty") -12552 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-atom-base-type: error message") -12553 # check that stop(1) was called -12554 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-atom-base-type: exit status") -12555 # don't restore from ebp -12556 81 0/subop/add %esp 8/imm32 -12557 # . epilogue -12558 5d/pop-to-ebp -12559 c3/return -12560 -12561 test-read-from-stream-with-non-stream-compound-base-type: -12562 # . prologue -12563 55/push-ebp -12564 89/<- %ebp 4/r32/esp -12565 # setup -12566 (clear-stream _test-input-stream) -12567 (clear-stream $_test-input-buffered-file->buffer) -12568 (clear-stream _test-output-stream) -12569 (clear-stream $_test-output-buffered-file->buffer) -12570 (clear-stream _test-error-stream) -12571 (clear-stream $_test-error-buffered-file->buffer) -12572 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12573 68/push 0/imm32 -12574 68/push 0/imm32 -12575 89/<- %edx 4/r32/esp -12576 (tailor-exit-descriptor %edx 0x10) -12577 # -12578 (write _test-input-stream "fn foo {\n") -12579 (write _test-input-stream " var a: (handle int)\n") -12580 (write _test-input-stream " read-from-stream a, 0\n") -12581 (write _test-input-stream "}\n") -12582 # convert -12583 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12584 # registers except esp clobbered at this point -12585 # restore ed -12586 89/<- %edx 4/r32/esp -12587 (flush _test-output-buffered-file) -12588 (flush _test-error-buffered-file) -12589 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12595 # check output -12596 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-compound-base-type: output should be empty") -12597 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-compound-base-type: error message") -12598 # check that stop(1) was called -12599 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-compound-base-type: exit status") -12600 # don't restore from ebp -12601 81 0/subop/add %esp 8/imm32 -12602 # . epilogue -12603 5d/pop-to-ebp -12604 c3/return -12605 -12606 test-read-from-stream-with-non-stream-compound-base-type-2: -12607 # . prologue -12608 55/push-ebp -12609 89/<- %ebp 4/r32/esp -12610 # setup -12611 (clear-stream _test-input-stream) -12612 (clear-stream $_test-input-buffered-file->buffer) -12613 (clear-stream _test-output-stream) -12614 (clear-stream $_test-output-buffered-file->buffer) -12615 (clear-stream _test-error-stream) -12616 (clear-stream $_test-error-buffered-file->buffer) -12617 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12618 68/push 0/imm32 -12619 68/push 0/imm32 -12620 89/<- %edx 4/r32/esp -12621 (tailor-exit-descriptor %edx 0x10) -12622 # -12623 (write _test-input-stream "fn foo {\n") -12624 (write _test-input-stream " var a: (addr int)\n") -12625 (write _test-input-stream " read-from-stream a, 0\n") -12626 (write _test-input-stream "}\n") -12627 # convert -12628 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12629 # registers except esp clobbered at this point -12630 # restore ed -12631 89/<- %edx 4/r32/esp -12632 (flush _test-output-buffered-file) -12633 (flush _test-error-buffered-file) -12634 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12640 # check output -12641 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-compound-base-type-2: output should be empty") -12642 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-compound-base-type-2: error message") -12643 # check that stop(1) was called -12644 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-compound-base-type-2: exit status") -12645 # don't restore from ebp -12646 81 0/subop/add %esp 8/imm32 -12647 # . epilogue -12648 5d/pop-to-ebp -12649 c3/return -12650 -12651 test-read-from-stream-with-stream-atom-base-type: -12652 # . prologue -12653 55/push-ebp -12654 89/<- %ebp 4/r32/esp -12655 # setup -12656 (clear-stream _test-input-stream) -12657 (clear-stream $_test-input-buffered-file->buffer) -12658 (clear-stream _test-output-stream) -12659 (clear-stream $_test-output-buffered-file->buffer) -12660 (clear-stream _test-error-stream) -12661 (clear-stream $_test-error-buffered-file->buffer) -12662 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12663 68/push 0/imm32 -12664 68/push 0/imm32 -12665 89/<- %edx 4/r32/esp -12666 (tailor-exit-descriptor %edx 0x10) -12667 # -12668 (write _test-input-stream "fn foo {\n") -12669 (write _test-input-stream " var a: stream\n") -12670 (write _test-input-stream " read-from-stream a, 0\n") -12671 (write _test-input-stream "}\n") -12672 # convert -12673 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12674 # registers except esp clobbered at this point -12675 # restore ed -12676 89/<- %edx 4/r32/esp -12677 (flush _test-output-buffered-file) -12678 (flush _test-error-buffered-file) -12679 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12685 # check output -12686 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-stream-atom-base-type: output should be empty") -12687 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-stream-atom-base-type: error message") -12688 # check that stop(1) was called -12689 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-stream-atom-base-type: exit status") -12690 # don't restore from ebp -12691 81 0/subop/add %esp 8/imm32 -12692 # . epilogue -12693 5d/pop-to-ebp -12694 c3/return -12695 -12696 test-read-from-stream-with-wrong-index-type: -12697 # . prologue -12698 55/push-ebp -12699 89/<- %ebp 4/r32/esp -12700 # setup -12701 (clear-stream _test-input-stream) -12702 (clear-stream $_test-input-buffered-file->buffer) -12703 (clear-stream _test-output-stream) -12704 (clear-stream $_test-output-buffered-file->buffer) -12705 (clear-stream _test-error-stream) -12706 (clear-stream $_test-error-buffered-file->buffer) -12707 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12708 68/push 0/imm32 -12709 68/push 0/imm32 -12710 89/<- %edx 4/r32/esp -12711 (tailor-exit-descriptor %edx 0x10) -12712 # -12713 (write _test-input-stream "fn foo {\n") -12714 (write _test-input-stream " var a/eax: (addr stream int) <- copy 0\n") -12715 (write _test-input-stream " var b: boolean\n") -12716 (write _test-input-stream " read-from-stream a, b\n") -12717 (write _test-input-stream "}\n") -12718 # convert -12719 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12720 # registers except esp clobbered at this point -12721 # restore ed -12722 89/<- %edx 4/r32/esp -12723 (flush _test-output-buffered-file) -12724 (flush _test-error-buffered-file) -12725 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12731 # check output -12732 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-wrong-index-type: output should be empty") -12733 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: target 'b' must be an addr" "F - test-read-from-stream-with-wrong-index-type: error message") -12734 # check that stop(1) was called -12735 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-wrong-index-type: exit status") -12736 # don't restore from ebp -12737 81 0/subop/add %esp 8/imm32 -12738 # . epilogue -12739 5d/pop-to-ebp -12740 c3/return -12741 -12742 test-read-from-stream-with-no-inouts: -12743 # . prologue -12744 55/push-ebp -12745 89/<- %ebp 4/r32/esp -12746 # setup -12747 (clear-stream _test-input-stream) -12748 (clear-stream $_test-input-buffered-file->buffer) -12749 (clear-stream _test-output-stream) -12750 (clear-stream $_test-output-buffered-file->buffer) -12751 (clear-stream _test-error-stream) -12752 (clear-stream $_test-error-buffered-file->buffer) -12753 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12754 68/push 0/imm32 -12755 68/push 0/imm32 -12756 89/<- %edx 4/r32/esp -12757 (tailor-exit-descriptor %edx 0x10) -12758 # -12759 (write _test-input-stream "fn foo {\n") -12760 (write _test-input-stream " read-from-stream\n") -12761 (write _test-input-stream "}\n") -12762 # convert -12763 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12764 # registers except esp clobbered at this point -12765 # restore ed -12766 89/<- %edx 4/r32/esp -12767 (flush _test-output-buffered-file) -12768 (flush _test-error-buffered-file) -12769 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12775 # check output -12776 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-no-inouts: output should be empty") -12777 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too few inouts (2 required)" "F - test-read-from-stream-with-no-inouts: error message") -12778 # check that stop(1) was called -12779 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-no-inouts: exit status") -12780 # don't restore from ebp -12781 81 0/subop/add %esp 8/imm32 -12782 # . epilogue -12783 5d/pop-to-ebp -12784 c3/return -12785 -12786 test-read-from-stream-with-too-few-inouts: -12787 # . prologue -12788 55/push-ebp -12789 89/<- %ebp 4/r32/esp -12790 # setup -12791 (clear-stream _test-input-stream) -12792 (clear-stream $_test-input-buffered-file->buffer) -12793 (clear-stream _test-output-stream) -12794 (clear-stream $_test-output-buffered-file->buffer) -12795 (clear-stream _test-error-stream) -12796 (clear-stream $_test-error-buffered-file->buffer) -12797 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12798 68/push 0/imm32 -12799 68/push 0/imm32 -12800 89/<- %edx 4/r32/esp -12801 (tailor-exit-descriptor %edx 0x10) -12802 # -12803 (write _test-input-stream "fn foo {\n") -12804 (write _test-input-stream " var a: (addr stream int)\n") -12805 (write _test-input-stream " read-from-stream a\n") -12806 (write _test-input-stream "}\n") -12807 # convert -12808 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12809 # registers except esp clobbered at this point -12810 # restore ed -12811 89/<- %edx 4/r32/esp -12812 (flush _test-output-buffered-file) -12813 (flush _test-error-buffered-file) -12814 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12820 # check output -12821 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-too-few-inouts: output should be empty") -12822 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too few inouts (2 required)" "F - test-read-from-stream-with-too-few-inouts: error message") -12823 # check that stop(1) was called -12824 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-too-few-inouts: exit status") -12825 # don't restore from ebp -12826 81 0/subop/add %esp 8/imm32 -12827 # . epilogue -12828 5d/pop-to-ebp -12829 c3/return -12830 -12831 test-read-from-stream-with-too-many-inouts: -12832 # . prologue -12833 55/push-ebp -12834 89/<- %ebp 4/r32/esp -12835 # setup -12836 (clear-stream _test-input-stream) -12837 (clear-stream $_test-input-buffered-file->buffer) -12838 (clear-stream _test-output-stream) -12839 (clear-stream $_test-output-buffered-file->buffer) -12840 (clear-stream _test-error-stream) -12841 (clear-stream $_test-error-buffered-file->buffer) -12842 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12843 68/push 0/imm32 -12844 68/push 0/imm32 -12845 89/<- %edx 4/r32/esp -12846 (tailor-exit-descriptor %edx 0x10) -12847 # -12848 (write _test-input-stream "fn foo {\n") -12849 (write _test-input-stream " var a: (addr stream int)\n") -12850 (write _test-input-stream " var b: (addr int)\n") -12851 (write _test-input-stream " read-from-stream a, b, 0\n") -12852 (write _test-input-stream "}\n") -12853 # convert -12854 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12855 # registers except esp clobbered at this point -12856 # restore ed -12857 89/<- %edx 4/r32/esp -12858 (flush _test-output-buffered-file) -12859 (flush _test-error-buffered-file) -12860 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12866 # check output -12867 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-too-many-inouts: output should be empty") -12868 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too many inouts (2 required)" "F - test-read-from-stream-with-too-many-inouts: error message") -12869 # check that stop(1) was called -12870 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-too-many-inouts: exit status") -12871 # don't restore from ebp -12872 81 0/subop/add %esp 8/imm32 -12873 # . epilogue -12874 5d/pop-to-ebp -12875 c3/return -12876 -12877 test-read-from-stream-with-output: -12878 # . prologue -12879 55/push-ebp -12880 89/<- %ebp 4/r32/esp -12881 # setup -12882 (clear-stream _test-input-stream) -12883 (clear-stream $_test-input-buffered-file->buffer) -12884 (clear-stream _test-output-stream) -12885 (clear-stream $_test-output-buffered-file->buffer) -12886 (clear-stream _test-error-stream) -12887 (clear-stream $_test-error-buffered-file->buffer) -12888 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -12889 68/push 0/imm32 -12890 68/push 0/imm32 -12891 89/<- %edx 4/r32/esp -12892 (tailor-exit-descriptor %edx 0x10) -12893 # -12894 (write _test-input-stream "fn foo {\n") -12895 (write _test-input-stream " var a: (addr stream int)\n") -12896 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n") -12897 (write _test-input-stream " b <- read-from-stream a, b\n") -12898 (write _test-input-stream "}\n") -12899 # convert -12900 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -12901 # registers except esp clobbered at this point -12902 # restore ed -12903 89/<- %edx 4/r32/esp -12904 (flush _test-output-buffered-file) -12905 (flush _test-error-buffered-file) -12906 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -12912 # check output -12913 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-output: output should be empty") -12914 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: unexpected output" "F - test-read-from-stream-with-output: error message") -12915 # check that stop(1) was called -12916 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-output: exit status") -12917 # don't restore from ebp -12918 81 0/subop/add %esp 8/imm32 -12919 # . epilogue -12920 5d/pop-to-ebp -12921 c3/return -12922 -12923 test-convert-write-to-stream: -12924 # . prologue -12925 55/push-ebp -12926 89/<- %ebp 4/r32/esp -12927 # setup -12928 (clear-stream _test-input-stream) -12929 (clear-stream $_test-input-buffered-file->buffer) -12930 (clear-stream _test-output-stream) -12931 (clear-stream $_test-output-buffered-file->buffer) -12932 # -12933 (write _test-input-stream "fn foo {\n") -12934 (write _test-input-stream " var s/esi: (addr stream int) <- copy 0\n") -12935 (write _test-input-stream " var o/ecx: (addr int) <- copy 0\n") -12936 (write _test-input-stream " write-to-stream s, o\n") -12937 (write _test-input-stream "}\n") -12938 # convert -12939 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -12940 # registers except esp clobbered at this point -12941 # restore ed -12942 89/<- %edx 4/r32/esp -12943 (flush _test-output-buffered-file) -12944 (flush _test-error-buffered-file) -12945 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -12951 # check output -12952 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-write-to-stream/0") -12953 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-write-to-stream/1") -12954 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-write-to-stream/2") -12955 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-write-to-stream/3") -12956 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-write-to-stream/4") -12957 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-write-to-stream/5") -12958 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-write-to-stream/6") -12959 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-write-to-stream/7") -12960 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-write-to-stream/8") -12961 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-write-to-stream/9") -12962 (check-next-stream-line-equal _test-output-stream " (write-to-stream %esi %ecx 0x00000004)" "F - test-convert-write-to-stream/10") -12963 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-write-to-stream/11") -12964 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-write-to-stream/12") -12965 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-write-to-stream/13") -12966 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-write-to-stream/14") -12967 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-write-to-stream/15") -12968 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-write-to-stream/16") -12969 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-write-to-stream/17") -12970 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-write-to-stream/18") -12971 # . epilogue -12972 89/<- %esp 5/r32/ebp -12973 5d/pop-to-ebp -12974 c3/return -12975 -12976 test-convert-write-to-stream-with-correct-payload-size: -12977 # . prologue -12978 55/push-ebp -12979 89/<- %ebp 4/r32/esp -12980 # setup -12981 (clear-stream _test-input-stream) -12982 (clear-stream $_test-input-buffered-file->buffer) -12983 (clear-stream _test-output-stream) -12984 (clear-stream $_test-output-buffered-file->buffer) -12985 # -12986 (write _test-input-stream "fn foo {\n") -12987 (write _test-input-stream " var s/esi: (addr stream handle int) <- copy 0\n") -12988 (write _test-input-stream " var o/ecx: (addr handle int) <- copy 0\n") -12989 (write _test-input-stream " write-to-stream s, o\n") -12990 (write _test-input-stream "}\n") -12991 # convert -12992 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -12993 # registers except esp clobbered at this point -12994 # restore ed -12995 89/<- %edx 4/r32/esp -12996 (flush _test-output-buffered-file) -12997 (flush _test-error-buffered-file) -12998 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -13004 # check output -13005 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-write-to-stream-with-correct-payload-size/0") -13006 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-write-to-stream-with-correct-payload-size/1") -13007 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-write-to-stream-with-correct-payload-size/2") -13008 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-write-to-stream-with-correct-payload-size/3") -13009 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-write-to-stream-with-correct-payload-size/4") -13010 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-write-to-stream-with-correct-payload-size/5") -13011 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-write-to-stream-with-correct-payload-size/6") -13012 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-write-to-stream-with-correct-payload-size/7") -13013 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-write-to-stream-with-correct-payload-size/8") -13014 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-write-to-stream-with-correct-payload-size/9") -13015 (check-next-stream-line-equal _test-output-stream " (write-to-stream %esi %ecx 0x00000008)" "F - test-convert-write-to-stream-with-correct-payload-size/10") -13016 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-write-to-stream-with-correct-payload-size/11") -13017 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-write-to-stream-with-correct-payload-size/12") -13018 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-write-to-stream-with-correct-payload-size/13") -13019 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-write-to-stream-with-correct-payload-size/14") -13020 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-write-to-stream-with-correct-payload-size/15") -13021 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-write-to-stream-with-correct-payload-size/16") -13022 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-write-to-stream-with-correct-payload-size/17") -13023 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-write-to-stream-with-correct-payload-size/18") -13024 # . epilogue -13025 89/<- %esp 5/r32/ebp -13026 5d/pop-to-ebp -13027 c3/return -13028 -13029 test-write-to-stream-with-non-stream-atom-base-type: -13030 # . prologue -13031 55/push-ebp -13032 89/<- %ebp 4/r32/esp -13033 # setup -13034 (clear-stream _test-input-stream) -13035 (clear-stream $_test-input-buffered-file->buffer) -13036 (clear-stream _test-output-stream) -13037 (clear-stream $_test-output-buffered-file->buffer) -13038 (clear-stream _test-error-stream) -13039 (clear-stream $_test-error-buffered-file->buffer) -13040 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13041 68/push 0/imm32 -13042 68/push 0/imm32 -13043 89/<- %edx 4/r32/esp -13044 (tailor-exit-descriptor %edx 0x10) -13045 # -13046 (write _test-input-stream "fn foo {\n") -13047 (write _test-input-stream " var a: int\n") -13048 (write _test-input-stream " write-to-stream a, 0\n") -13049 (write _test-input-stream "}\n") -13050 # convert -13051 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13052 # registers except esp clobbered at this point -13053 # restore ed -13054 89/<- %edx 4/r32/esp -13055 (flush _test-output-buffered-file) -13056 (flush _test-error-buffered-file) -13057 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13063 # check output -13064 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-atom-base-type: output should be empty") -13065 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-atom-base-type: error message") -13066 # check that stop(1) was called -13067 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-atom-base-type: exit status") -13068 # don't restore from ebp -13069 81 0/subop/add %esp 8/imm32 -13070 # . epilogue -13071 5d/pop-to-ebp -13072 c3/return -13073 -13074 test-write-to-stream-with-non-stream-compound-base-type: -13075 # . prologue -13076 55/push-ebp -13077 89/<- %ebp 4/r32/esp -13078 # setup -13079 (clear-stream _test-input-stream) -13080 (clear-stream $_test-input-buffered-file->buffer) -13081 (clear-stream _test-output-stream) -13082 (clear-stream $_test-output-buffered-file->buffer) -13083 (clear-stream _test-error-stream) -13084 (clear-stream $_test-error-buffered-file->buffer) -13085 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13086 68/push 0/imm32 -13087 68/push 0/imm32 -13088 89/<- %edx 4/r32/esp -13089 (tailor-exit-descriptor %edx 0x10) -13090 # -13091 (write _test-input-stream "fn foo {\n") -13092 (write _test-input-stream " var a: (handle int)\n") -13093 (write _test-input-stream " write-to-stream a, 0\n") -13094 (write _test-input-stream "}\n") -13095 # convert -13096 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13097 # registers except esp clobbered at this point -13098 # restore ed -13099 89/<- %edx 4/r32/esp -13100 (flush _test-output-buffered-file) -13101 (flush _test-error-buffered-file) -13102 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13108 # check output -13109 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-compound-base-type: output should be empty") -13110 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-compound-base-type: error message") -13111 # check that stop(1) was called -13112 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-compound-base-type: exit status") -13113 # don't restore from ebp -13114 81 0/subop/add %esp 8/imm32 -13115 # . epilogue -13116 5d/pop-to-ebp -13117 c3/return -13118 -13119 test-write-to-stream-with-non-stream-compound-base-type-2: -13120 # . prologue -13121 55/push-ebp -13122 89/<- %ebp 4/r32/esp -13123 # setup -13124 (clear-stream _test-input-stream) -13125 (clear-stream $_test-input-buffered-file->buffer) -13126 (clear-stream _test-output-stream) -13127 (clear-stream $_test-output-buffered-file->buffer) -13128 (clear-stream _test-error-stream) -13129 (clear-stream $_test-error-buffered-file->buffer) -13130 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13131 68/push 0/imm32 -13132 68/push 0/imm32 -13133 89/<- %edx 4/r32/esp -13134 (tailor-exit-descriptor %edx 0x10) -13135 # -13136 (write _test-input-stream "fn foo {\n") -13137 (write _test-input-stream " var a: (addr int)\n") -13138 (write _test-input-stream " write-to-stream a, 0\n") -13139 (write _test-input-stream "}\n") -13140 # convert -13141 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13142 # registers except esp clobbered at this point -13143 # restore ed -13144 89/<- %edx 4/r32/esp -13145 (flush _test-output-buffered-file) -13146 (flush _test-error-buffered-file) -13147 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13153 # check output -13154 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-compound-base-type-2: output should be empty") -13155 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-compound-base-type-2: error message") -13156 # check that stop(1) was called -13157 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-compound-base-type-2: exit status") -13158 # don't restore from ebp -13159 81 0/subop/add %esp 8/imm32 -13160 # . epilogue -13161 5d/pop-to-ebp -13162 c3/return -13163 -13164 test-write-to-stream-with-stream-atom-base-type: -13165 # . prologue -13166 55/push-ebp -13167 89/<- %ebp 4/r32/esp -13168 # setup -13169 (clear-stream _test-input-stream) -13170 (clear-stream $_test-input-buffered-file->buffer) -13171 (clear-stream _test-output-stream) -13172 (clear-stream $_test-output-buffered-file->buffer) -13173 (clear-stream _test-error-stream) -13174 (clear-stream $_test-error-buffered-file->buffer) -13175 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13176 68/push 0/imm32 -13177 68/push 0/imm32 -13178 89/<- %edx 4/r32/esp -13179 (tailor-exit-descriptor %edx 0x10) -13180 # -13181 (write _test-input-stream "fn foo {\n") -13182 (write _test-input-stream " var a: stream\n") -13183 (write _test-input-stream " write-to-stream a, 0\n") -13184 (write _test-input-stream "}\n") -13185 # convert -13186 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13187 # registers except esp clobbered at this point -13188 # restore ed -13189 89/<- %edx 4/r32/esp -13190 (flush _test-output-buffered-file) -13191 (flush _test-error-buffered-file) -13192 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13198 # check output -13199 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-stream-atom-base-type: output should be empty") -13200 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-stream-atom-base-type: error message") -13201 # check that stop(1) was called -13202 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-stream-atom-base-type: exit status") -13203 # don't restore from ebp -13204 81 0/subop/add %esp 8/imm32 -13205 # . epilogue -13206 5d/pop-to-ebp -13207 c3/return -13208 -13209 test-write-to-stream-with-wrong-index-type: -13210 # . prologue -13211 55/push-ebp -13212 89/<- %ebp 4/r32/esp -13213 # setup -13214 (clear-stream _test-input-stream) -13215 (clear-stream $_test-input-buffered-file->buffer) -13216 (clear-stream _test-output-stream) -13217 (clear-stream $_test-output-buffered-file->buffer) -13218 (clear-stream _test-error-stream) -13219 (clear-stream $_test-error-buffered-file->buffer) -13220 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13221 68/push 0/imm32 -13222 68/push 0/imm32 -13223 89/<- %edx 4/r32/esp -13224 (tailor-exit-descriptor %edx 0x10) -13225 # -13226 (write _test-input-stream "fn foo {\n") -13227 (write _test-input-stream " var a/eax: (addr stream int) <- copy 0\n") -13228 (write _test-input-stream " var b: boolean\n") -13229 (write _test-input-stream " write-to-stream a, b\n") -13230 (write _test-input-stream "}\n") -13231 # convert -13232 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13233 # registers except esp clobbered at this point -13234 # restore ed -13235 89/<- %edx 4/r32/esp -13236 (flush _test-output-buffered-file) -13237 (flush _test-error-buffered-file) -13238 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13244 # check output -13245 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-wrong-index-type: output should be empty") -13246 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: target 'b' must be an addr" "F - test-write-to-stream-with-wrong-index-type: error message") -13247 # check that stop(1) was called -13248 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-wrong-index-type: exit status") -13249 # don't restore from ebp -13250 81 0/subop/add %esp 8/imm32 -13251 # . epilogue -13252 5d/pop-to-ebp -13253 c3/return -13254 -13255 test-write-to-stream-with-no-inouts: -13256 # . prologue -13257 55/push-ebp -13258 89/<- %ebp 4/r32/esp -13259 # setup -13260 (clear-stream _test-input-stream) -13261 (clear-stream $_test-input-buffered-file->buffer) -13262 (clear-stream _test-output-stream) -13263 (clear-stream $_test-output-buffered-file->buffer) -13264 (clear-stream _test-error-stream) -13265 (clear-stream $_test-error-buffered-file->buffer) -13266 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13267 68/push 0/imm32 -13268 68/push 0/imm32 -13269 89/<- %edx 4/r32/esp -13270 (tailor-exit-descriptor %edx 0x10) -13271 # -13272 (write _test-input-stream "fn foo {\n") -13273 (write _test-input-stream " write-to-stream\n") -13274 (write _test-input-stream "}\n") -13275 # convert -13276 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13277 # registers except esp clobbered at this point -13278 # restore ed -13279 89/<- %edx 4/r32/esp -13280 (flush _test-output-buffered-file) -13281 (flush _test-error-buffered-file) -13282 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13288 # check output -13289 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-no-inouts: output should be empty") -13290 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too few inouts (2 required)" "F - test-write-to-stream-with-no-inouts: error message") -13291 # check that stop(1) was called -13292 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-no-inouts: exit status") -13293 # don't restore from ebp -13294 81 0/subop/add %esp 8/imm32 -13295 # . epilogue -13296 5d/pop-to-ebp -13297 c3/return -13298 -13299 test-write-to-stream-with-too-few-inouts: -13300 # . prologue -13301 55/push-ebp -13302 89/<- %ebp 4/r32/esp -13303 # setup -13304 (clear-stream _test-input-stream) -13305 (clear-stream $_test-input-buffered-file->buffer) -13306 (clear-stream _test-output-stream) -13307 (clear-stream $_test-output-buffered-file->buffer) -13308 (clear-stream _test-error-stream) -13309 (clear-stream $_test-error-buffered-file->buffer) -13310 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13311 68/push 0/imm32 -13312 68/push 0/imm32 -13313 89/<- %edx 4/r32/esp -13314 (tailor-exit-descriptor %edx 0x10) -13315 # -13316 (write _test-input-stream "fn foo {\n") -13317 (write _test-input-stream " var a: (addr stream int)\n") -13318 (write _test-input-stream " write-to-stream a\n") -13319 (write _test-input-stream "}\n") -13320 # convert -13321 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13322 # registers except esp clobbered at this point -13323 # restore ed -13324 89/<- %edx 4/r32/esp -13325 (flush _test-output-buffered-file) -13326 (flush _test-error-buffered-file) -13327 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13333 # check output -13334 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-too-few-inouts: output should be empty") -13335 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too few inouts (2 required)" "F - test-write-to-stream-with-too-few-inouts: error message") -13336 # check that stop(1) was called -13337 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-too-few-inouts: exit status") -13338 # don't restore from ebp -13339 81 0/subop/add %esp 8/imm32 -13340 # . epilogue -13341 5d/pop-to-ebp -13342 c3/return -13343 -13344 test-write-to-stream-with-too-many-inouts: -13345 # . prologue -13346 55/push-ebp -13347 89/<- %ebp 4/r32/esp -13348 # setup -13349 (clear-stream _test-input-stream) -13350 (clear-stream $_test-input-buffered-file->buffer) -13351 (clear-stream _test-output-stream) -13352 (clear-stream $_test-output-buffered-file->buffer) -13353 (clear-stream _test-error-stream) -13354 (clear-stream $_test-error-buffered-file->buffer) -13355 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13356 68/push 0/imm32 -13357 68/push 0/imm32 -13358 89/<- %edx 4/r32/esp -13359 (tailor-exit-descriptor %edx 0x10) -13360 # -13361 (write _test-input-stream "fn foo {\n") -13362 (write _test-input-stream " var a: (addr stream int)\n") -13363 (write _test-input-stream " var b: (addr int)\n") -13364 (write _test-input-stream " write-to-stream a, b, 0\n") -13365 (write _test-input-stream "}\n") -13366 # convert -13367 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13368 # registers except esp clobbered at this point -13369 # restore ed -13370 89/<- %edx 4/r32/esp -13371 (flush _test-output-buffered-file) -13372 (flush _test-error-buffered-file) -13373 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13379 # check output -13380 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-too-many-inouts: output should be empty") -13381 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too many inouts (2 required)" "F - test-write-to-stream-with-too-many-inouts: error message") -13382 # check that stop(1) was called -13383 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-too-many-inouts: exit status") -13384 # don't restore from ebp -13385 81 0/subop/add %esp 8/imm32 -13386 # . epilogue -13387 5d/pop-to-ebp -13388 c3/return -13389 -13390 test-write-to-stream-with-output: -13391 # . prologue -13392 55/push-ebp -13393 89/<- %ebp 4/r32/esp -13394 # setup -13395 (clear-stream _test-input-stream) -13396 (clear-stream $_test-input-buffered-file->buffer) -13397 (clear-stream _test-output-stream) -13398 (clear-stream $_test-output-buffered-file->buffer) -13399 (clear-stream _test-error-stream) -13400 (clear-stream $_test-error-buffered-file->buffer) -13401 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13402 68/push 0/imm32 -13403 68/push 0/imm32 -13404 89/<- %edx 4/r32/esp -13405 (tailor-exit-descriptor %edx 0x10) -13406 # -13407 (write _test-input-stream "fn foo {\n") -13408 (write _test-input-stream " var a: (addr stream int)\n") -13409 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n") -13410 (write _test-input-stream " b <- write-to-stream a, b\n") -13411 (write _test-input-stream "}\n") -13412 # convert -13413 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13414 # registers except esp clobbered at this point -13415 # restore ed -13416 89/<- %edx 4/r32/esp -13417 (flush _test-output-buffered-file) -13418 (flush _test-error-buffered-file) -13419 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13425 # check output -13426 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-output: output should be empty") -13427 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: unexpected output" "F - test-write-to-stream-with-output: error message") -13428 # check that stop(1) was called -13429 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-output: exit status") -13430 # don't restore from ebp -13431 81 0/subop/add %esp 8/imm32 -13432 # . epilogue -13433 5d/pop-to-ebp -13434 c3/return -13435 -13436 test-length-with-non-array-atom-base-type: -13437 # . prologue -13438 55/push-ebp -13439 89/<- %ebp 4/r32/esp -13440 # setup -13441 (clear-stream _test-input-stream) -13442 (clear-stream $_test-input-buffered-file->buffer) -13443 (clear-stream _test-output-stream) -13444 (clear-stream $_test-output-buffered-file->buffer) -13445 (clear-stream _test-error-stream) -13446 (clear-stream $_test-error-buffered-file->buffer) -13447 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13448 68/push 0/imm32 -13449 68/push 0/imm32 -13450 89/<- %edx 4/r32/esp -13451 (tailor-exit-descriptor %edx 0x10) -13452 # -13453 (write _test-input-stream "fn foo {\n") -13454 (write _test-input-stream " var a: int\n") -13455 (write _test-input-stream " var c/ecx: int <- length a\n") -13456 (write _test-input-stream "}\n") -13457 # convert -13458 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13459 # registers except esp clobbered at this point -13460 # restore ed -13461 89/<- %edx 4/r32/esp -13462 (flush _test-output-buffered-file) -13463 (flush _test-error-buffered-file) -13464 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13470 # check output -13471 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-atom-base-type: output should be empty") -13472 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-atom-base-type: error message") -13473 # check that stop(1) was called -13474 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-atom-base-type: exit status") -13475 # don't restore from ebp -13476 81 0/subop/add %esp 8/imm32 -13477 # . epilogue -13478 5d/pop-to-ebp -13479 c3/return -13480 -13481 test-length-with-non-array-compound-base-type: -13482 # . prologue -13483 55/push-ebp -13484 89/<- %ebp 4/r32/esp -13485 # setup -13486 (clear-stream _test-input-stream) -13487 (clear-stream $_test-input-buffered-file->buffer) -13488 (clear-stream _test-output-stream) -13489 (clear-stream $_test-output-buffered-file->buffer) -13490 (clear-stream _test-error-stream) -13491 (clear-stream $_test-error-buffered-file->buffer) -13492 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13493 68/push 0/imm32 -13494 68/push 0/imm32 -13495 89/<- %edx 4/r32/esp -13496 (tailor-exit-descriptor %edx 0x10) -13497 # -13498 (write _test-input-stream "fn foo {\n") -13499 (write _test-input-stream " var a: (handle int)\n") -13500 (write _test-input-stream " var c/ecx: (addr int) <- length a, 0\n") -13501 (write _test-input-stream "}\n") -13502 # convert -13503 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13504 # registers except esp clobbered at this point -13505 # restore ed -13506 89/<- %edx 4/r32/esp -13507 (flush _test-output-buffered-file) -13508 (flush _test-error-buffered-file) -13509 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13515 # check output -13516 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-compound-base-type: output should be empty") -13517 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-compound-base-type: error message") -13518 # check that stop(1) was called -13519 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-compound-base-type: exit status") -13520 # don't restore from ebp -13521 81 0/subop/add %esp 8/imm32 -13522 # . epilogue -13523 5d/pop-to-ebp -13524 c3/return -13525 -13526 test-length-with-non-array-compound-base-type-2: -13527 # . prologue -13528 55/push-ebp -13529 89/<- %ebp 4/r32/esp -13530 # setup -13531 (clear-stream _test-input-stream) -13532 (clear-stream $_test-input-buffered-file->buffer) -13533 (clear-stream _test-output-stream) -13534 (clear-stream $_test-output-buffered-file->buffer) -13535 (clear-stream _test-error-stream) -13536 (clear-stream $_test-error-buffered-file->buffer) -13537 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13538 68/push 0/imm32 -13539 68/push 0/imm32 -13540 89/<- %edx 4/r32/esp -13541 (tailor-exit-descriptor %edx 0x10) -13542 # -13543 (write _test-input-stream "fn foo {\n") -13544 (write _test-input-stream " var a: (addr int)\n") -13545 (write _test-input-stream " var c/ecx: (addr int) <- length a, 0\n") -13546 (write _test-input-stream "}\n") -13547 # convert -13548 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13549 # registers except esp clobbered at this point -13550 # restore ed -13551 89/<- %edx 4/r32/esp -13552 (flush _test-output-buffered-file) -13553 (flush _test-error-buffered-file) -13554 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13560 # check output -13561 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-compound-base-type-2: output should be empty") -13562 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-compound-base-type-2: error message") -13563 # check that stop(1) was called -13564 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-compound-base-type-2: exit status") -13565 # don't restore from ebp -13566 81 0/subop/add %esp 8/imm32 -13567 # . epilogue -13568 5d/pop-to-ebp -13569 c3/return -13570 -13571 test-length-with-array-atom-base-type: -13572 # . prologue -13573 55/push-ebp -13574 89/<- %ebp 4/r32/esp -13575 # setup -13576 (clear-stream _test-input-stream) -13577 (clear-stream $_test-input-buffered-file->buffer) -13578 (clear-stream _test-output-stream) -13579 (clear-stream $_test-output-buffered-file->buffer) -13580 (clear-stream _test-error-stream) -13581 (clear-stream $_test-error-buffered-file->buffer) -13582 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13583 68/push 0/imm32 -13584 68/push 0/imm32 -13585 89/<- %edx 4/r32/esp -13586 (tailor-exit-descriptor %edx 0x10) -13587 # -13588 (write _test-input-stream "fn foo {\n") -13589 (write _test-input-stream " var a: array\n") -13590 (write _test-input-stream " var c/ecx: (addr int) <- length a\n") -13591 (write _test-input-stream "}\n") -13592 # convert -13593 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13594 # registers except esp clobbered at this point -13595 # restore ed -13596 89/<- %edx 4/r32/esp -13597 (flush _test-output-buffered-file) -13598 (flush _test-error-buffered-file) -13599 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13605 # check output -13606 (check-stream-equal _test-output-stream "" "F - test-length-with-array-atom-base-type: output should be empty") -13607 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: array 'a' must specify the type of its elements" "F - test-length-with-array-atom-base-type: error message") -13608 # check that stop(1) was called -13609 (check-ints-equal *(edx+4) 2 "F - test-length-with-array-atom-base-type: exit status") -13610 # don't restore from ebp -13611 81 0/subop/add %esp 8/imm32 -13612 # . epilogue -13613 5d/pop-to-ebp -13614 c3/return -13615 -13616 test-length-with-addr-base-on-stack: -13617 # . prologue -13618 55/push-ebp -13619 89/<- %ebp 4/r32/esp -13620 # setup -13621 (clear-stream _test-input-stream) -13622 (clear-stream $_test-input-buffered-file->buffer) -13623 (clear-stream _test-output-stream) -13624 (clear-stream $_test-output-buffered-file->buffer) -13625 (clear-stream _test-error-stream) -13626 (clear-stream $_test-error-buffered-file->buffer) -13627 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13628 68/push 0/imm32 -13629 68/push 0/imm32 -13630 89/<- %edx 4/r32/esp -13631 (tailor-exit-descriptor %edx 0x10) -13632 # -13633 (write _test-input-stream "fn foo {\n") -13634 (write _test-input-stream " var a: (addr array int)\n") -13635 (write _test-input-stream " var c/ecx: (addr int) <- length a\n") -13636 (write _test-input-stream "}\n") -13637 # convert -13638 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13639 # registers except esp clobbered at this point -13640 # restore ed -13641 89/<- %edx 4/r32/esp -13642 (flush _test-output-buffered-file) -13643 (flush _test-error-buffered-file) -13644 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13650 # check output -13651 (check-stream-equal _test-output-stream "" "F - test-length-with-addr-base-on-stack: output should be empty") -13652 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is an addr to an array, and so must live in a register" "F - test-length-with-addr-base-on-stack: error message") -13653 # check that stop(1) was called -13654 (check-ints-equal *(edx+4) 2 "F - test-length-with-addr-base-on-stack: exit status") -13655 # don't restore from ebp -13656 81 0/subop/add %esp 8/imm32 -13657 # . epilogue -13658 5d/pop-to-ebp -13659 c3/return -13660 -13661 test-length-with-wrong-output-type: -13662 # . prologue -13663 55/push-ebp -13664 89/<- %ebp 4/r32/esp -13665 # setup -13666 (clear-stream _test-input-stream) -13667 (clear-stream $_test-input-buffered-file->buffer) -13668 (clear-stream _test-output-stream) -13669 (clear-stream $_test-output-buffered-file->buffer) -13670 (clear-stream _test-error-stream) -13671 (clear-stream $_test-error-buffered-file->buffer) -13672 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13673 68/push 0/imm32 -13674 68/push 0/imm32 -13675 89/<- %edx 4/r32/esp -13676 (tailor-exit-descriptor %edx 0x10) -13677 # -13678 (write _test-input-stream "fn foo {\n") -13679 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") -13680 (write _test-input-stream " var o/edi: (addr int) <- length a\n") -13681 (write _test-input-stream "}\n") -13682 # convert -13683 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13684 # registers except esp clobbered at this point -13685 # restore ed -13686 89/<- %edx 4/r32/esp -13687 (flush _test-output-buffered-file) -13688 (flush _test-error-buffered-file) -13689 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13695 # check output -13696 (check-stream-equal _test-output-stream "" "F - test-length-with-wrong-output-type: output should be empty") -13697 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: output 'o' does not have the right type" "F - test-length-with-wrong-output-type: error message") -13698 # check that stop(1) was called -13699 (check-ints-equal *(edx+4) 2 "F - test-length-with-wrong-output-type: exit status") -13700 # don't restore from ebp -13701 81 0/subop/add %esp 8/imm32 -13702 # . epilogue -13703 5d/pop-to-ebp -13704 c3/return -13705 -13706 test-length-with-wrong-output-compound-type: -13707 # . prologue -13708 55/push-ebp -13709 89/<- %ebp 4/r32/esp -13710 # setup -13711 (clear-stream _test-input-stream) -13712 (clear-stream $_test-input-buffered-file->buffer) -13713 (clear-stream _test-output-stream) -13714 (clear-stream $_test-output-buffered-file->buffer) -13715 (clear-stream _test-error-stream) -13716 (clear-stream $_test-error-buffered-file->buffer) -13717 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13718 68/push 0/imm32 -13719 68/push 0/imm32 -13720 89/<- %edx 4/r32/esp -13721 (tailor-exit-descriptor %edx 0x10) -13722 # -13723 (write _test-input-stream "fn foo {\n") -13724 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n") -13725 (write _test-input-stream " var o/edi: (addr handle int) <- length a\n") -13726 (write _test-input-stream "}\n") -13727 # convert -13728 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13729 # registers except esp clobbered at this point -13730 # restore ed -13731 89/<- %edx 4/r32/esp -13732 (flush _test-output-buffered-file) -13733 (flush _test-error-buffered-file) -13734 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13740 # check output -13741 (check-stream-equal _test-output-stream "" "F - test-length-with-wrong-output-compound-type: output should be empty") -13742 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: output 'o' does not have the right type" "F - test-length-with-wrong-output-compound-type: error message") -13743 # check that stop(1) was called -13744 (check-ints-equal *(edx+4) 2 "F - test-length-with-wrong-output-compound-type: exit status") -13745 # don't restore from ebp -13746 81 0/subop/add %esp 8/imm32 -13747 # . epilogue -13748 5d/pop-to-ebp -13749 c3/return -13750 -13751 test-length-with-no-inouts: -13752 # . prologue -13753 55/push-ebp -13754 89/<- %ebp 4/r32/esp -13755 # setup -13756 (clear-stream _test-input-stream) -13757 (clear-stream $_test-input-buffered-file->buffer) -13758 (clear-stream _test-output-stream) -13759 (clear-stream $_test-output-buffered-file->buffer) -13760 (clear-stream _test-error-stream) -13761 (clear-stream $_test-error-buffered-file->buffer) -13762 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13763 68/push 0/imm32 -13764 68/push 0/imm32 -13765 89/<- %edx 4/r32/esp -13766 (tailor-exit-descriptor %edx 0x10) -13767 # -13768 (write _test-input-stream "fn foo {\n") -13769 (write _test-input-stream " var c/ecx: int <- length\n") -13770 (write _test-input-stream "}\n") -13771 # convert -13772 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13773 # registers except esp clobbered at this point -13774 # restore ed -13775 89/<- %edx 4/r32/esp -13776 (flush _test-output-buffered-file) -13777 (flush _test-error-buffered-file) -13778 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13784 # check output -13785 (check-stream-equal _test-output-stream "" "F - test-length-with-no-inouts: output should be empty") -13786 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too few inouts (1 required)" "F - test-length-with-no-inouts: error message") -13787 # check that stop(1) was called -13788 (check-ints-equal *(edx+4) 2 "F - test-length-with-no-inouts: exit status") -13789 # don't restore from ebp -13790 81 0/subop/add %esp 8/imm32 -13791 # . epilogue -13792 5d/pop-to-ebp -13793 c3/return -13794 -13795 test-length-with-too-many-inouts: -13796 # . prologue -13797 55/push-ebp -13798 89/<- %ebp 4/r32/esp -13799 # setup -13800 (clear-stream _test-input-stream) -13801 (clear-stream $_test-input-buffered-file->buffer) -13802 (clear-stream _test-output-stream) -13803 (clear-stream $_test-output-buffered-file->buffer) -13804 (clear-stream _test-error-stream) -13805 (clear-stream $_test-error-buffered-file->buffer) -13806 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13807 68/push 0/imm32 -13808 68/push 0/imm32 -13809 89/<- %edx 4/r32/esp -13810 (tailor-exit-descriptor %edx 0x10) -13811 # -13812 (write _test-input-stream "fn foo {\n") -13813 (write _test-input-stream " var a: (array int 3)\n") -13814 (write _test-input-stream " var c/ecx: int <- length a, 0, 0\n") -13815 (write _test-input-stream "}\n") -13816 # convert -13817 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13818 # registers except esp clobbered at this point -13819 # restore ed -13820 89/<- %edx 4/r32/esp -13821 (flush _test-output-buffered-file) -13822 (flush _test-error-buffered-file) -13823 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13829 # check output -13830 (check-stream-equal _test-output-stream "" "F - test-length-with-too-many-inouts: output should be empty") -13831 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too many inouts (1 required)" "F - test-length-with-too-many-inouts: error message") -13832 # check that stop(1) was called -13833 (check-ints-equal *(edx+4) 2 "F - test-length-with-too-many-inouts: exit status") -13834 # don't restore from ebp -13835 81 0/subop/add %esp 8/imm32 -13836 # . epilogue -13837 5d/pop-to-ebp -13838 c3/return -13839 -13840 test-length-with-no-output: -13841 # . prologue -13842 55/push-ebp -13843 89/<- %ebp 4/r32/esp -13844 # setup -13845 (clear-stream _test-input-stream) -13846 (clear-stream $_test-input-buffered-file->buffer) -13847 (clear-stream _test-output-stream) -13848 (clear-stream $_test-output-buffered-file->buffer) -13849 (clear-stream _test-error-stream) -13850 (clear-stream $_test-error-buffered-file->buffer) -13851 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13852 68/push 0/imm32 -13853 68/push 0/imm32 -13854 89/<- %edx 4/r32/esp -13855 (tailor-exit-descriptor %edx 0x10) -13856 # -13857 (write _test-input-stream "fn foo {\n") -13858 (write _test-input-stream " var a: (array int 3)\n") -13859 (write _test-input-stream " length a\n") -13860 (write _test-input-stream "}\n") -13861 # convert -13862 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13863 # registers except esp clobbered at this point -13864 # restore ed -13865 89/<- %edx 4/r32/esp -13866 (flush _test-output-buffered-file) -13867 (flush _test-error-buffered-file) -13868 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13874 # check output -13875 (check-stream-equal _test-output-stream "" "F - test-length-with-no-output: output should be empty") -13876 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: must have an output" "F - test-length-with-no-output: error message") -13877 # check that stop(1) was called -13878 (check-ints-equal *(edx+4) 2 "F - test-length-with-no-output: exit status") -13879 # don't restore from ebp -13880 81 0/subop/add %esp 8/imm32 -13881 # . epilogue -13882 5d/pop-to-ebp -13883 c3/return -13884 -13885 test-length-with-too-many-outputs: -13886 # . prologue -13887 55/push-ebp -13888 89/<- %ebp 4/r32/esp -13889 # setup -13890 (clear-stream _test-input-stream) -13891 (clear-stream $_test-input-buffered-file->buffer) -13892 (clear-stream _test-output-stream) -13893 (clear-stream $_test-output-buffered-file->buffer) -13894 (clear-stream _test-error-stream) -13895 (clear-stream $_test-error-buffered-file->buffer) -13896 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -13897 68/push 0/imm32 -13898 68/push 0/imm32 -13899 89/<- %edx 4/r32/esp -13900 (tailor-exit-descriptor %edx 0x10) -13901 # -13902 (write _test-input-stream "fn foo {\n") -13903 (write _test-input-stream " var a: (array int 3)\n") -13904 (write _test-input-stream " var b/eax: int <- copy 0\n") -13905 (write _test-input-stream " var c/ecx: int <- copy 0\n") -13906 (write _test-input-stream " b, c <- length a\n") -13907 (write _test-input-stream "}\n") -13908 # convert -13909 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -13910 # registers except esp clobbered at this point -13911 # restore ed -13912 89/<- %edx 4/r32/esp -13913 (flush _test-output-buffered-file) -13914 (flush _test-error-buffered-file) -13915 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -13921 # check output -13922 (check-stream-equal _test-output-stream "" "F - test-length-with-too-many-outputs: output should be empty") -13923 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too many outputs (1 required)" "F - test-length-with-too-many-outputs: error message") -13924 # check that stop(1) was called -13925 (check-ints-equal *(edx+4) 2 "F - test-length-with-too-many-outputs: exit status") -13926 # don't restore from ebp -13927 81 0/subop/add %esp 8/imm32 -13928 # . epilogue -13929 5d/pop-to-ebp -13930 c3/return -13931 -13932 test-convert-function-with-return-register-and-local: -13933 # . prologue -13934 55/push-ebp -13935 89/<- %ebp 4/r32/esp -13936 # setup -13937 (clear-stream _test-input-stream) -13938 (clear-stream $_test-input-buffered-file->buffer) -13939 (clear-stream _test-output-stream) -13940 (clear-stream $_test-output-buffered-file->buffer) -13941 # -13942 (write _test-input-stream "fn foo -> _/eax: int {\n") -13943 (write _test-input-stream " var y/eax: int <- copy 3\n") -13944 (write _test-input-stream " var z/ecx: int <- copy 4\n") -13945 (write _test-input-stream " return y\n") -13946 (write _test-input-stream "}\n") -13947 # convert -13948 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -13949 (flush _test-output-buffered-file) -13950 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -13956 # check output -13957 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register-and-local/0") -13958 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-register-and-local/1") -13959 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register-and-local/2") -13960 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register-and-local/3") -13961 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register-and-local/4") -13962 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register-and-local/5") -13963 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register-and-local/6") -13964 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register-and-local/7") -13965 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-return-register-and-local/8") -13966 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-return-register-and-local/9") -13967 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-return-register-and-local/10") -13968 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-return-register-and-local/11") -13969 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register-and-local/12") -13970 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register-and-local/13") -13971 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register-and-local/14") -13972 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register-and-local/15") -13973 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-register-and-local/16") -13974 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register-and-local/17") -13975 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register-and-local/18") -13976 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register-and-local/19") -13977 # . epilogue -13978 89/<- %esp 5/r32/ebp -13979 5d/pop-to-ebp -13980 c3/return -13981 -13982 test-convert-function-with-return-register-and-local-2: -13983 # . prologue -13984 55/push-ebp -13985 89/<- %ebp 4/r32/esp -13986 # setup -13987 (clear-stream _test-input-stream) -13988 (clear-stream $_test-input-buffered-file->buffer) -13989 (clear-stream _test-output-stream) -13990 (clear-stream $_test-output-buffered-file->buffer) -13991 # -13992 (write _test-input-stream "fn foo -> _/eax: int {\n") -13993 (write _test-input-stream " var y/eax: int <- copy 3\n") -13994 (write _test-input-stream " var z/ecx: int <- copy 4\n") -13995 (write _test-input-stream " return z\n") -13996 (write _test-input-stream "}\n") -13997 # convert -13998 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -13999 (flush _test-output-buffered-file) -14000 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -14006 # check output -14007 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register-and-local-2/0") -14008 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-register-and-local-2/1") -14009 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register-and-local-2/2") -14010 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register-and-local-2/3") -14011 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register-and-local-2/4") -14012 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register-and-local-2/5") -14013 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register-and-local-2/6") -14014 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register-and-local-2/7") -14015 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-return-register-and-local-2/8") -14016 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-return-register-and-local-2/9") -14017 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000000/r32" "F - test-convert-function-with-return-register-and-local-2/10") -14018 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-return-register-and-local-2/11") -14019 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register-and-local-2/12") -14020 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register-and-local-2/13") -14021 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register-and-local-2/14") -14022 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register-and-local-2/15") -14023 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-register-and-local-2/16") -14024 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register-and-local-2/17") -14025 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register-and-local-2/18") -14026 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register-and-local-2/19") -14027 # . epilogue -14028 89/<- %esp 5/r32/ebp -14029 5d/pop-to-ebp -14030 c3/return -14031 -14032 test-convert-function-with-return-float-register-and-local: -14033 # . prologue -14034 55/push-ebp -14035 89/<- %ebp 4/r32/esp -14036 # setup -14037 (clear-stream _test-input-stream) -14038 (clear-stream $_test-input-buffered-file->buffer) -14039 (clear-stream _test-output-stream) -14040 (clear-stream $_test-output-buffered-file->buffer) -14041 # -14042 (write _test-input-stream "fn foo -> _/xmm1: float {\n") -14043 (write _test-input-stream " var y/eax: int <- copy 3\n") -14044 (write _test-input-stream " var g/xmm0: float <- convert y\n") -14045 (write _test-input-stream " var h/xmm1: float <- convert y\n") -14046 (write _test-input-stream " return g\n") -14047 (write _test-input-stream "}\n") -14048 # convert -14049 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -14050 (flush _test-output-buffered-file) -14051 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -14057 # check output -14058 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-float-register-and-local/0") -14059 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-float-register-and-local/1") -14060 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-float-register-and-local/2") -14061 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-float-register-and-local/3") -14062 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-float-register-and-local/4") -14063 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-float-register-and-local/5") -14064 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-float-register-and-local/6") # var y -14065 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-float-register-and-local/7") -14066 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-function-with-return-float-register-and-local/8") # var g -14067 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 0/x32" "F - test-convert-function-with-return-float-register-and-local/9") -14068 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000000/x32" "F - test-convert-function-with-return-float-register-and-local/10") -14069 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-function-with-return-float-register-and-local/11") # var h -14070 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-function-with-return-float-register-and-local/12") -14071 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-function-with-return-float-register-and-local/13") -14072 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> %xmm0 0x00000001/x32" "F - test-convert-function-with-return-float-register-and-local/14") # return g -14073 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/15") # reclaim h -14074 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 0/x32" "F - test-convert-floating-point-dereferenced/16") # reclaim g -14075 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/17") -14076 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-return-float-register-and-local/18") # reclaim y -14077 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-float-register-and-local/19") -14078 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-float-register-and-local/20") -14079 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-float-register-and-local/21") -14080 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-float-register-and-local/22") -14081 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-float-register-and-local/23") -14082 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-float-register-and-local/24") -14083 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-float-register-and-local/25") -14084 # . epilogue -14085 89/<- %esp 5/r32/ebp -14086 5d/pop-to-ebp -14087 c3/return -14088 -14089 test-convert-function-with-return-and-local-vars: -14090 # . prologue -14091 55/push-ebp -14092 89/<- %ebp 4/r32/esp -14093 # setup -14094 (clear-stream _test-input-stream) -14095 (clear-stream $_test-input-buffered-file->buffer) -14096 (clear-stream _test-output-stream) -14097 (clear-stream $_test-output-buffered-file->buffer) -14098 # -14099 (write _test-input-stream "fn foo -> _/eax: int {\n") -14100 (write _test-input-stream " {\n") -14101 (write _test-input-stream " var x: int\n") -14102 (write _test-input-stream " {\n") -14103 (write _test-input-stream " var y: int\n") -14104 (write _test-input-stream " return y\n") -14105 (write _test-input-stream " increment x\n") -14106 (write _test-input-stream " }\n") -14107 (write _test-input-stream " }\n") -14108 (write _test-input-stream " return 0\n") -14109 (write _test-input-stream "}\n") -14110 # convert -14111 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -14112 (flush _test-output-buffered-file) -14113 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -14119 # check output -14120 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-and-local-vars/0") -14121 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-and-local-vars/1") -14122 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-and-local-vars/2") -14123 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-and-local-vars/3") -14124 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/4") -14125 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-and-local-vars/5") -14126 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/6") -14127 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-return-and-local-vars/7") -14128 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return-and-local-vars/8") # var x -14129 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/9") -14130 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-return-and-local-vars/10") -14131 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return-and-local-vars/11") # var y -14132 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-with-return-and-local-vars/12") -14133 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/13") -14134 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/14") -14135 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-and-local-vars/15") -14136 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/16") -14137 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-return-and-local-vars/17") -14138 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/18") -14139 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/19") -14140 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-return-and-local-vars/20") -14141 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy %eax 0/imm32" "F - test-convert-function-with-return-and-local-vars/21") -14142 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-and-local-vars/21") -14143 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/21") -14144 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-and-local-vars/22") -14145 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-and-local-vars/23") -14146 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-and-local-vars/24") -14147 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-and-local-vars/25") -14148 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-and-local-vars/26") -14149 # . epilogue -14150 89/<- %esp 5/r32/ebp -14151 5d/pop-to-ebp -14152 c3/return -14153 -14154 test-copy-object-with-no-inout: -14155 # . prologue -14156 55/push-ebp -14157 89/<- %ebp 4/r32/esp -14158 # setup -14159 (clear-stream _test-input-stream) -14160 (clear-stream $_test-input-buffered-file->buffer) -14161 (clear-stream _test-output-stream) -14162 (clear-stream $_test-output-buffered-file->buffer) -14163 (clear-stream _test-error-stream) -14164 (clear-stream $_test-error-buffered-file->buffer) -14165 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14166 68/push 0/imm32 -14167 68/push 0/imm32 -14168 89/<- %edx 4/r32/esp -14169 (tailor-exit-descriptor %edx 0x10) -14170 # -14171 (write _test-input-stream "fn foo {\n") -14172 (write _test-input-stream " copy-object\n") -14173 (write _test-input-stream "}\n") -14174 # convert -14175 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14176 # registers except esp clobbered at this point -14177 # restore ed -14178 89/<- %edx 4/r32/esp -14179 (flush _test-output-buffered-file) -14180 (flush _test-error-buffered-file) -14181 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14187 # check output -14188 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-no-inout: output should be empty") -14189 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-no-inout: error message") -14190 # check that stop(1) was called -14191 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-no-inout: exit status") -14192 # don't restore from ebp -14193 81 0/subop/add %esp 8/imm32 -14194 # . epilogue -14195 5d/pop-to-ebp -14196 c3/return -14197 -14198 test-copy-object-with-no-source: -14199 # . prologue -14200 55/push-ebp -14201 89/<- %ebp 4/r32/esp -14202 # setup -14203 (clear-stream _test-input-stream) -14204 (clear-stream $_test-input-buffered-file->buffer) -14205 (clear-stream _test-output-stream) -14206 (clear-stream $_test-output-buffered-file->buffer) -14207 (clear-stream _test-error-stream) -14208 (clear-stream $_test-error-buffered-file->buffer) -14209 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14210 68/push 0/imm32 -14211 68/push 0/imm32 -14212 89/<- %edx 4/r32/esp -14213 (tailor-exit-descriptor %edx 0x10) -14214 # -14215 (write _test-input-stream "fn foo {\n") -14216 (write _test-input-stream " var x: (addr int)\n") -14217 (write _test-input-stream " copy-object x\n") -14218 (write _test-input-stream "}\n") -14219 # convert -14220 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14221 # registers except esp clobbered at this point -14222 # restore ed -14223 89/<- %edx 4/r32/esp -14224 (flush _test-output-buffered-file) -14225 (flush _test-error-buffered-file) -14226 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14232 # check output -14233 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-no-source: output should be empty") -14234 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-no-source: error message") -14235 # check that stop(1) was called -14236 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-no-source: exit status") -14237 # don't restore from ebp -14238 81 0/subop/add %esp 8/imm32 -14239 # . epilogue -14240 5d/pop-to-ebp -14241 c3/return -14242 -14243 test-copy-object-with-too-many-inouts: -14244 # . prologue -14245 55/push-ebp -14246 89/<- %ebp 4/r32/esp -14247 # setup -14248 (clear-stream _test-input-stream) -14249 (clear-stream $_test-input-buffered-file->buffer) -14250 (clear-stream _test-output-stream) -14251 (clear-stream $_test-output-buffered-file->buffer) -14252 (clear-stream _test-error-stream) -14253 (clear-stream $_test-error-buffered-file->buffer) -14254 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14255 68/push 0/imm32 -14256 68/push 0/imm32 -14257 89/<- %edx 4/r32/esp -14258 (tailor-exit-descriptor %edx 0x10) -14259 # -14260 (write _test-input-stream "fn foo {\n") -14261 (write _test-input-stream " var x: (addr boolean)\n") -14262 (write _test-input-stream " copy-object x, x, x\n") -14263 (write _test-input-stream "}\n") -14264 # convert -14265 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14266 # registers except esp clobbered at this point -14267 # restore ed -14268 89/<- %edx 4/r32/esp -14269 (flush _test-output-buffered-file) -14270 (flush _test-error-buffered-file) -14271 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14277 # check output -14278 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-too-many-inouts: output should be empty") -14279 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-too-many-inouts: error message") -14280 # check that stop(1) was called -14281 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-too-many-inouts: exit status") -14282 # don't restore from ebp -14283 81 0/subop/add %esp 8/imm32 -14284 # . epilogue -14285 5d/pop-to-ebp -14286 c3/return -14287 -14288 test-copy-object-with-output: -14289 # . prologue -14290 55/push-ebp -14291 89/<- %ebp 4/r32/esp -14292 # setup -14293 (clear-stream _test-input-stream) -14294 (clear-stream $_test-input-buffered-file->buffer) -14295 (clear-stream _test-output-stream) -14296 (clear-stream $_test-output-buffered-file->buffer) -14297 (clear-stream _test-error-stream) -14298 (clear-stream $_test-error-buffered-file->buffer) -14299 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14300 68/push 0/imm32 -14301 68/push 0/imm32 -14302 89/<- %edx 4/r32/esp -14303 (tailor-exit-descriptor %edx 0x10) -14304 # -14305 (write _test-input-stream "fn foo {\n") -14306 (write _test-input-stream " var x/eax: (addr boolean) <- copy 0\n") -14307 (write _test-input-stream " var y/ecx: (addr boolean) <- copy 0\n") -14308 (write _test-input-stream " x <- copy-object x, y\n") -14309 (write _test-input-stream "}\n") -14310 # convert -14311 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14312 # registers except esp clobbered at this point -14313 # restore ed -14314 89/<- %edx 4/r32/esp -14315 (flush _test-output-buffered-file) -14316 (flush _test-error-buffered-file) -14317 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14323 # check output -14324 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-output: output should be empty") -14325 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must not have any outputs" "F - test-copy-object-with-output: error message") -14326 # check that stop(1) was called -14327 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-output: exit status") -14328 # don't restore from ebp -14329 81 0/subop/add %esp 8/imm32 -14330 # . epilogue -14331 5d/pop-to-ebp -14332 c3/return -14333 -14334 test-copy-object-deref-address: -14335 # . prologue -14336 55/push-ebp -14337 89/<- %ebp 4/r32/esp -14338 # setup -14339 (clear-stream _test-input-stream) -14340 (clear-stream $_test-input-buffered-file->buffer) -14341 (clear-stream _test-output-stream) -14342 (clear-stream $_test-output-buffered-file->buffer) -14343 # -14344 (write _test-input-stream "fn foo {\n") -14345 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") -14346 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n") -14347 (write _test-input-stream " copy-object *y, x\n") -14348 (write _test-input-stream "}\n") -14349 # convert -14350 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -14351 (flush _test-output-buffered-file) -14352 # no errors +10008 # +10009 (write _test-input-stream "fn foo {\n") +10010 (write _test-input-stream " var x: (stream int 3)\n") +10011 (write _test-input-stream " var y/eax: (addr stream int) <- address x\n") +10012 (write _test-input-stream "}\n") +10013 # convert +10014 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +10015 (flush _test-output-buffered-file) +10016 # no errors +10017 # . epilogue +10018 89/<- %esp 5/r32/ebp +10019 5d/pop-to-ebp +10020 c3/return +10021 +10022 test-get-with-wrong-field: +10023 # . prologue +10024 55/push-ebp +10025 89/<- %ebp 4/r32/esp +10026 # setup +10027 (clear-stream _test-input-stream) +10028 (clear-stream $_test-input-buffered-file->buffer) +10029 (clear-stream _test-output-stream) +10030 (clear-stream $_test-output-buffered-file->buffer) +10031 (clear-stream _test-error-stream) +10032 (clear-stream $_test-error-buffered-file->buffer) +10033 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10034 68/push 0/imm32 +10035 68/push 0/imm32 +10036 89/<- %edx 4/r32/esp +10037 (tailor-exit-descriptor %edx 0x10) +10038 # +10039 (write _test-input-stream "fn foo {\n") +10040 (write _test-input-stream " var a: t\n") +10041 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") +10042 (write _test-input-stream "}\n") +10043 (write _test-input-stream "type t {\n") +10044 (write _test-input-stream " x: int\n") +10045 (write _test-input-stream "}\n") +10046 # convert +10047 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10048 # registers except esp clobbered at this point +10049 # restore ed +10050 89/<- %edx 4/r32/esp +10051 (flush _test-output-buffered-file) +10052 (flush _test-error-buffered-file) +10053 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10059 # check output +10060 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty") +10061 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'y'" "F - test-get-with-wrong-field: error message") +10062 # check that stop(1) was called +10063 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status") +10064 # don't restore from ebp +10065 81 0/subop/add %esp 8/imm32 +10066 # . epilogue +10067 5d/pop-to-ebp +10068 c3/return +10069 +10070 test-get-with-wrong-base-type: +10071 # . prologue +10072 55/push-ebp +10073 89/<- %ebp 4/r32/esp +10074 # setup +10075 (clear-stream _test-input-stream) +10076 (clear-stream $_test-input-buffered-file->buffer) +10077 (clear-stream _test-output-stream) +10078 (clear-stream $_test-output-buffered-file->buffer) +10079 (clear-stream _test-error-stream) +10080 (clear-stream $_test-error-buffered-file->buffer) +10081 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10082 68/push 0/imm32 +10083 68/push 0/imm32 +10084 89/<- %edx 4/r32/esp +10085 (tailor-exit-descriptor %edx 0x10) +10086 # +10087 (write _test-input-stream "fn foo {\n") +10088 (write _test-input-stream " var a: int\n") +10089 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") +10090 (write _test-input-stream "}\n") +10091 # convert +10092 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10093 # registers except esp clobbered at this point +10094 # restore ed +10095 89/<- %edx 4/r32/esp +10096 (flush _test-output-buffered-file) +10097 (flush _test-error-buffered-file) +10098 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10104 # check output +10105 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type: output should be empty") +10106 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' must have a 'type' definition" "F - test-get-with-wrong-base-type: error message") +10107 # check that stop(1) was called +10108 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status") +10109 # don't restore from ebp +10110 81 0/subop/add %esp 8/imm32 +10111 # . epilogue +10112 5d/pop-to-ebp +10113 c3/return +10114 +10115 test-get-with-wrong-base-type-2: +10116 # . prologue +10117 55/push-ebp +10118 89/<- %ebp 4/r32/esp +10119 # setup +10120 (clear-stream _test-input-stream) +10121 (clear-stream $_test-input-buffered-file->buffer) +10122 (clear-stream _test-output-stream) +10123 (clear-stream $_test-output-buffered-file->buffer) +10124 (clear-stream _test-error-stream) +10125 (clear-stream $_test-error-buffered-file->buffer) +10126 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10127 68/push 0/imm32 +10128 68/push 0/imm32 +10129 89/<- %edx 4/r32/esp +10130 (tailor-exit-descriptor %edx 0x10) +10131 # +10132 (write _test-input-stream "fn foo {\n") +10133 (write _test-input-stream " var a: (addr t)\n") +10134 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") +10135 (write _test-input-stream "}\n") +10136 (write _test-input-stream "type t {\n") +10137 (write _test-input-stream " x: int\n") +10138 (write _test-input-stream "}\n") +10139 # convert +10140 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10141 # registers except esp clobbered at this point +10142 # restore ed +10143 89/<- %edx 4/r32/esp +10144 (flush _test-output-buffered-file) +10145 (flush _test-error-buffered-file) +10146 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10152 # check output +10153 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-2: output should be empty") +10154 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' is an 'addr' type, and so must live in a register" "F - test-get-with-wrong-base-type-2: error message") +10155 # check that stop(1) was called +10156 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status") +10157 # don't restore from ebp +10158 81 0/subop/add %esp 8/imm32 +10159 # . epilogue +10160 5d/pop-to-ebp +10161 c3/return +10162 +10163 test-get-with-wrong-base-type-3: +10164 # . prologue +10165 55/push-ebp +10166 89/<- %ebp 4/r32/esp +10167 # setup +10168 (clear-stream _test-input-stream) +10169 (clear-stream $_test-input-buffered-file->buffer) +10170 (clear-stream _test-output-stream) +10171 (clear-stream $_test-output-buffered-file->buffer) +10172 (clear-stream _test-error-stream) +10173 (clear-stream $_test-error-buffered-file->buffer) +10174 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10175 68/push 0/imm32 +10176 68/push 0/imm32 +10177 89/<- %edx 4/r32/esp +10178 (tailor-exit-descriptor %edx 0x10) +10179 # +10180 (write _test-input-stream "fn foo {\n") +10181 (write _test-input-stream " var a: (handle int)\n") +10182 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") +10183 (write _test-input-stream "}\n") +10184 # convert +10185 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10186 # registers except esp clobbered at this point +10187 # restore ed +10188 89/<- %edx 4/r32/esp +10189 (flush _test-output-buffered-file) +10190 (flush _test-error-buffered-file) +10191 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10197 # check output +10198 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-3: output should be empty") +10199 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' must have a 'type' definition" "F - test-get-with-wrong-base-type-3: error message") +10200 # check that stop(1) was called +10201 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-3: exit status") +10202 # don't restore from ebp +10203 81 0/subop/add %esp 8/imm32 +10204 # . epilogue +10205 5d/pop-to-ebp +10206 c3/return +10207 +10208 test-get-with-wrong-offset-type: +10209 # . prologue +10210 55/push-ebp +10211 89/<- %ebp 4/r32/esp +10212 # setup +10213 (clear-stream _test-input-stream) +10214 (clear-stream $_test-input-buffered-file->buffer) +10215 (clear-stream _test-output-stream) +10216 (clear-stream $_test-output-buffered-file->buffer) +10217 (clear-stream _test-error-stream) +10218 (clear-stream $_test-error-buffered-file->buffer) +10219 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10220 68/push 0/imm32 +10221 68/push 0/imm32 +10222 89/<- %edx 4/r32/esp +10223 (tailor-exit-descriptor %edx 0x10) +10224 # +10225 (write _test-input-stream "fn foo {\n") +10226 (write _test-input-stream " var a: t\n") +10227 (write _test-input-stream " var b: int\n") +10228 (write _test-input-stream " var c/ecx: (addr int) <- get a, b\n") +10229 (write _test-input-stream "}\n") +10230 (write _test-input-stream "type t {\n") +10231 (write _test-input-stream " x: int\n") +10232 (write _test-input-stream "}\n") +10233 # convert +10234 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10235 # registers except esp clobbered at this point +10236 # restore ed +10237 89/<- %edx 4/r32/esp +10238 (flush _test-output-buffered-file) +10239 (flush _test-error-buffered-file) +10240 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10246 # check output +10247 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-offset-type: output should be empty") +10248 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'b'" "F - test-get-with-wrong-offset-type: error message") +10249 # check that stop(1) was called +10250 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: exit status") +10251 # don't restore from ebp +10252 81 0/subop/add %esp 8/imm32 +10253 # . epilogue +10254 5d/pop-to-ebp +10255 c3/return +10256 +10257 test-get-with-wrong-output-type: +10258 # . prologue +10259 55/push-ebp +10260 89/<- %ebp 4/r32/esp +10261 # setup +10262 (clear-stream _test-input-stream) +10263 (clear-stream $_test-input-buffered-file->buffer) +10264 (clear-stream _test-output-stream) +10265 (clear-stream $_test-output-buffered-file->buffer) +10266 (clear-stream _test-error-stream) +10267 (clear-stream $_test-error-buffered-file->buffer) +10268 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10269 68/push 0/imm32 +10270 68/push 0/imm32 +10271 89/<- %edx 4/r32/esp +10272 (tailor-exit-descriptor %edx 0x10) +10273 # +10274 (write _test-input-stream "fn foo {\n") +10275 (write _test-input-stream " var a: t\n") +10276 (write _test-input-stream " var c: (addr int)\n") +10277 (write _test-input-stream " c <- get a, x\n") +10278 (write _test-input-stream "}\n") +10279 (write _test-input-stream "type t {\n") +10280 (write _test-input-stream " x: int\n") +10281 (write _test-input-stream "}\n") +10282 # convert +10283 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10284 # registers except esp clobbered at this point +10285 # restore ed +10286 89/<- %edx 4/r32/esp +10287 (flush _test-output-buffered-file) +10288 (flush _test-error-buffered-file) +10289 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10295 # check output +10296 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type: output should be empty") +10297 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output 'c' is not in a register" "F - test-get-with-wrong-output-type: error message") +10298 # check that stop(1) was called +10299 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type: exit status") +10300 # don't restore from ebp +10301 81 0/subop/add %esp 8/imm32 +10302 # . epilogue +10303 5d/pop-to-ebp +10304 c3/return +10305 +10306 test-get-with-wrong-output-type-2: +10307 # . prologue +10308 55/push-ebp +10309 89/<- %ebp 4/r32/esp +10310 # setup +10311 (clear-stream _test-input-stream) +10312 (clear-stream $_test-input-buffered-file->buffer) +10313 (clear-stream _test-output-stream) +10314 (clear-stream $_test-output-buffered-file->buffer) +10315 (clear-stream _test-error-stream) +10316 (clear-stream $_test-error-buffered-file->buffer) +10317 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10318 68/push 0/imm32 +10319 68/push 0/imm32 +10320 89/<- %edx 4/r32/esp +10321 (tailor-exit-descriptor %edx 0x10) +10322 # +10323 (write _test-input-stream "fn foo {\n") +10324 (write _test-input-stream " var a: t\n") +10325 (write _test-input-stream " var c/ecx: int <- get a, x\n") +10326 (write _test-input-stream "}\n") +10327 (write _test-input-stream "type t {\n") +10328 (write _test-input-stream " x: int\n") +10329 (write _test-input-stream "}\n") +10330 # convert +10331 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10332 # registers except esp clobbered at this point +10333 # restore ed +10334 89/<- %edx 4/r32/esp +10335 (flush _test-output-buffered-file) +10336 (flush _test-error-buffered-file) +10337 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10343 # check output +10344 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-2: output should be empty") +10345 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an addr" "F - test-get-with-wrong-output-type-2: error message") +10346 # check that stop(1) was called +10347 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status") +10348 # don't restore from ebp +10349 81 0/subop/add %esp 8/imm32 +10350 # . epilogue +10351 5d/pop-to-ebp +10352 c3/return +10353 +10354 test-get-with-wrong-output-type-3: +10355 # . prologue +10356 55/push-ebp +10357 89/<- %ebp 4/r32/esp +10358 # setup +10359 (clear-stream _test-input-stream) +10360 (clear-stream $_test-input-buffered-file->buffer) +10361 (clear-stream _test-output-stream) +10362 (clear-stream $_test-output-buffered-file->buffer) +10363 (clear-stream _test-error-stream) +10364 (clear-stream $_test-error-buffered-file->buffer) +10365 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10366 68/push 0/imm32 +10367 68/push 0/imm32 +10368 89/<- %edx 4/r32/esp +10369 (tailor-exit-descriptor %edx 0x10) +10370 # +10371 (write _test-input-stream "fn foo {\n") +10372 (write _test-input-stream " var a: t\n") +10373 (write _test-input-stream " var c/ecx: (array int) <- get a, x\n") +10374 (write _test-input-stream "}\n") +10375 (write _test-input-stream "type t {\n") +10376 (write _test-input-stream " x: int\n") +10377 (write _test-input-stream "}\n") +10378 # convert +10379 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10380 # registers except esp clobbered at this point +10381 # restore ed +10382 89/<- %edx 4/r32/esp +10383 (flush _test-output-buffered-file) +10384 (flush _test-error-buffered-file) +10385 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10391 # check output +10392 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-3: output should be empty") +10393 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an addr" "F - test-get-with-wrong-output-type-3: error message") +10394 # check that stop(1) was called +10395 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status") +10396 # don't restore from ebp +10397 81 0/subop/add %esp 8/imm32 +10398 # . epilogue +10399 5d/pop-to-ebp +10400 c3/return +10401 +10402 test-get-with-wrong-output-type-4: +10403 # . prologue +10404 55/push-ebp +10405 89/<- %ebp 4/r32/esp +10406 # setup +10407 (clear-stream _test-input-stream) +10408 (clear-stream $_test-input-buffered-file->buffer) +10409 (clear-stream _test-output-stream) +10410 (clear-stream $_test-output-buffered-file->buffer) +10411 (clear-stream _test-error-stream) +10412 (clear-stream $_test-error-buffered-file->buffer) +10413 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10414 68/push 0/imm32 +10415 68/push 0/imm32 +10416 89/<- %edx 4/r32/esp +10417 (tailor-exit-descriptor %edx 0x10) +10418 # +10419 (write _test-input-stream "fn foo {\n") +10420 (write _test-input-stream " var a: t\n") +10421 (write _test-input-stream " var c/ecx: (addr boolean) <- get a, x\n") +10422 (write _test-input-stream "}\n") +10423 (write _test-input-stream "type t {\n") +10424 (write _test-input-stream " x: int\n") +10425 (write _test-input-stream "}\n") +10426 # convert +10427 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10428 # registers except esp clobbered at this point +10429 # restore ed +10430 89/<- %edx 4/r32/esp +10431 (flush _test-output-buffered-file) +10432 (flush _test-error-buffered-file) +10433 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10439 # check output +10440 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-4: output should be empty") +10441 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: wrong output type for member 'x' of type 't'" "F - test-get-with-wrong-output-type-4: error message") +10442 # check that stop(1) was called +10443 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status") +10444 # don't restore from ebp +10445 81 0/subop/add %esp 8/imm32 +10446 # . epilogue +10447 5d/pop-to-ebp +10448 c3/return +10449 +10450 test-get-with-wrong-output-type-5: +10451 # . prologue +10452 55/push-ebp +10453 89/<- %ebp 4/r32/esp +10454 # setup +10455 (clear-stream _test-input-stream) +10456 (clear-stream $_test-input-buffered-file->buffer) +10457 (clear-stream _test-output-stream) +10458 (clear-stream $_test-output-buffered-file->buffer) +10459 # +10460 (write _test-input-stream "fn foo {\n") +10461 (write _test-input-stream " var a: t\n") +10462 (write _test-input-stream " var c/ecx: (addr handle int) <- get a, x\n") +10463 (write _test-input-stream "}\n") +10464 (write _test-input-stream "type t {\n") +10465 (write _test-input-stream " x: (handle int)\n") +10466 (write _test-input-stream "}\n") +10467 # convert +10468 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +10469 (flush _test-output-buffered-file) +10470 # no errors +10471 # . epilogue +10472 89/<- %esp 5/r32/ebp +10473 5d/pop-to-ebp +10474 c3/return +10475 +10476 test-get-with-too-few-inouts: +10477 # . prologue +10478 55/push-ebp +10479 89/<- %ebp 4/r32/esp +10480 # setup +10481 (clear-stream _test-input-stream) +10482 (clear-stream $_test-input-buffered-file->buffer) +10483 (clear-stream _test-output-stream) +10484 (clear-stream $_test-output-buffered-file->buffer) +10485 (clear-stream _test-error-stream) +10486 (clear-stream $_test-error-buffered-file->buffer) +10487 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10488 68/push 0/imm32 +10489 68/push 0/imm32 +10490 89/<- %edx 4/r32/esp +10491 (tailor-exit-descriptor %edx 0x10) +10492 # +10493 (write _test-input-stream "fn foo {\n") +10494 (write _test-input-stream " var a: t\n") +10495 (write _test-input-stream " var c/ecx: (addr int) <- get a\n") +10496 (write _test-input-stream "}\n") +10497 (write _test-input-stream "type t {\n") +10498 (write _test-input-stream " x: int\n") +10499 (write _test-input-stream "}\n") +10500 # convert +10501 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10502 # registers except esp clobbered at this point +10503 # restore ed +10504 89/<- %edx 4/r32/esp +10505 (flush _test-output-buffered-file) +10506 (flush _test-error-buffered-file) +10507 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10513 # check output +10514 (check-stream-equal _test-output-stream "" "F - test-get-with-too-few-inouts: output should be empty") +10515 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too few inouts (2 required)" "F - test-get-with-too-few-inouts: error message") +10516 # check that stop(1) was called +10517 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-few-inouts: exit status") +10518 # don't restore from ebp +10519 81 0/subop/add %esp 8/imm32 +10520 # . epilogue +10521 5d/pop-to-ebp +10522 c3/return +10523 +10524 test-get-with-too-many-inouts: +10525 # . prologue +10526 55/push-ebp +10527 89/<- %ebp 4/r32/esp +10528 # setup +10529 (clear-stream _test-input-stream) +10530 (clear-stream $_test-input-buffered-file->buffer) +10531 (clear-stream _test-output-stream) +10532 (clear-stream $_test-output-buffered-file->buffer) +10533 (clear-stream _test-error-stream) +10534 (clear-stream $_test-error-buffered-file->buffer) +10535 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10536 68/push 0/imm32 +10537 68/push 0/imm32 +10538 89/<- %edx 4/r32/esp +10539 (tailor-exit-descriptor %edx 0x10) +10540 # +10541 (write _test-input-stream "fn foo {\n") +10542 (write _test-input-stream " var a: t\n") +10543 (write _test-input-stream " var c/ecx: (addr int) <- get a, x, 0\n") +10544 (write _test-input-stream "}\n") +10545 (write _test-input-stream "type t {\n") +10546 (write _test-input-stream " x: int\n") +10547 (write _test-input-stream "}\n") +10548 # convert +10549 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10550 # registers except esp clobbered at this point +10551 # restore ed +10552 89/<- %edx 4/r32/esp +10553 (flush _test-output-buffered-file) +10554 (flush _test-error-buffered-file) +10555 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10561 # check output +10562 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-inouts: output should be empty") +10563 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many inouts (2 required)" "F - test-get-with-too-many-inouts: error message") +10564 # check that stop(1) was called +10565 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-inouts: exit status") +10566 # don't restore from ebp +10567 81 0/subop/add %esp 8/imm32 +10568 # . epilogue +10569 5d/pop-to-ebp +10570 c3/return +10571 +10572 test-get-with-no-output: +10573 # . prologue +10574 55/push-ebp +10575 89/<- %ebp 4/r32/esp +10576 # setup +10577 (clear-stream _test-input-stream) +10578 (clear-stream $_test-input-buffered-file->buffer) +10579 (clear-stream _test-output-stream) +10580 (clear-stream $_test-output-buffered-file->buffer) +10581 (clear-stream _test-error-stream) +10582 (clear-stream $_test-error-buffered-file->buffer) +10583 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10584 68/push 0/imm32 +10585 68/push 0/imm32 +10586 89/<- %edx 4/r32/esp +10587 (tailor-exit-descriptor %edx 0x10) +10588 # +10589 (write _test-input-stream "fn foo {\n") +10590 (write _test-input-stream " var a: t\n") +10591 (write _test-input-stream " get a, x\n") +10592 (write _test-input-stream "}\n") +10593 (write _test-input-stream "type t {\n") +10594 (write _test-input-stream " x: int\n") +10595 (write _test-input-stream "}\n") +10596 # convert +10597 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10598 # registers except esp clobbered at this point +10599 # restore ed +10600 89/<- %edx 4/r32/esp +10601 (flush _test-output-buffered-file) +10602 (flush _test-error-buffered-file) +10603 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10609 # check output +10610 (check-stream-equal _test-output-stream "" "F - test-get-with-no-output: output should be empty") +10611 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: must have an output" "F - test-get-with-no-output: error message") +10612 # check that stop(1) was called +10613 (check-ints-equal *(edx+4) 2 "F - test-get-with-no-output: exit status") +10614 # don't restore from ebp +10615 81 0/subop/add %esp 8/imm32 +10616 # . epilogue +10617 5d/pop-to-ebp +10618 c3/return +10619 +10620 test-get-with-too-many-outputs: +10621 # . prologue +10622 55/push-ebp +10623 89/<- %ebp 4/r32/esp +10624 # setup +10625 (clear-stream _test-input-stream) +10626 (clear-stream $_test-input-buffered-file->buffer) +10627 (clear-stream _test-output-stream) +10628 (clear-stream $_test-output-buffered-file->buffer) +10629 (clear-stream _test-error-stream) +10630 (clear-stream $_test-error-buffered-file->buffer) +10631 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10632 68/push 0/imm32 +10633 68/push 0/imm32 +10634 89/<- %edx 4/r32/esp +10635 (tailor-exit-descriptor %edx 0x10) +10636 # +10637 (write _test-input-stream "fn foo {\n") +10638 (write _test-input-stream " var a: t\n") +10639 (write _test-input-stream " var b: int\n") +10640 (write _test-input-stream " var c/eax: (addr int) <- copy 0\n") +10641 (write _test-input-stream " c, b <- get a, x\n") +10642 (write _test-input-stream "}\n") +10643 (write _test-input-stream "type t {\n") +10644 (write _test-input-stream " x: int\n") +10645 (write _test-input-stream "}\n") +10646 # convert +10647 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +10648 # registers except esp clobbered at this point +10649 # restore ed +10650 89/<- %edx 4/r32/esp +10651 (flush _test-output-buffered-file) +10652 (flush _test-error-buffered-file) +10653 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +10659 # check output +10660 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-outputs: output should be empty") +10661 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many outputs (1 required)" "F - test-get-with-too-many-outputs: error message") +10662 # check that stop(1) was called +10663 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-outputs: exit status") +10664 # don't restore from ebp +10665 81 0/subop/add %esp 8/imm32 +10666 # . epilogue +10667 5d/pop-to-ebp +10668 c3/return +10669 +10670 test-convert-array-of-user-defined-types: +10671 # . prologue +10672 55/push-ebp +10673 89/<- %ebp 4/r32/esp +10674 # setup +10675 (clear-stream _test-input-stream) +10676 (clear-stream $_test-input-buffered-file->buffer) +10677 (clear-stream _test-output-stream) +10678 (clear-stream $_test-output-buffered-file->buffer) +10679 # +10680 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 +10681 (write _test-input-stream " x: int\n") +10682 (write _test-input-stream " y: int\n") +10683 (write _test-input-stream "}\n") +10684 (write _test-input-stream "fn foo {\n") +10685 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") +10686 (write _test-input-stream " var idx/ecx: int <- copy 3\n") +10687 (write _test-input-stream " var x/eax: (addr t) <- index arr, idx\n") +10688 (write _test-input-stream "}\n") +10689 # convert +10690 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +10691 (flush _test-output-buffered-file) +10692 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +10698 # check output +10699 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") +10700 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") +10701 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") +10702 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") +10703 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") +10704 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") +10705 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") +10706 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") +10707 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") +10708 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") +10709 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000008 *eax \"foo\" \"arr\")" "F - test-convert-array-of-user-defined-types/10") +10710 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-array-of-user-defined-types/12") +10711 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-array-of-user-defined-types/13") +10712 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000003 + 4) 0x00000000/r32" "F - test-convert-array-of-user-defined-types/14") +10713 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/15") +10714 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/16") +10715 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/17") +10716 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/18") +10717 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/19") +10718 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/20") +10719 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/21") +10720 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/22") +10721 # . epilogue +10722 89/<- %esp 5/r32/ebp +10723 5d/pop-to-ebp +10724 c3/return +10725 +10726 test-convert-length-of-array-of-user-defined-types-to-eax: +10727 # . prologue +10728 55/push-ebp +10729 89/<- %ebp 4/r32/esp +10730 # setup +10731 (clear-stream _test-input-stream) +10732 (clear-stream $_test-input-buffered-file->buffer) +10733 (clear-stream _test-output-stream) +10734 (clear-stream $_test-output-buffered-file->buffer) +10735 # +10736 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 +10737 (write _test-input-stream " x: int\n") +10738 (write _test-input-stream " y: int\n") +10739 (write _test-input-stream " z: int\n") +10740 (write _test-input-stream "}\n") +10741 (write _test-input-stream "fn foo {\n") +10742 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") +10743 (write _test-input-stream " var x/eax: int <- length arr\n") +10744 (write _test-input-stream "}\n") +10745 # convert +10746 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +10747 (flush _test-output-buffered-file) +10748 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +10754 # check output +10755 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") +10756 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") +10757 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") +10758 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/3") +10759 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") +10760 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") +10761 # var arr +10762 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/6") +10763 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/7") +10764 # length instruction +10765 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") +10766 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") +10767 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/10") +10768 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/11") +10769 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/12") +10770 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/13") +10771 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/14") +10772 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/15") +10773 # reclaim arr +10774 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/16") +10775 # +10776 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") +10777 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") +10778 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") +10779 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/20") +10780 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/21") +10781 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") +10782 # . epilogue +10783 89/<- %esp 5/r32/ebp +10784 5d/pop-to-ebp +10785 c3/return +10786 +10787 test-convert-length-of-array-of-user-defined-types-to-ecx: +10788 # . prologue +10789 55/push-ebp +10790 89/<- %ebp 4/r32/esp +10791 # setup +10792 (clear-stream _test-input-stream) +10793 (clear-stream $_test-input-buffered-file->buffer) +10794 (clear-stream _test-output-stream) +10795 (clear-stream $_test-output-buffered-file->buffer) +10796 # +10797 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 +10798 (write _test-input-stream " x: int\n") +10799 (write _test-input-stream " y: int\n") +10800 (write _test-input-stream " z: int\n") +10801 (write _test-input-stream "}\n") +10802 (write _test-input-stream "fn foo {\n") +10803 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") +10804 (write _test-input-stream " var x/ecx: int <- length arr\n") +10805 (write _test-input-stream "}\n") +10806 # convert +10807 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +10808 (flush _test-output-buffered-file) +10809 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +10815 # check output +10816 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") +10817 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") +10818 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") +10819 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/3") +10820 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") +10821 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") +10822 # var a +10823 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/6") +10824 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/7") +10825 # var x +10826 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/8") +10827 # length instruction +10828 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") +10829 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") +10830 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/11") +10831 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/12") +10832 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/13") +10833 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/14") +10834 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/15") +10835 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/16") +10836 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/17") +10837 # reclaim x +10838 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/18") +10839 # reclaim a +10840 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/19") +10841 # +10842 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") +10843 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") +10844 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") +10845 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/23") +10846 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/24") +10847 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") +10848 # . epilogue +10849 89/<- %esp 5/r32/ebp +10850 5d/pop-to-ebp +10851 c3/return +10852 +10853 test-convert-length-of-array-of-user-defined-types-to-edx: +10854 # . prologue +10855 55/push-ebp +10856 89/<- %ebp 4/r32/esp +10857 # setup +10858 (clear-stream _test-input-stream) +10859 (clear-stream $_test-input-buffered-file->buffer) +10860 (clear-stream _test-output-stream) +10861 (clear-stream $_test-output-buffered-file->buffer) +10862 # +10863 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 +10864 (write _test-input-stream " x: int\n") +10865 (write _test-input-stream " y: int\n") +10866 (write _test-input-stream " z: int\n") +10867 (write _test-input-stream "}\n") +10868 (write _test-input-stream "fn foo {\n") +10869 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") +10870 (write _test-input-stream " var x/edx: int <- length arr\n") +10871 (write _test-input-stream "}\n") +10872 # convert +10873 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +10874 (flush _test-output-buffered-file) +10875 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +10881 # check output +10882 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") +10883 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") +10884 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") +10885 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/3") +10886 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") +10887 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") +10888 # var a +10889 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/6") +10890 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/7") +10891 # var x +10892 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/8") +10893 # length instruction +10894 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") +10895 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") +10896 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/11") +10897 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/12") +10898 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/13") +10899 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/14") +10900 (check-next-stream-line-equal _test-output-stream " 89/<- %edx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/15") +10901 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/16") +10902 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/17") +10903 # reclaim x +10904 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/18") +10905 # reclaim a +10906 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/19") +10907 # +10908 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") +10909 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") +10910 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") +10911 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/23") +10912 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/24") +10913 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") +10914 # . epilogue +10915 89/<- %esp 5/r32/ebp +10916 5d/pop-to-ebp +10917 c3/return +10918 +10919 test-convert-length-of-array-of-user-defined-types: +10920 # . prologue +10921 55/push-ebp +10922 89/<- %ebp 4/r32/esp +10923 # setup +10924 (clear-stream _test-input-stream) +10925 (clear-stream $_test-input-buffered-file->buffer) +10926 (clear-stream _test-output-stream) +10927 (clear-stream $_test-output-buffered-file->buffer) +10928 # +10929 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 +10930 (write _test-input-stream " x: int\n") +10931 (write _test-input-stream " y: int\n") +10932 (write _test-input-stream " z: int\n") +10933 (write _test-input-stream "}\n") +10934 (write _test-input-stream "fn foo {\n") +10935 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") +10936 (write _test-input-stream " var x/ebx: int <- length arr\n") +10937 (write _test-input-stream "}\n") +10938 # convert +10939 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +10940 (flush _test-output-buffered-file) +10941 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +10947 # check output +10948 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") +10949 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") +10950 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") +10951 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") +10952 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") +10953 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") +10954 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") +10955 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types/7") +10956 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") +10957 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") +10958 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") +10959 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") +10960 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") +10961 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types/13") +10962 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types/14") +10963 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types/15") +10964 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") +10965 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") +10966 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") +10967 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") +10968 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") +10969 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") +10970 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") +10971 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") +10972 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") +10973 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") +10974 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") +10975 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") +10976 # . epilogue +10977 89/<- %esp 5/r32/ebp +10978 5d/pop-to-ebp +10979 c3/return +10980 +10981 test-index-with-non-array-atom-base-type: +10982 # . prologue +10983 55/push-ebp +10984 89/<- %ebp 4/r32/esp +10985 # setup +10986 (clear-stream _test-input-stream) +10987 (clear-stream $_test-input-buffered-file->buffer) +10988 (clear-stream _test-output-stream) +10989 (clear-stream $_test-output-buffered-file->buffer) +10990 (clear-stream _test-error-stream) +10991 (clear-stream $_test-error-buffered-file->buffer) +10992 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +10993 68/push 0/imm32 +10994 68/push 0/imm32 +10995 89/<- %edx 4/r32/esp +10996 (tailor-exit-descriptor %edx 0x10) +10997 # +10998 (write _test-input-stream "fn foo {\n") +10999 (write _test-input-stream " var a: int\n") +11000 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") +11001 (write _test-input-stream "}\n") +11002 # convert +11003 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11004 # registers except esp clobbered at this point +11005 # restore ed +11006 89/<- %edx 4/r32/esp +11007 (flush _test-output-buffered-file) +11008 (flush _test-error-buffered-file) +11009 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11015 # check output +11016 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-atom-base-type: output should be empty") +11017 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-atom-base-type: error message") +11018 # check that stop(1) was called +11019 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-atom-base-type: exit status") +11020 # don't restore from ebp +11021 81 0/subop/add %esp 8/imm32 +11022 # . epilogue +11023 5d/pop-to-ebp +11024 c3/return +11025 +11026 test-index-with-non-array-compound-base-type: +11027 # . prologue +11028 55/push-ebp +11029 89/<- %ebp 4/r32/esp +11030 # setup +11031 (clear-stream _test-input-stream) +11032 (clear-stream $_test-input-buffered-file->buffer) +11033 (clear-stream _test-output-stream) +11034 (clear-stream $_test-output-buffered-file->buffer) +11035 (clear-stream _test-error-stream) +11036 (clear-stream $_test-error-buffered-file->buffer) +11037 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11038 68/push 0/imm32 +11039 68/push 0/imm32 +11040 89/<- %edx 4/r32/esp +11041 (tailor-exit-descriptor %edx 0x10) +11042 # +11043 (write _test-input-stream "fn foo {\n") +11044 (write _test-input-stream " var a: (handle int)\n") +11045 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") +11046 (write _test-input-stream "}\n") +11047 # convert +11048 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11049 # registers except esp clobbered at this point +11050 # restore ed +11051 89/<- %edx 4/r32/esp +11052 (flush _test-output-buffered-file) +11053 (flush _test-error-buffered-file) +11054 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11060 # check output +11061 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-compound-base-type: output should be empty") +11062 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-compound-base-type: error message") +11063 # check that stop(1) was called +11064 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-compound-base-type: exit status") +11065 # don't restore from ebp +11066 81 0/subop/add %esp 8/imm32 +11067 # . epilogue +11068 5d/pop-to-ebp +11069 c3/return +11070 +11071 test-index-with-non-array-compound-base-type-2: +11072 # . prologue +11073 55/push-ebp +11074 89/<- %ebp 4/r32/esp +11075 # setup +11076 (clear-stream _test-input-stream) +11077 (clear-stream $_test-input-buffered-file->buffer) +11078 (clear-stream _test-output-stream) +11079 (clear-stream $_test-output-buffered-file->buffer) +11080 (clear-stream _test-error-stream) +11081 (clear-stream $_test-error-buffered-file->buffer) +11082 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11083 68/push 0/imm32 +11084 68/push 0/imm32 +11085 89/<- %edx 4/r32/esp +11086 (tailor-exit-descriptor %edx 0x10) +11087 # +11088 (write _test-input-stream "fn foo {\n") +11089 (write _test-input-stream " var a: (addr int)\n") +11090 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") +11091 (write _test-input-stream "}\n") +11092 # convert +11093 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11094 # registers except esp clobbered at this point +11095 # restore ed +11096 89/<- %edx 4/r32/esp +11097 (flush _test-output-buffered-file) +11098 (flush _test-error-buffered-file) +11099 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11105 # check output +11106 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-compound-base-type-2: output should be empty") +11107 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-compound-base-type-2: error message") +11108 # check that stop(1) was called +11109 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-compound-base-type-2: exit status") +11110 # don't restore from ebp +11111 81 0/subop/add %esp 8/imm32 +11112 # . epilogue +11113 5d/pop-to-ebp +11114 c3/return +11115 +11116 test-index-with-array-atom-base-type: +11117 # . prologue +11118 55/push-ebp +11119 89/<- %ebp 4/r32/esp +11120 # setup +11121 (clear-stream _test-input-stream) +11122 (clear-stream $_test-input-buffered-file->buffer) +11123 (clear-stream _test-output-stream) +11124 (clear-stream $_test-output-buffered-file->buffer) +11125 (clear-stream _test-error-stream) +11126 (clear-stream $_test-error-buffered-file->buffer) +11127 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11128 68/push 0/imm32 +11129 68/push 0/imm32 +11130 89/<- %edx 4/r32/esp +11131 (tailor-exit-descriptor %edx 0x10) +11132 # +11133 (write _test-input-stream "fn foo {\n") +11134 (write _test-input-stream " var a: array\n") +11135 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") +11136 (write _test-input-stream "}\n") +11137 # convert +11138 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11139 # registers except esp clobbered at this point +11140 # restore ed +11141 89/<- %edx 4/r32/esp +11142 (flush _test-output-buffered-file) +11143 (flush _test-error-buffered-file) +11144 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11150 # check output +11151 (check-stream-equal _test-output-stream "" "F - test-index-with-array-atom-base-type: output should be empty") +11152 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: array 'a' must specify the type of its elements" "F - test-index-with-array-atom-base-type: error message") +11153 # check that stop(1) was called +11154 (check-ints-equal *(edx+4) 2 "F - test-index-with-array-atom-base-type: exit status") +11155 # don't restore from ebp +11156 81 0/subop/add %esp 8/imm32 +11157 # . epilogue +11158 5d/pop-to-ebp +11159 c3/return +11160 +11161 test-index-with-addr-base-on-stack: +11162 # . prologue +11163 55/push-ebp +11164 89/<- %ebp 4/r32/esp +11165 # setup +11166 (clear-stream _test-input-stream) +11167 (clear-stream $_test-input-buffered-file->buffer) +11168 (clear-stream _test-output-stream) +11169 (clear-stream $_test-output-buffered-file->buffer) +11170 (clear-stream _test-error-stream) +11171 (clear-stream $_test-error-buffered-file->buffer) +11172 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11173 68/push 0/imm32 +11174 68/push 0/imm32 +11175 89/<- %edx 4/r32/esp +11176 (tailor-exit-descriptor %edx 0x10) +11177 # +11178 (write _test-input-stream "fn foo {\n") +11179 (write _test-input-stream " var a: (addr array int)\n") +11180 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n") +11181 (write _test-input-stream "}\n") +11182 # convert +11183 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11184 # registers except esp clobbered at this point +11185 # restore ed +11186 89/<- %edx 4/r32/esp +11187 (flush _test-output-buffered-file) +11188 (flush _test-error-buffered-file) +11189 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11195 # check output +11196 (check-stream-equal _test-output-stream "" "F - test-index-with-addr-base-on-stack: output should be empty") +11197 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is an addr to an array, and so must live in a register" "F - test-index-with-addr-base-on-stack: error message") +11198 # check that stop(1) was called +11199 (check-ints-equal *(edx+4) 2 "F - test-index-with-addr-base-on-stack: exit status") +11200 # don't restore from ebp +11201 81 0/subop/add %esp 8/imm32 +11202 # . epilogue +11203 5d/pop-to-ebp +11204 c3/return +11205 +11206 test-index-with-wrong-index-type: +11207 # . prologue +11208 55/push-ebp +11209 89/<- %ebp 4/r32/esp +11210 # setup +11211 (clear-stream _test-input-stream) +11212 (clear-stream $_test-input-buffered-file->buffer) +11213 (clear-stream _test-output-stream) +11214 (clear-stream $_test-output-buffered-file->buffer) +11215 (clear-stream _test-error-stream) +11216 (clear-stream $_test-error-buffered-file->buffer) +11217 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11218 68/push 0/imm32 +11219 68/push 0/imm32 +11220 89/<- %edx 4/r32/esp +11221 (tailor-exit-descriptor %edx 0x10) +11222 # +11223 (write _test-input-stream "fn foo {\n") +11224 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") +11225 (write _test-input-stream " var b: boolean\n") +11226 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") +11227 (write _test-input-stream "}\n") +11228 # convert +11229 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11230 # registers except esp clobbered at this point +11231 # restore ed +11232 89/<- %edx 4/r32/esp +11233 (flush _test-output-buffered-file) +11234 (flush _test-error-buffered-file) +11235 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11241 # check output +11242 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-index-type: output should be empty") +11243 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: second argument 'b' must be an int or offset" "F - test-index-with-wrong-index-type: error message") +11244 # check that stop(1) was called +11245 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-index-type: exit status") +11246 # don't restore from ebp +11247 81 0/subop/add %esp 8/imm32 +11248 # . epilogue +11249 5d/pop-to-ebp +11250 c3/return +11251 +11252 test-index-with-offset-atom-index-type: +11253 # . prologue +11254 55/push-ebp +11255 89/<- %ebp 4/r32/esp +11256 # setup +11257 (clear-stream _test-input-stream) +11258 (clear-stream $_test-input-buffered-file->buffer) +11259 (clear-stream _test-output-stream) +11260 (clear-stream $_test-output-buffered-file->buffer) +11261 (clear-stream _test-error-stream) +11262 (clear-stream $_test-error-buffered-file->buffer) +11263 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11264 68/push 0/imm32 +11265 68/push 0/imm32 +11266 89/<- %edx 4/r32/esp +11267 (tailor-exit-descriptor %edx 0x10) +11268 # +11269 (write _test-input-stream "fn foo {\n") +11270 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") +11271 (write _test-input-stream " var b: offset\n") +11272 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") +11273 (write _test-input-stream "}\n") +11274 # convert +11275 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11276 # registers except esp clobbered at this point +11277 # restore ed +11278 89/<- %edx 4/r32/esp +11279 (flush _test-output-buffered-file) +11280 (flush _test-error-buffered-file) +11281 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11287 # check output +11288 (check-stream-equal _test-output-stream "" "F - test-index-with-offset-atom-index-type: output should be empty") +11289 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: offset 'b' must specify the type of array elements" "F - test-index-with-offset-atom-index-type: error message") +11290 # check that stop(1) was called +11291 (check-ints-equal *(edx+4) 2 "F - test-index-with-offset-atom-index-type: exit status") +11292 # don't restore from ebp +11293 81 0/subop/add %esp 8/imm32 +11294 # . epilogue +11295 5d/pop-to-ebp +11296 c3/return +11297 +11298 test-index-with-offset-on-stack: +11299 # . prologue +11300 55/push-ebp +11301 89/<- %ebp 4/r32/esp +11302 # setup +11303 (clear-stream _test-input-stream) +11304 (clear-stream $_test-input-buffered-file->buffer) +11305 (clear-stream _test-output-stream) +11306 (clear-stream $_test-output-buffered-file->buffer) +11307 (clear-stream _test-error-stream) +11308 (clear-stream $_test-error-buffered-file->buffer) +11309 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11310 68/push 0/imm32 +11311 68/push 0/imm32 +11312 89/<- %edx 4/r32/esp +11313 (tailor-exit-descriptor %edx 0x10) +11314 # +11315 (write _test-input-stream "fn foo {\n") +11316 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") +11317 (write _test-input-stream " var b: int\n") +11318 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") +11319 (write _test-input-stream "}\n") +11320 # convert +11321 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11322 # registers except esp clobbered at this point +11323 # restore ed +11324 89/<- %edx 4/r32/esp +11325 (flush _test-output-buffered-file) +11326 (flush _test-error-buffered-file) +11327 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11333 # check output +11334 (check-stream-equal _test-output-stream "" "F - test-index-with-offset-on-stack: output should be empty") +11335 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: second argument 'b' must be in a register" "F - test-index-with-offset-on-stack: error message") +11336 # check that stop(1) was called +11337 (check-ints-equal *(edx+4) 2 "F - test-index-with-offset-on-stack: exit status") +11338 # don't restore from ebp +11339 81 0/subop/add %esp 8/imm32 +11340 # . epilogue +11341 5d/pop-to-ebp +11342 c3/return +11343 +11344 test-index-needs-offset-type: +11345 # . prologue +11346 55/push-ebp +11347 89/<- %ebp 4/r32/esp +11348 # setup +11349 (clear-stream _test-input-stream) +11350 (clear-stream $_test-input-buffered-file->buffer) +11351 (clear-stream _test-output-stream) +11352 (clear-stream $_test-output-buffered-file->buffer) +11353 (clear-stream _test-error-stream) +11354 (clear-stream $_test-error-buffered-file->buffer) +11355 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11356 68/push 0/imm32 +11357 68/push 0/imm32 +11358 89/<- %edx 4/r32/esp +11359 (tailor-exit-descriptor %edx 0x10) +11360 # +11361 (write _test-input-stream "fn foo {\n") +11362 (write _test-input-stream " var a/eax: (addr array t) <- copy 0\n") +11363 (write _test-input-stream " var b/ebx: int <- copy 0\n") +11364 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n") +11365 (write _test-input-stream "}\n") +11366 (write _test-input-stream "type t {\n") # size 12 is not a power of two +11367 (write _test-input-stream " x: int\n") +11368 (write _test-input-stream " y: int\n") +11369 (write _test-input-stream " z: int\n") +11370 (write _test-input-stream "}\n") +11371 # convert +11372 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11373 # registers except esp clobbered at this point +11374 # restore ed +11375 89/<- %edx 4/r32/esp +11376 (flush _test-output-buffered-file) +11377 (flush _test-error-buffered-file) +11378 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11384 # check output +11385 (check-stream-equal _test-output-stream "" "F - test-index-needs-offset-type: output should be empty") +11386 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: cannot take an int for array 'a'; create an offset instead. See mu.md for details." "F - test-index-needs-offset-type: error message") +11387 # check that stop(1) was called +11388 (check-ints-equal *(edx+4) 2 "F - test-index-needs-offset-type: exit status") +11389 # don't restore from ebp +11390 81 0/subop/add %esp 8/imm32 +11391 # . epilogue +11392 5d/pop-to-ebp +11393 c3/return +11394 +11395 test-index-with-output-not-address: +11396 # . prologue +11397 55/push-ebp +11398 89/<- %ebp 4/r32/esp +11399 # setup +11400 (clear-stream _test-input-stream) +11401 (clear-stream $_test-input-buffered-file->buffer) +11402 (clear-stream _test-output-stream) +11403 (clear-stream $_test-output-buffered-file->buffer) +11404 (clear-stream _test-error-stream) +11405 (clear-stream $_test-error-buffered-file->buffer) +11406 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11407 68/push 0/imm32 +11408 68/push 0/imm32 +11409 89/<- %edx 4/r32/esp +11410 (tailor-exit-descriptor %edx 0x10) +11411 # +11412 (write _test-input-stream "fn foo {\n") +11413 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") +11414 (write _test-input-stream " var o/edi: int <- index a, 0\n") +11415 (write _test-input-stream "}\n") +11416 # convert +11417 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11418 # registers except esp clobbered at this point +11419 # restore ed +11420 89/<- %edx 4/r32/esp +11421 (flush _test-output-buffered-file) +11422 (flush _test-error-buffered-file) +11423 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11429 # check output +11430 (check-stream-equal _test-output-stream "" "F - test-index-with-output-not-address: output should be empty") +11431 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' must be an addr" "F - test-index-with-output-not-address: error message") +11432 # check that stop(1) was called +11433 (check-ints-equal *(edx+4) 2 "F - test-index-with-output-not-address: exit status") +11434 # don't restore from ebp +11435 81 0/subop/add %esp 8/imm32 +11436 # . epilogue +11437 5d/pop-to-ebp +11438 c3/return +11439 +11440 test-index-with-output-not-address-2: +11441 # . prologue +11442 55/push-ebp +11443 89/<- %ebp 4/r32/esp +11444 # setup +11445 (clear-stream _test-input-stream) +11446 (clear-stream $_test-input-buffered-file->buffer) +11447 (clear-stream _test-output-stream) +11448 (clear-stream $_test-output-buffered-file->buffer) +11449 (clear-stream _test-error-stream) +11450 (clear-stream $_test-error-buffered-file->buffer) +11451 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11452 68/push 0/imm32 +11453 68/push 0/imm32 +11454 89/<- %edx 4/r32/esp +11455 (tailor-exit-descriptor %edx 0x10) +11456 # +11457 (write _test-input-stream "fn foo {\n") +11458 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") +11459 (write _test-input-stream " var o/edi: (int) <- index a, 0\n") +11460 (write _test-input-stream "}\n") +11461 # convert +11462 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11463 # registers except esp clobbered at this point +11464 # restore ed +11465 89/<- %edx 4/r32/esp +11466 (flush _test-output-buffered-file) +11467 (flush _test-error-buffered-file) +11468 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11474 # check output +11475 (check-stream-equal _test-output-stream "" "F - test-index-with-output-not-address-2: output should be empty") +11476 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' must be an addr" "F - test-index-with-output-not-address-2: error message") +11477 # check that stop(1) was called +11478 (check-ints-equal *(edx+4) 2 "F - test-index-with-output-not-address-2: exit status") +11479 # don't restore from ebp +11480 81 0/subop/add %esp 8/imm32 +11481 # . epilogue +11482 5d/pop-to-ebp +11483 c3/return +11484 +11485 test-index-with-wrong-output-type: +11486 # . prologue +11487 55/push-ebp +11488 89/<- %ebp 4/r32/esp +11489 # setup +11490 (clear-stream _test-input-stream) +11491 (clear-stream $_test-input-buffered-file->buffer) +11492 (clear-stream _test-output-stream) +11493 (clear-stream $_test-output-buffered-file->buffer) +11494 (clear-stream _test-error-stream) +11495 (clear-stream $_test-error-buffered-file->buffer) +11496 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11497 68/push 0/imm32 +11498 68/push 0/imm32 +11499 89/<- %edx 4/r32/esp +11500 (tailor-exit-descriptor %edx 0x10) +11501 # +11502 (write _test-input-stream "fn foo {\n") +11503 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") +11504 (write _test-input-stream " var o/edi: (addr int) <- index a, 0\n") +11505 (write _test-input-stream "}\n") +11506 # convert +11507 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11508 # registers except esp clobbered at this point +11509 # restore ed +11510 89/<- %edx 4/r32/esp +11511 (flush _test-output-buffered-file) +11512 (flush _test-error-buffered-file) +11513 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11519 # check output +11520 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-output-type: output should be empty") +11521 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' does not have the right type" "F - test-index-with-wrong-output-type: error message") +11522 # check that stop(1) was called +11523 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-output-type: exit status") +11524 # don't restore from ebp +11525 81 0/subop/add %esp 8/imm32 +11526 # . epilogue +11527 5d/pop-to-ebp +11528 c3/return +11529 +11530 test-index-with-wrong-output-compound-type: +11531 # . prologue +11532 55/push-ebp +11533 89/<- %ebp 4/r32/esp +11534 # setup +11535 (clear-stream _test-input-stream) +11536 (clear-stream $_test-input-buffered-file->buffer) +11537 (clear-stream _test-output-stream) +11538 (clear-stream $_test-output-buffered-file->buffer) +11539 (clear-stream _test-error-stream) +11540 (clear-stream $_test-error-buffered-file->buffer) +11541 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11542 68/push 0/imm32 +11543 68/push 0/imm32 +11544 89/<- %edx 4/r32/esp +11545 (tailor-exit-descriptor %edx 0x10) +11546 # +11547 (write _test-input-stream "fn foo {\n") +11548 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n") +11549 (write _test-input-stream " var o/edi: (addr handle int) <- index a, 0\n") +11550 (write _test-input-stream "}\n") +11551 # convert +11552 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11553 # registers except esp clobbered at this point +11554 # restore ed +11555 89/<- %edx 4/r32/esp +11556 (flush _test-output-buffered-file) +11557 (flush _test-error-buffered-file) +11558 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11564 # check output +11565 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-output-compound-type: output should be empty") +11566 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' does not have the right type" "F - test-index-with-wrong-output-compound-type: error message") +11567 # check that stop(1) was called +11568 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-output-compound-type: exit status") +11569 # don't restore from ebp +11570 81 0/subop/add %esp 8/imm32 +11571 # . epilogue +11572 5d/pop-to-ebp +11573 c3/return +11574 +11575 test-index-with-no-inouts: +11576 # . prologue +11577 55/push-ebp +11578 89/<- %ebp 4/r32/esp +11579 # setup +11580 (clear-stream _test-input-stream) +11581 (clear-stream $_test-input-buffered-file->buffer) +11582 (clear-stream _test-output-stream) +11583 (clear-stream $_test-output-buffered-file->buffer) +11584 (clear-stream _test-error-stream) +11585 (clear-stream $_test-error-buffered-file->buffer) +11586 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11587 68/push 0/imm32 +11588 68/push 0/imm32 +11589 89/<- %edx 4/r32/esp +11590 (tailor-exit-descriptor %edx 0x10) +11591 # +11592 (write _test-input-stream "fn foo {\n") +11593 (write _test-input-stream " var c/ecx: (addr int) <- index\n") +11594 (write _test-input-stream "}\n") +11595 # convert +11596 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11597 # registers except esp clobbered at this point +11598 # restore ed +11599 89/<- %edx 4/r32/esp +11600 (flush _test-output-buffered-file) +11601 (flush _test-error-buffered-file) +11602 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11608 # check output +11609 (check-stream-equal _test-output-stream "" "F - test-index-with-no-inouts: output should be empty") +11610 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too few inouts (2 required)" "F - test-index-with-no-inouts: error message") +11611 # check that stop(1) was called +11612 (check-ints-equal *(edx+4) 2 "F - test-index-with-no-inouts: exit status") +11613 # don't restore from ebp +11614 81 0/subop/add %esp 8/imm32 +11615 # . epilogue +11616 5d/pop-to-ebp +11617 c3/return +11618 +11619 test-index-with-too-few-inouts: +11620 # . prologue +11621 55/push-ebp +11622 89/<- %ebp 4/r32/esp +11623 # setup +11624 (clear-stream _test-input-stream) +11625 (clear-stream $_test-input-buffered-file->buffer) +11626 (clear-stream _test-output-stream) +11627 (clear-stream $_test-output-buffered-file->buffer) +11628 (clear-stream _test-error-stream) +11629 (clear-stream $_test-error-buffered-file->buffer) +11630 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11631 68/push 0/imm32 +11632 68/push 0/imm32 +11633 89/<- %edx 4/r32/esp +11634 (tailor-exit-descriptor %edx 0x10) +11635 # +11636 (write _test-input-stream "fn foo {\n") +11637 (write _test-input-stream " var a: (array int 3)\n") +11638 (write _test-input-stream " var c/ecx: (addr int) <- index a\n") +11639 (write _test-input-stream "}\n") +11640 # convert +11641 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11642 # registers except esp clobbered at this point +11643 # restore ed +11644 89/<- %edx 4/r32/esp +11645 (flush _test-output-buffered-file) +11646 (flush _test-error-buffered-file) +11647 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11653 # check output +11654 (check-stream-equal _test-output-stream "" "F - test-index-with-too-few-inouts: output should be empty") +11655 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too few inouts (2 required)" "F - test-index-with-too-few-inouts: error message") +11656 # check that stop(1) was called +11657 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-few-inouts: exit status") +11658 # don't restore from ebp +11659 81 0/subop/add %esp 8/imm32 +11660 # . epilogue +11661 5d/pop-to-ebp +11662 c3/return +11663 +11664 test-index-with-too-many-inouts: +11665 # . prologue +11666 55/push-ebp +11667 89/<- %ebp 4/r32/esp +11668 # setup +11669 (clear-stream _test-input-stream) +11670 (clear-stream $_test-input-buffered-file->buffer) +11671 (clear-stream _test-output-stream) +11672 (clear-stream $_test-output-buffered-file->buffer) +11673 (clear-stream _test-error-stream) +11674 (clear-stream $_test-error-buffered-file->buffer) +11675 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11676 68/push 0/imm32 +11677 68/push 0/imm32 +11678 89/<- %edx 4/r32/esp +11679 (tailor-exit-descriptor %edx 0x10) +11680 # +11681 (write _test-input-stream "fn foo {\n") +11682 (write _test-input-stream " var a: (array int 3)\n") +11683 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0, 0\n") +11684 (write _test-input-stream "}\n") +11685 # convert +11686 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11687 # registers except esp clobbered at this point +11688 # restore ed +11689 89/<- %edx 4/r32/esp +11690 (flush _test-output-buffered-file) +11691 (flush _test-error-buffered-file) +11692 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11698 # check output +11699 (check-stream-equal _test-output-stream "" "F - test-index-with-too-many-inouts: output should be empty") +11700 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too many inouts (2 required)" "F - test-index-with-too-many-inouts: error message") +11701 # check that stop(1) was called +11702 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-many-inouts: exit status") +11703 # don't restore from ebp +11704 81 0/subop/add %esp 8/imm32 +11705 # . epilogue +11706 5d/pop-to-ebp +11707 c3/return +11708 +11709 test-index-with-no-output: +11710 # . prologue +11711 55/push-ebp +11712 89/<- %ebp 4/r32/esp +11713 # setup +11714 (clear-stream _test-input-stream) +11715 (clear-stream $_test-input-buffered-file->buffer) +11716 (clear-stream _test-output-stream) +11717 (clear-stream $_test-output-buffered-file->buffer) +11718 (clear-stream _test-error-stream) +11719 (clear-stream $_test-error-buffered-file->buffer) +11720 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11721 68/push 0/imm32 +11722 68/push 0/imm32 +11723 89/<- %edx 4/r32/esp +11724 (tailor-exit-descriptor %edx 0x10) +11725 # +11726 (write _test-input-stream "fn foo {\n") +11727 (write _test-input-stream " var a: (array int 3)\n") +11728 (write _test-input-stream " index a, 0\n") +11729 (write _test-input-stream "}\n") +11730 # convert +11731 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11732 # registers except esp clobbered at this point +11733 # restore ed +11734 89/<- %edx 4/r32/esp +11735 (flush _test-output-buffered-file) +11736 (flush _test-error-buffered-file) +11737 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11743 # check output +11744 (check-stream-equal _test-output-stream "" "F - test-index-with-no-output: output should be empty") +11745 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: must have an output" "F - test-index-with-no-output: error message") +11746 # check that stop(1) was called +11747 (check-ints-equal *(edx+4) 2 "F - test-index-with-no-output: exit status") +11748 # don't restore from ebp +11749 81 0/subop/add %esp 8/imm32 +11750 # . epilogue +11751 5d/pop-to-ebp +11752 c3/return +11753 +11754 test-index-with-too-many-outputs: +11755 # . prologue +11756 55/push-ebp +11757 89/<- %ebp 4/r32/esp +11758 # setup +11759 (clear-stream _test-input-stream) +11760 (clear-stream $_test-input-buffered-file->buffer) +11761 (clear-stream _test-output-stream) +11762 (clear-stream $_test-output-buffered-file->buffer) +11763 (clear-stream _test-error-stream) +11764 (clear-stream $_test-error-buffered-file->buffer) +11765 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11766 68/push 0/imm32 +11767 68/push 0/imm32 +11768 89/<- %edx 4/r32/esp +11769 (tailor-exit-descriptor %edx 0x10) +11770 # +11771 (write _test-input-stream "fn foo {\n") +11772 (write _test-input-stream " var a: (array int 3)\n") +11773 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n") +11774 (write _test-input-stream " var c/ecx: (addr int) <- copy 0\n") +11775 (write _test-input-stream " b, c <- index a, 0\n") +11776 (write _test-input-stream "}\n") +11777 # convert +11778 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11779 # registers except esp clobbered at this point +11780 # restore ed +11781 89/<- %edx 4/r32/esp +11782 (flush _test-output-buffered-file) +11783 (flush _test-error-buffered-file) +11784 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11790 # check output +11791 (check-stream-equal _test-output-stream "" "F - test-index-with-too-many-outputs: output should be empty") +11792 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too many outputs (1 required)" "F - test-index-with-too-many-outputs: error message") +11793 # check that stop(1) was called +11794 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-many-outputs: exit status") +11795 # don't restore from ebp +11796 81 0/subop/add %esp 8/imm32 +11797 # . epilogue +11798 5d/pop-to-ebp +11799 c3/return +11800 +11801 test-compute-offset-with-non-array-atom-base-type: +11802 # . prologue +11803 55/push-ebp +11804 89/<- %ebp 4/r32/esp +11805 # setup +11806 (clear-stream _test-input-stream) +11807 (clear-stream $_test-input-buffered-file->buffer) +11808 (clear-stream _test-output-stream) +11809 (clear-stream $_test-output-buffered-file->buffer) +11810 (clear-stream _test-error-stream) +11811 (clear-stream $_test-error-buffered-file->buffer) +11812 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11813 68/push 0/imm32 +11814 68/push 0/imm32 +11815 89/<- %edx 4/r32/esp +11816 (tailor-exit-descriptor %edx 0x10) +11817 # +11818 (write _test-input-stream "fn foo {\n") +11819 (write _test-input-stream " var a: int\n") +11820 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n") +11821 (write _test-input-stream "}\n") +11822 # convert +11823 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11824 # registers except esp clobbered at this point +11825 # restore ed +11826 89/<- %edx 4/r32/esp +11827 (flush _test-output-buffered-file) +11828 (flush _test-error-buffered-file) +11829 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11835 # check output +11836 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-atom-base-type: output should be empty") +11837 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-atom-base-type: error message") +11838 # check that stop(1) was called +11839 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-atom-base-type: exit status") +11840 # don't restore from ebp +11841 81 0/subop/add %esp 8/imm32 +11842 # . epilogue +11843 5d/pop-to-ebp +11844 c3/return +11845 +11846 test-compute-offset-with-non-array-compound-base-type: +11847 # . prologue +11848 55/push-ebp +11849 89/<- %ebp 4/r32/esp +11850 # setup +11851 (clear-stream _test-input-stream) +11852 (clear-stream $_test-input-buffered-file->buffer) +11853 (clear-stream _test-output-stream) +11854 (clear-stream $_test-output-buffered-file->buffer) +11855 (clear-stream _test-error-stream) +11856 (clear-stream $_test-error-buffered-file->buffer) +11857 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11858 68/push 0/imm32 +11859 68/push 0/imm32 +11860 89/<- %edx 4/r32/esp +11861 (tailor-exit-descriptor %edx 0x10) +11862 # +11863 (write _test-input-stream "fn foo {\n") +11864 (write _test-input-stream " var a: (handle int)\n") +11865 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n") +11866 (write _test-input-stream "}\n") +11867 # convert +11868 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11869 # registers except esp clobbered at this point +11870 # restore ed +11871 89/<- %edx 4/r32/esp +11872 (flush _test-output-buffered-file) +11873 (flush _test-error-buffered-file) +11874 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11880 # check output +11881 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-compound-base-type: output should be empty") +11882 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-compound-base-type: error message") +11883 # check that stop(1) was called +11884 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-compound-base-type: exit status") +11885 # don't restore from ebp +11886 81 0/subop/add %esp 8/imm32 +11887 # . epilogue +11888 5d/pop-to-ebp +11889 c3/return +11890 +11891 test-compute-offset-with-non-array-compound-base-type-2: +11892 # . prologue +11893 55/push-ebp +11894 89/<- %ebp 4/r32/esp +11895 # setup +11896 (clear-stream _test-input-stream) +11897 (clear-stream $_test-input-buffered-file->buffer) +11898 (clear-stream _test-output-stream) +11899 (clear-stream $_test-output-buffered-file->buffer) +11900 (clear-stream _test-error-stream) +11901 (clear-stream $_test-error-buffered-file->buffer) +11902 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11903 68/push 0/imm32 +11904 68/push 0/imm32 +11905 89/<- %edx 4/r32/esp +11906 (tailor-exit-descriptor %edx 0x10) +11907 # +11908 (write _test-input-stream "fn foo {\n") +11909 (write _test-input-stream " var a: (addr int)\n") +11910 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n") +11911 (write _test-input-stream "}\n") +11912 # convert +11913 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11914 # registers except esp clobbered at this point +11915 # restore ed +11916 89/<- %edx 4/r32/esp +11917 (flush _test-output-buffered-file) +11918 (flush _test-error-buffered-file) +11919 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11925 # check output +11926 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-compound-base-type-2: output should be empty") +11927 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-compound-base-type-2: error message") +11928 # check that stop(1) was called +11929 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-compound-base-type-2: exit status") +11930 # don't restore from ebp +11931 81 0/subop/add %esp 8/imm32 +11932 # . epilogue +11933 5d/pop-to-ebp +11934 c3/return +11935 +11936 test-compute-offset-with-array-atom-base-type: +11937 # . prologue +11938 55/push-ebp +11939 89/<- %ebp 4/r32/esp +11940 # setup +11941 (clear-stream _test-input-stream) +11942 (clear-stream $_test-input-buffered-file->buffer) +11943 (clear-stream _test-output-stream) +11944 (clear-stream $_test-output-buffered-file->buffer) +11945 (clear-stream _test-error-stream) +11946 (clear-stream $_test-error-buffered-file->buffer) +11947 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11948 68/push 0/imm32 +11949 68/push 0/imm32 +11950 89/<- %edx 4/r32/esp +11951 (tailor-exit-descriptor %edx 0x10) +11952 # +11953 (write _test-input-stream "fn foo {\n") +11954 (write _test-input-stream " var a: array\n") +11955 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n") +11956 (write _test-input-stream "}\n") +11957 # convert +11958 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +11959 # registers except esp clobbered at this point +11960 # restore ed +11961 89/<- %edx 4/r32/esp +11962 (flush _test-output-buffered-file) +11963 (flush _test-error-buffered-file) +11964 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +11970 # check output +11971 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-array-atom-base-type: output should be empty") +11972 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: array 'a' must specify the type of its elements" "F - test-compute-offset-with-array-atom-base-type: error message") +11973 # check that stop(1) was called +11974 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-array-atom-base-type: exit status") +11975 # don't restore from ebp +11976 81 0/subop/add %esp 8/imm32 +11977 # . epilogue +11978 5d/pop-to-ebp +11979 c3/return +11980 +11981 test-compute-offset-with-wrong-index-type: +11982 # . prologue +11983 55/push-ebp +11984 89/<- %ebp 4/r32/esp +11985 # setup +11986 (clear-stream _test-input-stream) +11987 (clear-stream $_test-input-buffered-file->buffer) +11988 (clear-stream _test-output-stream) +11989 (clear-stream $_test-output-buffered-file->buffer) +11990 (clear-stream _test-error-stream) +11991 (clear-stream $_test-error-buffered-file->buffer) +11992 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +11993 68/push 0/imm32 +11994 68/push 0/imm32 +11995 89/<- %edx 4/r32/esp +11996 (tailor-exit-descriptor %edx 0x10) +11997 # +11998 (write _test-input-stream "fn foo {\n") +11999 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n") +12000 (write _test-input-stream " var b: boolean\n") +12001 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, b\n") +12002 (write _test-input-stream "}\n") +12003 # convert +12004 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12005 # registers except esp clobbered at this point +12006 # restore ed +12007 89/<- %edx 4/r32/esp +12008 (flush _test-output-buffered-file) +12009 (flush _test-error-buffered-file) +12010 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12016 # check output +12017 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-index-type: output should be empty") +12018 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: second argument 'b' must be an int" "F - test-compute-offset-with-wrong-index-type: error message") +12019 # check that stop(1) was called +12020 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-index-type: exit status") +12021 # don't restore from ebp +12022 81 0/subop/add %esp 8/imm32 +12023 # . epilogue +12024 5d/pop-to-ebp +12025 c3/return +12026 +12027 test-compute-offset-with-output-not-offset: +12028 # . prologue +12029 55/push-ebp +12030 89/<- %ebp 4/r32/esp +12031 # setup +12032 (clear-stream _test-input-stream) +12033 (clear-stream $_test-input-buffered-file->buffer) +12034 (clear-stream _test-output-stream) +12035 (clear-stream $_test-output-buffered-file->buffer) +12036 (clear-stream _test-error-stream) +12037 (clear-stream $_test-error-buffered-file->buffer) +12038 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12039 68/push 0/imm32 +12040 68/push 0/imm32 +12041 89/<- %edx 4/r32/esp +12042 (tailor-exit-descriptor %edx 0x10) +12043 # +12044 (write _test-input-stream "fn foo {\n") +12045 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") +12046 (write _test-input-stream " var o/edi: int <- compute-offset a, 0\n") +12047 (write _test-input-stream "}\n") +12048 # convert +12049 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12050 # registers except esp clobbered at this point +12051 # restore ed +12052 89/<- %edx 4/r32/esp +12053 (flush _test-output-buffered-file) +12054 (flush _test-error-buffered-file) +12055 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12061 # check output +12062 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-output-not-offset: output should be empty") +12063 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' must be an offset" "F - test-compute-offset-with-output-not-offset: error message") +12064 # check that stop(1) was called +12065 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-output-not-offset: exit status") +12066 # don't restore from ebp +12067 81 0/subop/add %esp 8/imm32 +12068 # . epilogue +12069 5d/pop-to-ebp +12070 c3/return +12071 +12072 test-compute-offset-with-output-not-address-2: +12073 # . prologue +12074 55/push-ebp +12075 89/<- %ebp 4/r32/esp +12076 # setup +12077 (clear-stream _test-input-stream) +12078 (clear-stream $_test-input-buffered-file->buffer) +12079 (clear-stream _test-output-stream) +12080 (clear-stream $_test-output-buffered-file->buffer) +12081 (clear-stream _test-error-stream) +12082 (clear-stream $_test-error-buffered-file->buffer) +12083 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12084 68/push 0/imm32 +12085 68/push 0/imm32 +12086 89/<- %edx 4/r32/esp +12087 (tailor-exit-descriptor %edx 0x10) +12088 # +12089 (write _test-input-stream "fn foo {\n") +12090 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") +12091 (write _test-input-stream " var o/edi: (int) <- compute-offset a, 0\n") +12092 (write _test-input-stream "}\n") +12093 # convert +12094 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12095 # registers except esp clobbered at this point +12096 # restore ed +12097 89/<- %edx 4/r32/esp +12098 (flush _test-output-buffered-file) +12099 (flush _test-error-buffered-file) +12100 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12106 # check output +12107 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-output-not-address-2: output should be empty") +12108 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' must be an offset" "F - test-compute-offset-with-output-not-address-2: error message") +12109 # check that stop(1) was called +12110 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-output-not-address-2: exit status") +12111 # don't restore from ebp +12112 81 0/subop/add %esp 8/imm32 +12113 # . epilogue +12114 5d/pop-to-ebp +12115 c3/return +12116 +12117 test-compute-offset-with-wrong-output-type: +12118 # . prologue +12119 55/push-ebp +12120 89/<- %ebp 4/r32/esp +12121 # setup +12122 (clear-stream _test-input-stream) +12123 (clear-stream $_test-input-buffered-file->buffer) +12124 (clear-stream _test-output-stream) +12125 (clear-stream $_test-output-buffered-file->buffer) +12126 (clear-stream _test-error-stream) +12127 (clear-stream $_test-error-buffered-file->buffer) +12128 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12129 68/push 0/imm32 +12130 68/push 0/imm32 +12131 89/<- %edx 4/r32/esp +12132 (tailor-exit-descriptor %edx 0x10) +12133 # +12134 (write _test-input-stream "fn foo {\n") +12135 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") +12136 (write _test-input-stream " var o/edi: (offset int) <- compute-offset a, 0\n") +12137 (write _test-input-stream "}\n") +12138 # convert +12139 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12140 # registers except esp clobbered at this point +12141 # restore ed +12142 89/<- %edx 4/r32/esp +12143 (flush _test-output-buffered-file) +12144 (flush _test-error-buffered-file) +12145 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12151 # check output +12152 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-output-type: output should be empty") +12153 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' does not have the right type" "F - test-compute-offset-with-wrong-output-type: error message") +12154 # check that stop(1) was called +12155 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-output-type: exit status") +12156 # don't restore from ebp +12157 81 0/subop/add %esp 8/imm32 +12158 # . epilogue +12159 5d/pop-to-ebp +12160 c3/return +12161 +12162 test-compute-offset-with-wrong-output-compound-type: +12163 # . prologue +12164 55/push-ebp +12165 89/<- %ebp 4/r32/esp +12166 # setup +12167 (clear-stream _test-input-stream) +12168 (clear-stream $_test-input-buffered-file->buffer) +12169 (clear-stream _test-output-stream) +12170 (clear-stream $_test-output-buffered-file->buffer) +12171 (clear-stream _test-error-stream) +12172 (clear-stream $_test-error-buffered-file->buffer) +12173 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12174 68/push 0/imm32 +12175 68/push 0/imm32 +12176 89/<- %edx 4/r32/esp +12177 (tailor-exit-descriptor %edx 0x10) +12178 # +12179 (write _test-input-stream "fn foo {\n") +12180 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n") +12181 (write _test-input-stream " var o/edi: (offset handle int) <- compute-offset a, 0\n") +12182 (write _test-input-stream "}\n") +12183 # convert +12184 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12185 # registers except esp clobbered at this point +12186 # restore ed +12187 89/<- %edx 4/r32/esp +12188 (flush _test-output-buffered-file) +12189 (flush _test-error-buffered-file) +12190 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12196 # check output +12197 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-output-compound-type: output should be empty") +12198 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' does not have the right type" "F - test-compute-offset-with-wrong-output-compound-type: error message") +12199 # check that stop(1) was called +12200 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-output-compound-type: exit status") +12201 # don't restore from ebp +12202 81 0/subop/add %esp 8/imm32 +12203 # . epilogue +12204 5d/pop-to-ebp +12205 c3/return +12206 +12207 test-compute-offset-with-no-inouts: +12208 # . prologue +12209 55/push-ebp +12210 89/<- %ebp 4/r32/esp +12211 # setup +12212 (clear-stream _test-input-stream) +12213 (clear-stream $_test-input-buffered-file->buffer) +12214 (clear-stream _test-output-stream) +12215 (clear-stream $_test-output-buffered-file->buffer) +12216 (clear-stream _test-error-stream) +12217 (clear-stream $_test-error-buffered-file->buffer) +12218 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12219 68/push 0/imm32 +12220 68/push 0/imm32 +12221 89/<- %edx 4/r32/esp +12222 (tailor-exit-descriptor %edx 0x10) +12223 # +12224 (write _test-input-stream "fn foo {\n") +12225 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset\n") +12226 (write _test-input-stream "}\n") +12227 # convert +12228 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12229 # registers except esp clobbered at this point +12230 # restore ed +12231 89/<- %edx 4/r32/esp +12232 (flush _test-output-buffered-file) +12233 (flush _test-error-buffered-file) +12234 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12240 # check output +12241 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-no-inouts: output should be empty") +12242 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too few inouts (2 required)" "F - test-compute-offset-with-no-inouts: error message") +12243 # check that stop(1) was called +12244 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-no-inouts: exit status") +12245 # don't restore from ebp +12246 81 0/subop/add %esp 8/imm32 +12247 # . epilogue +12248 5d/pop-to-ebp +12249 c3/return +12250 +12251 test-compute-offset-with-too-few-inouts: +12252 # . prologue +12253 55/push-ebp +12254 89/<- %ebp 4/r32/esp +12255 # setup +12256 (clear-stream _test-input-stream) +12257 (clear-stream $_test-input-buffered-file->buffer) +12258 (clear-stream _test-output-stream) +12259 (clear-stream $_test-output-buffered-file->buffer) +12260 (clear-stream _test-error-stream) +12261 (clear-stream $_test-error-buffered-file->buffer) +12262 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12263 68/push 0/imm32 +12264 68/push 0/imm32 +12265 89/<- %edx 4/r32/esp +12266 (tailor-exit-descriptor %edx 0x10) +12267 # +12268 (write _test-input-stream "fn foo {\n") +12269 (write _test-input-stream " var a: (array int 3)\n") +12270 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a\n") +12271 (write _test-input-stream "}\n") +12272 # convert +12273 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12274 # registers except esp clobbered at this point +12275 # restore ed +12276 89/<- %edx 4/r32/esp +12277 (flush _test-output-buffered-file) +12278 (flush _test-error-buffered-file) +12279 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12285 # check output +12286 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-few-inouts: output should be empty") +12287 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too few inouts (2 required)" "F - test-compute-offset-with-too-few-inouts: error message") +12288 # check that stop(1) was called +12289 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-few-inouts: exit status") +12290 # don't restore from ebp +12291 81 0/subop/add %esp 8/imm32 +12292 # . epilogue +12293 5d/pop-to-ebp +12294 c3/return +12295 +12296 test-compute-offset-with-too-many-inouts: +12297 # . prologue +12298 55/push-ebp +12299 89/<- %ebp 4/r32/esp +12300 # setup +12301 (clear-stream _test-input-stream) +12302 (clear-stream $_test-input-buffered-file->buffer) +12303 (clear-stream _test-output-stream) +12304 (clear-stream $_test-output-buffered-file->buffer) +12305 (clear-stream _test-error-stream) +12306 (clear-stream $_test-error-buffered-file->buffer) +12307 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12308 68/push 0/imm32 +12309 68/push 0/imm32 +12310 89/<- %edx 4/r32/esp +12311 (tailor-exit-descriptor %edx 0x10) +12312 # +12313 (write _test-input-stream "fn foo {\n") +12314 (write _test-input-stream " var a: (array int 3)\n") +12315 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0, 0\n") +12316 (write _test-input-stream "}\n") +12317 # convert +12318 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12319 # registers except esp clobbered at this point +12320 # restore ed +12321 89/<- %edx 4/r32/esp +12322 (flush _test-output-buffered-file) +12323 (flush _test-error-buffered-file) +12324 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12330 # check output +12331 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-many-inouts: output should be empty") +12332 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too many inouts (2 required)" "F - test-compute-offset-with-too-many-inouts: error message") +12333 # check that stop(1) was called +12334 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-many-inouts: exit status") +12335 # don't restore from ebp +12336 81 0/subop/add %esp 8/imm32 +12337 # . epilogue +12338 5d/pop-to-ebp +12339 c3/return +12340 +12341 test-compute-offset-with-no-output: +12342 # . prologue +12343 55/push-ebp +12344 89/<- %ebp 4/r32/esp +12345 # setup +12346 (clear-stream _test-input-stream) +12347 (clear-stream $_test-input-buffered-file->buffer) +12348 (clear-stream _test-output-stream) +12349 (clear-stream $_test-output-buffered-file->buffer) +12350 (clear-stream _test-error-stream) +12351 (clear-stream $_test-error-buffered-file->buffer) +12352 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12353 68/push 0/imm32 +12354 68/push 0/imm32 +12355 89/<- %edx 4/r32/esp +12356 (tailor-exit-descriptor %edx 0x10) +12357 # +12358 (write _test-input-stream "fn foo {\n") +12359 (write _test-input-stream " var a: (array int 3)\n") +12360 (write _test-input-stream " compute-offset a, 0\n") +12361 (write _test-input-stream "}\n") +12362 # convert +12363 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12364 # registers except esp clobbered at this point +12365 # restore ed +12366 89/<- %edx 4/r32/esp +12367 (flush _test-output-buffered-file) +12368 (flush _test-error-buffered-file) +12369 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12375 # check output +12376 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-no-output: output should be empty") +12377 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: must have an output" "F - test-compute-offset-with-no-output: error message") +12378 # check that stop(1) was called +12379 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-no-output: exit status") +12380 # don't restore from ebp +12381 81 0/subop/add %esp 8/imm32 +12382 # . epilogue +12383 5d/pop-to-ebp +12384 c3/return +12385 +12386 test-compute-offset-with-too-many-outputs: +12387 # . prologue +12388 55/push-ebp +12389 89/<- %ebp 4/r32/esp +12390 # setup +12391 (clear-stream _test-input-stream) +12392 (clear-stream $_test-input-buffered-file->buffer) +12393 (clear-stream _test-output-stream) +12394 (clear-stream $_test-output-buffered-file->buffer) +12395 (clear-stream _test-error-stream) +12396 (clear-stream $_test-error-buffered-file->buffer) +12397 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12398 68/push 0/imm32 +12399 68/push 0/imm32 +12400 89/<- %edx 4/r32/esp +12401 (tailor-exit-descriptor %edx 0x10) +12402 # +12403 (write _test-input-stream "fn foo {\n") +12404 (write _test-input-stream " var a: (array int 3)\n") +12405 (write _test-input-stream " var b/eax: (offset int) <- compute-offset a, 0\n") +12406 (write _test-input-stream " var c/ecx: (addr int) <- copy 0\n") +12407 (write _test-input-stream " b, c <- compute-offset a, 0\n") +12408 (write _test-input-stream "}\n") +12409 # convert +12410 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12411 # registers except esp clobbered at this point +12412 # restore ed +12413 89/<- %edx 4/r32/esp +12414 (flush _test-output-buffered-file) +12415 (flush _test-error-buffered-file) +12416 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12422 # check output +12423 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-many-outputs: output should be empty") +12424 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too many outputs (1 required)" "F - test-compute-offset-with-too-many-outputs: error message") +12425 # check that stop(1) was called +12426 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-many-outputs: exit status") +12427 # don't restore from ebp +12428 81 0/subop/add %esp 8/imm32 +12429 # . epilogue +12430 5d/pop-to-ebp +12431 c3/return +12432 +12433 test-convert-read-from-stream: +12434 # . prologue +12435 55/push-ebp +12436 89/<- %ebp 4/r32/esp +12437 # setup +12438 (clear-stream _test-input-stream) +12439 (clear-stream $_test-input-buffered-file->buffer) +12440 (clear-stream _test-output-stream) +12441 (clear-stream $_test-output-buffered-file->buffer) +12442 # +12443 (write _test-input-stream "fn foo {\n") +12444 (write _test-input-stream " var s/esi: (addr stream int) <- copy 0\n") +12445 (write _test-input-stream " var o/ecx: (addr int) <- copy 0\n") +12446 (write _test-input-stream " read-from-stream s, o\n") +12447 (write _test-input-stream "}\n") +12448 # convert +12449 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +12450 # registers except esp clobbered at this point +12451 # restore ed +12452 89/<- %edx 4/r32/esp +12453 (flush _test-output-buffered-file) +12454 (flush _test-error-buffered-file) +12455 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +12461 # check output +12462 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-read-from-stream/0") +12463 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-read-from-stream/1") +12464 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-read-from-stream/2") +12465 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-read-from-stream/3") +12466 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-read-from-stream/4") +12467 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-read-from-stream/5") +12468 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-read-from-stream/6") +12469 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-read-from-stream/7") +12470 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-read-from-stream/8") +12471 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-read-from-stream/9") +12472 (check-next-stream-line-equal _test-output-stream " (read-from-stream %esi %ecx 0x00000004)" "F - test-convert-read-from-stream/10") +12473 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-read-from-stream/11") +12474 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-read-from-stream/12") +12475 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-read-from-stream/13") +12476 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-read-from-stream/14") +12477 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-read-from-stream/15") +12478 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-read-from-stream/16") +12479 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-read-from-stream/17") +12480 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-read-from-stream/18") +12481 # . epilogue +12482 89/<- %esp 5/r32/ebp +12483 5d/pop-to-ebp +12484 c3/return +12485 +12486 test-convert-read-from-stream-with-correct-payload-size: +12487 # . prologue +12488 55/push-ebp +12489 89/<- %ebp 4/r32/esp +12490 # setup +12491 (clear-stream _test-input-stream) +12492 (clear-stream $_test-input-buffered-file->buffer) +12493 (clear-stream _test-output-stream) +12494 (clear-stream $_test-output-buffered-file->buffer) +12495 # +12496 (write _test-input-stream "fn foo {\n") +12497 (write _test-input-stream " var s/esi: (addr stream handle int) <- copy 0\n") +12498 (write _test-input-stream " var o/ecx: (addr handle int) <- copy 0\n") +12499 (write _test-input-stream " read-from-stream s, o\n") +12500 (write _test-input-stream "}\n") +12501 # convert +12502 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +12503 # registers except esp clobbered at this point +12504 # restore ed +12505 89/<- %edx 4/r32/esp +12506 (flush _test-output-buffered-file) +12507 (flush _test-error-buffered-file) +12508 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +12514 # check output +12515 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-read-from-stream-with-correct-payload-size/0") +12516 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-read-from-stream-with-correct-payload-size/1") +12517 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-read-from-stream-with-correct-payload-size/2") +12518 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-read-from-stream-with-correct-payload-size/3") +12519 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-read-from-stream-with-correct-payload-size/4") +12520 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-read-from-stream-with-correct-payload-size/5") +12521 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-read-from-stream-with-correct-payload-size/6") +12522 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-read-from-stream-with-correct-payload-size/7") +12523 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-read-from-stream-with-correct-payload-size/8") +12524 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-read-from-stream-with-correct-payload-size/9") +12525 (check-next-stream-line-equal _test-output-stream " (read-from-stream %esi %ecx 0x00000008)" "F - test-convert-read-from-stream-with-correct-payload-size/10") +12526 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-read-from-stream-with-correct-payload-size/11") +12527 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-read-from-stream-with-correct-payload-size/12") +12528 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-read-from-stream-with-correct-payload-size/13") +12529 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-read-from-stream-with-correct-payload-size/14") +12530 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-read-from-stream-with-correct-payload-size/15") +12531 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-read-from-stream-with-correct-payload-size/16") +12532 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-read-from-stream-with-correct-payload-size/17") +12533 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-read-from-stream-with-correct-payload-size/18") +12534 # . epilogue +12535 89/<- %esp 5/r32/ebp +12536 5d/pop-to-ebp +12537 c3/return +12538 +12539 test-read-from-stream-with-non-stream-atom-base-type: +12540 # . prologue +12541 55/push-ebp +12542 89/<- %ebp 4/r32/esp +12543 # setup +12544 (clear-stream _test-input-stream) +12545 (clear-stream $_test-input-buffered-file->buffer) +12546 (clear-stream _test-output-stream) +12547 (clear-stream $_test-output-buffered-file->buffer) +12548 (clear-stream _test-error-stream) +12549 (clear-stream $_test-error-buffered-file->buffer) +12550 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12551 68/push 0/imm32 +12552 68/push 0/imm32 +12553 89/<- %edx 4/r32/esp +12554 (tailor-exit-descriptor %edx 0x10) +12555 # +12556 (write _test-input-stream "fn foo {\n") +12557 (write _test-input-stream " var a: int\n") +12558 (write _test-input-stream " read-from-stream a, 0\n") +12559 (write _test-input-stream "}\n") +12560 # convert +12561 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12562 # registers except esp clobbered at this point +12563 # restore ed +12564 89/<- %edx 4/r32/esp +12565 (flush _test-output-buffered-file) +12566 (flush _test-error-buffered-file) +12567 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12573 # check output +12574 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-atom-base-type: output should be empty") +12575 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-atom-base-type: error message") +12576 # check that stop(1) was called +12577 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-atom-base-type: exit status") +12578 # don't restore from ebp +12579 81 0/subop/add %esp 8/imm32 +12580 # . epilogue +12581 5d/pop-to-ebp +12582 c3/return +12583 +12584 test-read-from-stream-with-non-stream-compound-base-type: +12585 # . prologue +12586 55/push-ebp +12587 89/<- %ebp 4/r32/esp +12588 # setup +12589 (clear-stream _test-input-stream) +12590 (clear-stream $_test-input-buffered-file->buffer) +12591 (clear-stream _test-output-stream) +12592 (clear-stream $_test-output-buffered-file->buffer) +12593 (clear-stream _test-error-stream) +12594 (clear-stream $_test-error-buffered-file->buffer) +12595 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12596 68/push 0/imm32 +12597 68/push 0/imm32 +12598 89/<- %edx 4/r32/esp +12599 (tailor-exit-descriptor %edx 0x10) +12600 # +12601 (write _test-input-stream "fn foo {\n") +12602 (write _test-input-stream " var a: (handle int)\n") +12603 (write _test-input-stream " read-from-stream a, 0\n") +12604 (write _test-input-stream "}\n") +12605 # convert +12606 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12607 # registers except esp clobbered at this point +12608 # restore ed +12609 89/<- %edx 4/r32/esp +12610 (flush _test-output-buffered-file) +12611 (flush _test-error-buffered-file) +12612 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12618 # check output +12619 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-compound-base-type: output should be empty") +12620 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-compound-base-type: error message") +12621 # check that stop(1) was called +12622 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-compound-base-type: exit status") +12623 # don't restore from ebp +12624 81 0/subop/add %esp 8/imm32 +12625 # . epilogue +12626 5d/pop-to-ebp +12627 c3/return +12628 +12629 test-read-from-stream-with-non-stream-compound-base-type-2: +12630 # . prologue +12631 55/push-ebp +12632 89/<- %ebp 4/r32/esp +12633 # setup +12634 (clear-stream _test-input-stream) +12635 (clear-stream $_test-input-buffered-file->buffer) +12636 (clear-stream _test-output-stream) +12637 (clear-stream $_test-output-buffered-file->buffer) +12638 (clear-stream _test-error-stream) +12639 (clear-stream $_test-error-buffered-file->buffer) +12640 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12641 68/push 0/imm32 +12642 68/push 0/imm32 +12643 89/<- %edx 4/r32/esp +12644 (tailor-exit-descriptor %edx 0x10) +12645 # +12646 (write _test-input-stream "fn foo {\n") +12647 (write _test-input-stream " var a: (addr int)\n") +12648 (write _test-input-stream " read-from-stream a, 0\n") +12649 (write _test-input-stream "}\n") +12650 # convert +12651 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12652 # registers except esp clobbered at this point +12653 # restore ed +12654 89/<- %edx 4/r32/esp +12655 (flush _test-output-buffered-file) +12656 (flush _test-error-buffered-file) +12657 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12663 # check output +12664 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-compound-base-type-2: output should be empty") +12665 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-compound-base-type-2: error message") +12666 # check that stop(1) was called +12667 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-compound-base-type-2: exit status") +12668 # don't restore from ebp +12669 81 0/subop/add %esp 8/imm32 +12670 # . epilogue +12671 5d/pop-to-ebp +12672 c3/return +12673 +12674 test-read-from-stream-with-stream-atom-base-type: +12675 # . prologue +12676 55/push-ebp +12677 89/<- %ebp 4/r32/esp +12678 # setup +12679 (clear-stream _test-input-stream) +12680 (clear-stream $_test-input-buffered-file->buffer) +12681 (clear-stream _test-output-stream) +12682 (clear-stream $_test-output-buffered-file->buffer) +12683 (clear-stream _test-error-stream) +12684 (clear-stream $_test-error-buffered-file->buffer) +12685 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12686 68/push 0/imm32 +12687 68/push 0/imm32 +12688 89/<- %edx 4/r32/esp +12689 (tailor-exit-descriptor %edx 0x10) +12690 # +12691 (write _test-input-stream "fn foo {\n") +12692 (write _test-input-stream " var a: stream\n") +12693 (write _test-input-stream " read-from-stream a, 0\n") +12694 (write _test-input-stream "}\n") +12695 # convert +12696 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12697 # registers except esp clobbered at this point +12698 # restore ed +12699 89/<- %edx 4/r32/esp +12700 (flush _test-output-buffered-file) +12701 (flush _test-error-buffered-file) +12702 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12708 # check output +12709 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-stream-atom-base-type: output should be empty") +12710 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-stream-atom-base-type: error message") +12711 # check that stop(1) was called +12712 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-stream-atom-base-type: exit status") +12713 # don't restore from ebp +12714 81 0/subop/add %esp 8/imm32 +12715 # . epilogue +12716 5d/pop-to-ebp +12717 c3/return +12718 +12719 test-read-from-stream-with-wrong-index-type: +12720 # . prologue +12721 55/push-ebp +12722 89/<- %ebp 4/r32/esp +12723 # setup +12724 (clear-stream _test-input-stream) +12725 (clear-stream $_test-input-buffered-file->buffer) +12726 (clear-stream _test-output-stream) +12727 (clear-stream $_test-output-buffered-file->buffer) +12728 (clear-stream _test-error-stream) +12729 (clear-stream $_test-error-buffered-file->buffer) +12730 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12731 68/push 0/imm32 +12732 68/push 0/imm32 +12733 89/<- %edx 4/r32/esp +12734 (tailor-exit-descriptor %edx 0x10) +12735 # +12736 (write _test-input-stream "fn foo {\n") +12737 (write _test-input-stream " var a/eax: (addr stream int) <- copy 0\n") +12738 (write _test-input-stream " var b: boolean\n") +12739 (write _test-input-stream " read-from-stream a, b\n") +12740 (write _test-input-stream "}\n") +12741 # convert +12742 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12743 # registers except esp clobbered at this point +12744 # restore ed +12745 89/<- %edx 4/r32/esp +12746 (flush _test-output-buffered-file) +12747 (flush _test-error-buffered-file) +12748 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12754 # check output +12755 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-wrong-index-type: output should be empty") +12756 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: target 'b' must be an addr" "F - test-read-from-stream-with-wrong-index-type: error message") +12757 # check that stop(1) was called +12758 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-wrong-index-type: exit status") +12759 # don't restore from ebp +12760 81 0/subop/add %esp 8/imm32 +12761 # . epilogue +12762 5d/pop-to-ebp +12763 c3/return +12764 +12765 test-read-from-stream-with-no-inouts: +12766 # . prologue +12767 55/push-ebp +12768 89/<- %ebp 4/r32/esp +12769 # setup +12770 (clear-stream _test-input-stream) +12771 (clear-stream $_test-input-buffered-file->buffer) +12772 (clear-stream _test-output-stream) +12773 (clear-stream $_test-output-buffered-file->buffer) +12774 (clear-stream _test-error-stream) +12775 (clear-stream $_test-error-buffered-file->buffer) +12776 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12777 68/push 0/imm32 +12778 68/push 0/imm32 +12779 89/<- %edx 4/r32/esp +12780 (tailor-exit-descriptor %edx 0x10) +12781 # +12782 (write _test-input-stream "fn foo {\n") +12783 (write _test-input-stream " read-from-stream\n") +12784 (write _test-input-stream "}\n") +12785 # convert +12786 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12787 # registers except esp clobbered at this point +12788 # restore ed +12789 89/<- %edx 4/r32/esp +12790 (flush _test-output-buffered-file) +12791 (flush _test-error-buffered-file) +12792 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12798 # check output +12799 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-no-inouts: output should be empty") +12800 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too few inouts (2 required)" "F - test-read-from-stream-with-no-inouts: error message") +12801 # check that stop(1) was called +12802 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-no-inouts: exit status") +12803 # don't restore from ebp +12804 81 0/subop/add %esp 8/imm32 +12805 # . epilogue +12806 5d/pop-to-ebp +12807 c3/return +12808 +12809 test-read-from-stream-with-too-few-inouts: +12810 # . prologue +12811 55/push-ebp +12812 89/<- %ebp 4/r32/esp +12813 # setup +12814 (clear-stream _test-input-stream) +12815 (clear-stream $_test-input-buffered-file->buffer) +12816 (clear-stream _test-output-stream) +12817 (clear-stream $_test-output-buffered-file->buffer) +12818 (clear-stream _test-error-stream) +12819 (clear-stream $_test-error-buffered-file->buffer) +12820 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12821 68/push 0/imm32 +12822 68/push 0/imm32 +12823 89/<- %edx 4/r32/esp +12824 (tailor-exit-descriptor %edx 0x10) +12825 # +12826 (write _test-input-stream "fn foo {\n") +12827 (write _test-input-stream " var a: (addr stream int)\n") +12828 (write _test-input-stream " read-from-stream a\n") +12829 (write _test-input-stream "}\n") +12830 # convert +12831 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12832 # registers except esp clobbered at this point +12833 # restore ed +12834 89/<- %edx 4/r32/esp +12835 (flush _test-output-buffered-file) +12836 (flush _test-error-buffered-file) +12837 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12843 # check output +12844 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-too-few-inouts: output should be empty") +12845 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too few inouts (2 required)" "F - test-read-from-stream-with-too-few-inouts: error message") +12846 # check that stop(1) was called +12847 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-too-few-inouts: exit status") +12848 # don't restore from ebp +12849 81 0/subop/add %esp 8/imm32 +12850 # . epilogue +12851 5d/pop-to-ebp +12852 c3/return +12853 +12854 test-read-from-stream-with-too-many-inouts: +12855 # . prologue +12856 55/push-ebp +12857 89/<- %ebp 4/r32/esp +12858 # setup +12859 (clear-stream _test-input-stream) +12860 (clear-stream $_test-input-buffered-file->buffer) +12861 (clear-stream _test-output-stream) +12862 (clear-stream $_test-output-buffered-file->buffer) +12863 (clear-stream _test-error-stream) +12864 (clear-stream $_test-error-buffered-file->buffer) +12865 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12866 68/push 0/imm32 +12867 68/push 0/imm32 +12868 89/<- %edx 4/r32/esp +12869 (tailor-exit-descriptor %edx 0x10) +12870 # +12871 (write _test-input-stream "fn foo {\n") +12872 (write _test-input-stream " var a: (addr stream int)\n") +12873 (write _test-input-stream " var b: (addr int)\n") +12874 (write _test-input-stream " read-from-stream a, b, 0\n") +12875 (write _test-input-stream "}\n") +12876 # convert +12877 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12878 # registers except esp clobbered at this point +12879 # restore ed +12880 89/<- %edx 4/r32/esp +12881 (flush _test-output-buffered-file) +12882 (flush _test-error-buffered-file) +12883 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12889 # check output +12890 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-too-many-inouts: output should be empty") +12891 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too many inouts (2 required)" "F - test-read-from-stream-with-too-many-inouts: error message") +12892 # check that stop(1) was called +12893 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-too-many-inouts: exit status") +12894 # don't restore from ebp +12895 81 0/subop/add %esp 8/imm32 +12896 # . epilogue +12897 5d/pop-to-ebp +12898 c3/return +12899 +12900 test-read-from-stream-with-output: +12901 # . prologue +12902 55/push-ebp +12903 89/<- %ebp 4/r32/esp +12904 # setup +12905 (clear-stream _test-input-stream) +12906 (clear-stream $_test-input-buffered-file->buffer) +12907 (clear-stream _test-output-stream) +12908 (clear-stream $_test-output-buffered-file->buffer) +12909 (clear-stream _test-error-stream) +12910 (clear-stream $_test-error-buffered-file->buffer) +12911 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +12912 68/push 0/imm32 +12913 68/push 0/imm32 +12914 89/<- %edx 4/r32/esp +12915 (tailor-exit-descriptor %edx 0x10) +12916 # +12917 (write _test-input-stream "fn foo {\n") +12918 (write _test-input-stream " var a: (addr stream int)\n") +12919 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n") +12920 (write _test-input-stream " b <- read-from-stream a, b\n") +12921 (write _test-input-stream "}\n") +12922 # convert +12923 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +12924 # registers except esp clobbered at this point +12925 # restore ed +12926 89/<- %edx 4/r32/esp +12927 (flush _test-output-buffered-file) +12928 (flush _test-error-buffered-file) +12929 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +12935 # check output +12936 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-output: output should be empty") +12937 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: unexpected output" "F - test-read-from-stream-with-output: error message") +12938 # check that stop(1) was called +12939 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-output: exit status") +12940 # don't restore from ebp +12941 81 0/subop/add %esp 8/imm32 +12942 # . epilogue +12943 5d/pop-to-ebp +12944 c3/return +12945 +12946 test-convert-write-to-stream: +12947 # . prologue +12948 55/push-ebp +12949 89/<- %ebp 4/r32/esp +12950 # setup +12951 (clear-stream _test-input-stream) +12952 (clear-stream $_test-input-buffered-file->buffer) +12953 (clear-stream _test-output-stream) +12954 (clear-stream $_test-output-buffered-file->buffer) +12955 # +12956 (write _test-input-stream "fn foo {\n") +12957 (write _test-input-stream " var s/esi: (addr stream int) <- copy 0\n") +12958 (write _test-input-stream " var o/ecx: (addr int) <- copy 0\n") +12959 (write _test-input-stream " write-to-stream s, o\n") +12960 (write _test-input-stream "}\n") +12961 # convert +12962 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +12963 # registers except esp clobbered at this point +12964 # restore ed +12965 89/<- %edx 4/r32/esp +12966 (flush _test-output-buffered-file) +12967 (flush _test-error-buffered-file) +12968 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +12974 # check output +12975 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-write-to-stream/0") +12976 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-write-to-stream/1") +12977 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-write-to-stream/2") +12978 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-write-to-stream/3") +12979 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-write-to-stream/4") +12980 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-write-to-stream/5") +12981 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-write-to-stream/6") +12982 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-write-to-stream/7") +12983 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-write-to-stream/8") +12984 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-write-to-stream/9") +12985 (check-next-stream-line-equal _test-output-stream " (write-to-stream %esi %ecx 0x00000004)" "F - test-convert-write-to-stream/10") +12986 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-write-to-stream/11") +12987 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-write-to-stream/12") +12988 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-write-to-stream/13") +12989 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-write-to-stream/14") +12990 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-write-to-stream/15") +12991 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-write-to-stream/16") +12992 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-write-to-stream/17") +12993 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-write-to-stream/18") +12994 # . epilogue +12995 89/<- %esp 5/r32/ebp +12996 5d/pop-to-ebp +12997 c3/return +12998 +12999 test-convert-write-to-stream-with-correct-payload-size: +13000 # . prologue +13001 55/push-ebp +13002 89/<- %ebp 4/r32/esp +13003 # setup +13004 (clear-stream _test-input-stream) +13005 (clear-stream $_test-input-buffered-file->buffer) +13006 (clear-stream _test-output-stream) +13007 (clear-stream $_test-output-buffered-file->buffer) +13008 # +13009 (write _test-input-stream "fn foo {\n") +13010 (write _test-input-stream " var s/esi: (addr stream handle int) <- copy 0\n") +13011 (write _test-input-stream " var o/ecx: (addr handle int) <- copy 0\n") +13012 (write _test-input-stream " write-to-stream s, o\n") +13013 (write _test-input-stream "}\n") +13014 # convert +13015 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +13016 # registers except esp clobbered at this point +13017 # restore ed +13018 89/<- %edx 4/r32/esp +13019 (flush _test-output-buffered-file) +13020 (flush _test-error-buffered-file) +13021 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +13027 # check output +13028 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-write-to-stream-with-correct-payload-size/0") +13029 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-write-to-stream-with-correct-payload-size/1") +13030 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-write-to-stream-with-correct-payload-size/2") +13031 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-write-to-stream-with-correct-payload-size/3") +13032 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-write-to-stream-with-correct-payload-size/4") +13033 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-write-to-stream-with-correct-payload-size/5") +13034 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-write-to-stream-with-correct-payload-size/6") +13035 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-write-to-stream-with-correct-payload-size/7") +13036 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-write-to-stream-with-correct-payload-size/8") +13037 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-write-to-stream-with-correct-payload-size/9") +13038 (check-next-stream-line-equal _test-output-stream " (write-to-stream %esi %ecx 0x00000008)" "F - test-convert-write-to-stream-with-correct-payload-size/10") +13039 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-write-to-stream-with-correct-payload-size/11") +13040 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-write-to-stream-with-correct-payload-size/12") +13041 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-write-to-stream-with-correct-payload-size/13") +13042 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-write-to-stream-with-correct-payload-size/14") +13043 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-write-to-stream-with-correct-payload-size/15") +13044 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-write-to-stream-with-correct-payload-size/16") +13045 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-write-to-stream-with-correct-payload-size/17") +13046 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-write-to-stream-with-correct-payload-size/18") +13047 # . epilogue +13048 89/<- %esp 5/r32/ebp +13049 5d/pop-to-ebp +13050 c3/return +13051 +13052 test-write-to-stream-with-non-stream-atom-base-type: +13053 # . prologue +13054 55/push-ebp +13055 89/<- %ebp 4/r32/esp +13056 # setup +13057 (clear-stream _test-input-stream) +13058 (clear-stream $_test-input-buffered-file->buffer) +13059 (clear-stream _test-output-stream) +13060 (clear-stream $_test-output-buffered-file->buffer) +13061 (clear-stream _test-error-stream) +13062 (clear-stream $_test-error-buffered-file->buffer) +13063 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13064 68/push 0/imm32 +13065 68/push 0/imm32 +13066 89/<- %edx 4/r32/esp +13067 (tailor-exit-descriptor %edx 0x10) +13068 # +13069 (write _test-input-stream "fn foo {\n") +13070 (write _test-input-stream " var a: int\n") +13071 (write _test-input-stream " write-to-stream a, 0\n") +13072 (write _test-input-stream "}\n") +13073 # convert +13074 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13075 # registers except esp clobbered at this point +13076 # restore ed +13077 89/<- %edx 4/r32/esp +13078 (flush _test-output-buffered-file) +13079 (flush _test-error-buffered-file) +13080 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13086 # check output +13087 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-atom-base-type: output should be empty") +13088 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-atom-base-type: error message") +13089 # check that stop(1) was called +13090 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-atom-base-type: exit status") +13091 # don't restore from ebp +13092 81 0/subop/add %esp 8/imm32 +13093 # . epilogue +13094 5d/pop-to-ebp +13095 c3/return +13096 +13097 test-write-to-stream-with-non-stream-compound-base-type: +13098 # . prologue +13099 55/push-ebp +13100 89/<- %ebp 4/r32/esp +13101 # setup +13102 (clear-stream _test-input-stream) +13103 (clear-stream $_test-input-buffered-file->buffer) +13104 (clear-stream _test-output-stream) +13105 (clear-stream $_test-output-buffered-file->buffer) +13106 (clear-stream _test-error-stream) +13107 (clear-stream $_test-error-buffered-file->buffer) +13108 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13109 68/push 0/imm32 +13110 68/push 0/imm32 +13111 89/<- %edx 4/r32/esp +13112 (tailor-exit-descriptor %edx 0x10) +13113 # +13114 (write _test-input-stream "fn foo {\n") +13115 (write _test-input-stream " var a: (handle int)\n") +13116 (write _test-input-stream " write-to-stream a, 0\n") +13117 (write _test-input-stream "}\n") +13118 # convert +13119 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13120 # registers except esp clobbered at this point +13121 # restore ed +13122 89/<- %edx 4/r32/esp +13123 (flush _test-output-buffered-file) +13124 (flush _test-error-buffered-file) +13125 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13131 # check output +13132 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-compound-base-type: output should be empty") +13133 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-compound-base-type: error message") +13134 # check that stop(1) was called +13135 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-compound-base-type: exit status") +13136 # don't restore from ebp +13137 81 0/subop/add %esp 8/imm32 +13138 # . epilogue +13139 5d/pop-to-ebp +13140 c3/return +13141 +13142 test-write-to-stream-with-non-stream-compound-base-type-2: +13143 # . prologue +13144 55/push-ebp +13145 89/<- %ebp 4/r32/esp +13146 # setup +13147 (clear-stream _test-input-stream) +13148 (clear-stream $_test-input-buffered-file->buffer) +13149 (clear-stream _test-output-stream) +13150 (clear-stream $_test-output-buffered-file->buffer) +13151 (clear-stream _test-error-stream) +13152 (clear-stream $_test-error-buffered-file->buffer) +13153 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13154 68/push 0/imm32 +13155 68/push 0/imm32 +13156 89/<- %edx 4/r32/esp +13157 (tailor-exit-descriptor %edx 0x10) +13158 # +13159 (write _test-input-stream "fn foo {\n") +13160 (write _test-input-stream " var a: (addr int)\n") +13161 (write _test-input-stream " write-to-stream a, 0\n") +13162 (write _test-input-stream "}\n") +13163 # convert +13164 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13165 # registers except esp clobbered at this point +13166 # restore ed +13167 89/<- %edx 4/r32/esp +13168 (flush _test-output-buffered-file) +13169 (flush _test-error-buffered-file) +13170 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13176 # check output +13177 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-compound-base-type-2: output should be empty") +13178 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-compound-base-type-2: error message") +13179 # check that stop(1) was called +13180 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-compound-base-type-2: exit status") +13181 # don't restore from ebp +13182 81 0/subop/add %esp 8/imm32 +13183 # . epilogue +13184 5d/pop-to-ebp +13185 c3/return +13186 +13187 test-write-to-stream-with-stream-atom-base-type: +13188 # . prologue +13189 55/push-ebp +13190 89/<- %ebp 4/r32/esp +13191 # setup +13192 (clear-stream _test-input-stream) +13193 (clear-stream $_test-input-buffered-file->buffer) +13194 (clear-stream _test-output-stream) +13195 (clear-stream $_test-output-buffered-file->buffer) +13196 (clear-stream _test-error-stream) +13197 (clear-stream $_test-error-buffered-file->buffer) +13198 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13199 68/push 0/imm32 +13200 68/push 0/imm32 +13201 89/<- %edx 4/r32/esp +13202 (tailor-exit-descriptor %edx 0x10) +13203 # +13204 (write _test-input-stream "fn foo {\n") +13205 (write _test-input-stream " var a: stream\n") +13206 (write _test-input-stream " write-to-stream a, 0\n") +13207 (write _test-input-stream "}\n") +13208 # convert +13209 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13210 # registers except esp clobbered at this point +13211 # restore ed +13212 89/<- %edx 4/r32/esp +13213 (flush _test-output-buffered-file) +13214 (flush _test-error-buffered-file) +13215 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13221 # check output +13222 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-stream-atom-base-type: output should be empty") +13223 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-stream-atom-base-type: error message") +13224 # check that stop(1) was called +13225 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-stream-atom-base-type: exit status") +13226 # don't restore from ebp +13227 81 0/subop/add %esp 8/imm32 +13228 # . epilogue +13229 5d/pop-to-ebp +13230 c3/return +13231 +13232 test-write-to-stream-with-wrong-index-type: +13233 # . prologue +13234 55/push-ebp +13235 89/<- %ebp 4/r32/esp +13236 # setup +13237 (clear-stream _test-input-stream) +13238 (clear-stream $_test-input-buffered-file->buffer) +13239 (clear-stream _test-output-stream) +13240 (clear-stream $_test-output-buffered-file->buffer) +13241 (clear-stream _test-error-stream) +13242 (clear-stream $_test-error-buffered-file->buffer) +13243 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13244 68/push 0/imm32 +13245 68/push 0/imm32 +13246 89/<- %edx 4/r32/esp +13247 (tailor-exit-descriptor %edx 0x10) +13248 # +13249 (write _test-input-stream "fn foo {\n") +13250 (write _test-input-stream " var a/eax: (addr stream int) <- copy 0\n") +13251 (write _test-input-stream " var b: boolean\n") +13252 (write _test-input-stream " write-to-stream a, b\n") +13253 (write _test-input-stream "}\n") +13254 # convert +13255 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13256 # registers except esp clobbered at this point +13257 # restore ed +13258 89/<- %edx 4/r32/esp +13259 (flush _test-output-buffered-file) +13260 (flush _test-error-buffered-file) +13261 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13267 # check output +13268 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-wrong-index-type: output should be empty") +13269 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: target 'b' must be an addr" "F - test-write-to-stream-with-wrong-index-type: error message") +13270 # check that stop(1) was called +13271 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-wrong-index-type: exit status") +13272 # don't restore from ebp +13273 81 0/subop/add %esp 8/imm32 +13274 # . epilogue +13275 5d/pop-to-ebp +13276 c3/return +13277 +13278 test-write-to-stream-with-no-inouts: +13279 # . prologue +13280 55/push-ebp +13281 89/<- %ebp 4/r32/esp +13282 # setup +13283 (clear-stream _test-input-stream) +13284 (clear-stream $_test-input-buffered-file->buffer) +13285 (clear-stream _test-output-stream) +13286 (clear-stream $_test-output-buffered-file->buffer) +13287 (clear-stream _test-error-stream) +13288 (clear-stream $_test-error-buffered-file->buffer) +13289 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13290 68/push 0/imm32 +13291 68/push 0/imm32 +13292 89/<- %edx 4/r32/esp +13293 (tailor-exit-descriptor %edx 0x10) +13294 # +13295 (write _test-input-stream "fn foo {\n") +13296 (write _test-input-stream " write-to-stream\n") +13297 (write _test-input-stream "}\n") +13298 # convert +13299 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13300 # registers except esp clobbered at this point +13301 # restore ed +13302 89/<- %edx 4/r32/esp +13303 (flush _test-output-buffered-file) +13304 (flush _test-error-buffered-file) +13305 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13311 # check output +13312 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-no-inouts: output should be empty") +13313 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too few inouts (2 required)" "F - test-write-to-stream-with-no-inouts: error message") +13314 # check that stop(1) was called +13315 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-no-inouts: exit status") +13316 # don't restore from ebp +13317 81 0/subop/add %esp 8/imm32 +13318 # . epilogue +13319 5d/pop-to-ebp +13320 c3/return +13321 +13322 test-write-to-stream-with-too-few-inouts: +13323 # . prologue +13324 55/push-ebp +13325 89/<- %ebp 4/r32/esp +13326 # setup +13327 (clear-stream _test-input-stream) +13328 (clear-stream $_test-input-buffered-file->buffer) +13329 (clear-stream _test-output-stream) +13330 (clear-stream $_test-output-buffered-file->buffer) +13331 (clear-stream _test-error-stream) +13332 (clear-stream $_test-error-buffered-file->buffer) +13333 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13334 68/push 0/imm32 +13335 68/push 0/imm32 +13336 89/<- %edx 4/r32/esp +13337 (tailor-exit-descriptor %edx 0x10) +13338 # +13339 (write _test-input-stream "fn foo {\n") +13340 (write _test-input-stream " var a: (addr stream int)\n") +13341 (write _test-input-stream " write-to-stream a\n") +13342 (write _test-input-stream "}\n") +13343 # convert +13344 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13345 # registers except esp clobbered at this point +13346 # restore ed +13347 89/<- %edx 4/r32/esp +13348 (flush _test-output-buffered-file) +13349 (flush _test-error-buffered-file) +13350 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13356 # check output +13357 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-too-few-inouts: output should be empty") +13358 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too few inouts (2 required)" "F - test-write-to-stream-with-too-few-inouts: error message") +13359 # check that stop(1) was called +13360 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-too-few-inouts: exit status") +13361 # don't restore from ebp +13362 81 0/subop/add %esp 8/imm32 +13363 # . epilogue +13364 5d/pop-to-ebp +13365 c3/return +13366 +13367 test-write-to-stream-with-too-many-inouts: +13368 # . prologue +13369 55/push-ebp +13370 89/<- %ebp 4/r32/esp +13371 # setup +13372 (clear-stream _test-input-stream) +13373 (clear-stream $_test-input-buffered-file->buffer) +13374 (clear-stream _test-output-stream) +13375 (clear-stream $_test-output-buffered-file->buffer) +13376 (clear-stream _test-error-stream) +13377 (clear-stream $_test-error-buffered-file->buffer) +13378 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13379 68/push 0/imm32 +13380 68/push 0/imm32 +13381 89/<- %edx 4/r32/esp +13382 (tailor-exit-descriptor %edx 0x10) +13383 # +13384 (write _test-input-stream "fn foo {\n") +13385 (write _test-input-stream " var a: (addr stream int)\n") +13386 (write _test-input-stream " var b: (addr int)\n") +13387 (write _test-input-stream " write-to-stream a, b, 0\n") +13388 (write _test-input-stream "}\n") +13389 # convert +13390 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13391 # registers except esp clobbered at this point +13392 # restore ed +13393 89/<- %edx 4/r32/esp +13394 (flush _test-output-buffered-file) +13395 (flush _test-error-buffered-file) +13396 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13402 # check output +13403 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-too-many-inouts: output should be empty") +13404 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too many inouts (2 required)" "F - test-write-to-stream-with-too-many-inouts: error message") +13405 # check that stop(1) was called +13406 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-too-many-inouts: exit status") +13407 # don't restore from ebp +13408 81 0/subop/add %esp 8/imm32 +13409 # . epilogue +13410 5d/pop-to-ebp +13411 c3/return +13412 +13413 test-write-to-stream-with-output: +13414 # . prologue +13415 55/push-ebp +13416 89/<- %ebp 4/r32/esp +13417 # setup +13418 (clear-stream _test-input-stream) +13419 (clear-stream $_test-input-buffered-file->buffer) +13420 (clear-stream _test-output-stream) +13421 (clear-stream $_test-output-buffered-file->buffer) +13422 (clear-stream _test-error-stream) +13423 (clear-stream $_test-error-buffered-file->buffer) +13424 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13425 68/push 0/imm32 +13426 68/push 0/imm32 +13427 89/<- %edx 4/r32/esp +13428 (tailor-exit-descriptor %edx 0x10) +13429 # +13430 (write _test-input-stream "fn foo {\n") +13431 (write _test-input-stream " var a: (addr stream int)\n") +13432 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n") +13433 (write _test-input-stream " b <- write-to-stream a, b\n") +13434 (write _test-input-stream "}\n") +13435 # convert +13436 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13437 # registers except esp clobbered at this point +13438 # restore ed +13439 89/<- %edx 4/r32/esp +13440 (flush _test-output-buffered-file) +13441 (flush _test-error-buffered-file) +13442 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13448 # check output +13449 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-output: output should be empty") +13450 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: unexpected output" "F - test-write-to-stream-with-output: error message") +13451 # check that stop(1) was called +13452 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-output: exit status") +13453 # don't restore from ebp +13454 81 0/subop/add %esp 8/imm32 +13455 # . epilogue +13456 5d/pop-to-ebp +13457 c3/return +13458 +13459 test-length-with-non-array-atom-base-type: +13460 # . prologue +13461 55/push-ebp +13462 89/<- %ebp 4/r32/esp +13463 # setup +13464 (clear-stream _test-input-stream) +13465 (clear-stream $_test-input-buffered-file->buffer) +13466 (clear-stream _test-output-stream) +13467 (clear-stream $_test-output-buffered-file->buffer) +13468 (clear-stream _test-error-stream) +13469 (clear-stream $_test-error-buffered-file->buffer) +13470 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13471 68/push 0/imm32 +13472 68/push 0/imm32 +13473 89/<- %edx 4/r32/esp +13474 (tailor-exit-descriptor %edx 0x10) +13475 # +13476 (write _test-input-stream "fn foo {\n") +13477 (write _test-input-stream " var a: int\n") +13478 (write _test-input-stream " var c/ecx: int <- length a\n") +13479 (write _test-input-stream "}\n") +13480 # convert +13481 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13482 # registers except esp clobbered at this point +13483 # restore ed +13484 89/<- %edx 4/r32/esp +13485 (flush _test-output-buffered-file) +13486 (flush _test-error-buffered-file) +13487 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13493 # check output +13494 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-atom-base-type: output should be empty") +13495 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-atom-base-type: error message") +13496 # check that stop(1) was called +13497 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-atom-base-type: exit status") +13498 # don't restore from ebp +13499 81 0/subop/add %esp 8/imm32 +13500 # . epilogue +13501 5d/pop-to-ebp +13502 c3/return +13503 +13504 test-length-with-non-array-compound-base-type: +13505 # . prologue +13506 55/push-ebp +13507 89/<- %ebp 4/r32/esp +13508 # setup +13509 (clear-stream _test-input-stream) +13510 (clear-stream $_test-input-buffered-file->buffer) +13511 (clear-stream _test-output-stream) +13512 (clear-stream $_test-output-buffered-file->buffer) +13513 (clear-stream _test-error-stream) +13514 (clear-stream $_test-error-buffered-file->buffer) +13515 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13516 68/push 0/imm32 +13517 68/push 0/imm32 +13518 89/<- %edx 4/r32/esp +13519 (tailor-exit-descriptor %edx 0x10) +13520 # +13521 (write _test-input-stream "fn foo {\n") +13522 (write _test-input-stream " var a: (handle int)\n") +13523 (write _test-input-stream " var c/ecx: (addr int) <- length a, 0\n") +13524 (write _test-input-stream "}\n") +13525 # convert +13526 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13527 # registers except esp clobbered at this point +13528 # restore ed +13529 89/<- %edx 4/r32/esp +13530 (flush _test-output-buffered-file) +13531 (flush _test-error-buffered-file) +13532 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13538 # check output +13539 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-compound-base-type: output should be empty") +13540 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-compound-base-type: error message") +13541 # check that stop(1) was called +13542 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-compound-base-type: exit status") +13543 # don't restore from ebp +13544 81 0/subop/add %esp 8/imm32 +13545 # . epilogue +13546 5d/pop-to-ebp +13547 c3/return +13548 +13549 test-length-with-non-array-compound-base-type-2: +13550 # . prologue +13551 55/push-ebp +13552 89/<- %ebp 4/r32/esp +13553 # setup +13554 (clear-stream _test-input-stream) +13555 (clear-stream $_test-input-buffered-file->buffer) +13556 (clear-stream _test-output-stream) +13557 (clear-stream $_test-output-buffered-file->buffer) +13558 (clear-stream _test-error-stream) +13559 (clear-stream $_test-error-buffered-file->buffer) +13560 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13561 68/push 0/imm32 +13562 68/push 0/imm32 +13563 89/<- %edx 4/r32/esp +13564 (tailor-exit-descriptor %edx 0x10) +13565 # +13566 (write _test-input-stream "fn foo {\n") +13567 (write _test-input-stream " var a: (addr int)\n") +13568 (write _test-input-stream " var c/ecx: (addr int) <- length a, 0\n") +13569 (write _test-input-stream "}\n") +13570 # convert +13571 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13572 # registers except esp clobbered at this point +13573 # restore ed +13574 89/<- %edx 4/r32/esp +13575 (flush _test-output-buffered-file) +13576 (flush _test-error-buffered-file) +13577 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13583 # check output +13584 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-compound-base-type-2: output should be empty") +13585 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-compound-base-type-2: error message") +13586 # check that stop(1) was called +13587 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-compound-base-type-2: exit status") +13588 # don't restore from ebp +13589 81 0/subop/add %esp 8/imm32 +13590 # . epilogue +13591 5d/pop-to-ebp +13592 c3/return +13593 +13594 test-length-with-array-atom-base-type: +13595 # . prologue +13596 55/push-ebp +13597 89/<- %ebp 4/r32/esp +13598 # setup +13599 (clear-stream _test-input-stream) +13600 (clear-stream $_test-input-buffered-file->buffer) +13601 (clear-stream _test-output-stream) +13602 (clear-stream $_test-output-buffered-file->buffer) +13603 (clear-stream _test-error-stream) +13604 (clear-stream $_test-error-buffered-file->buffer) +13605 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13606 68/push 0/imm32 +13607 68/push 0/imm32 +13608 89/<- %edx 4/r32/esp +13609 (tailor-exit-descriptor %edx 0x10) +13610 # +13611 (write _test-input-stream "fn foo {\n") +13612 (write _test-input-stream " var a: array\n") +13613 (write _test-input-stream " var c/ecx: (addr int) <- length a\n") +13614 (write _test-input-stream "}\n") +13615 # convert +13616 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13617 # registers except esp clobbered at this point +13618 # restore ed +13619 89/<- %edx 4/r32/esp +13620 (flush _test-output-buffered-file) +13621 (flush _test-error-buffered-file) +13622 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13628 # check output +13629 (check-stream-equal _test-output-stream "" "F - test-length-with-array-atom-base-type: output should be empty") +13630 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: array 'a' must specify the type of its elements" "F - test-length-with-array-atom-base-type: error message") +13631 # check that stop(1) was called +13632 (check-ints-equal *(edx+4) 2 "F - test-length-with-array-atom-base-type: exit status") +13633 # don't restore from ebp +13634 81 0/subop/add %esp 8/imm32 +13635 # . epilogue +13636 5d/pop-to-ebp +13637 c3/return +13638 +13639 test-length-with-addr-base-on-stack: +13640 # . prologue +13641 55/push-ebp +13642 89/<- %ebp 4/r32/esp +13643 # setup +13644 (clear-stream _test-input-stream) +13645 (clear-stream $_test-input-buffered-file->buffer) +13646 (clear-stream _test-output-stream) +13647 (clear-stream $_test-output-buffered-file->buffer) +13648 (clear-stream _test-error-stream) +13649 (clear-stream $_test-error-buffered-file->buffer) +13650 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13651 68/push 0/imm32 +13652 68/push 0/imm32 +13653 89/<- %edx 4/r32/esp +13654 (tailor-exit-descriptor %edx 0x10) +13655 # +13656 (write _test-input-stream "fn foo {\n") +13657 (write _test-input-stream " var a: (addr array int)\n") +13658 (write _test-input-stream " var c/ecx: (addr int) <- length a\n") +13659 (write _test-input-stream "}\n") +13660 # convert +13661 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13662 # registers except esp clobbered at this point +13663 # restore ed +13664 89/<- %edx 4/r32/esp +13665 (flush _test-output-buffered-file) +13666 (flush _test-error-buffered-file) +13667 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13673 # check output +13674 (check-stream-equal _test-output-stream "" "F - test-length-with-addr-base-on-stack: output should be empty") +13675 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is an addr to an array, and so must live in a register" "F - test-length-with-addr-base-on-stack: error message") +13676 # check that stop(1) was called +13677 (check-ints-equal *(edx+4) 2 "F - test-length-with-addr-base-on-stack: exit status") +13678 # don't restore from ebp +13679 81 0/subop/add %esp 8/imm32 +13680 # . epilogue +13681 5d/pop-to-ebp +13682 c3/return +13683 +13684 test-length-with-wrong-output-type: +13685 # . prologue +13686 55/push-ebp +13687 89/<- %ebp 4/r32/esp +13688 # setup +13689 (clear-stream _test-input-stream) +13690 (clear-stream $_test-input-buffered-file->buffer) +13691 (clear-stream _test-output-stream) +13692 (clear-stream $_test-output-buffered-file->buffer) +13693 (clear-stream _test-error-stream) +13694 (clear-stream $_test-error-buffered-file->buffer) +13695 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13696 68/push 0/imm32 +13697 68/push 0/imm32 +13698 89/<- %edx 4/r32/esp +13699 (tailor-exit-descriptor %edx 0x10) +13700 # +13701 (write _test-input-stream "fn foo {\n") +13702 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n") +13703 (write _test-input-stream " var o/edi: (addr int) <- length a\n") +13704 (write _test-input-stream "}\n") +13705 # convert +13706 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13707 # registers except esp clobbered at this point +13708 # restore ed +13709 89/<- %edx 4/r32/esp +13710 (flush _test-output-buffered-file) +13711 (flush _test-error-buffered-file) +13712 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13718 # check output +13719 (check-stream-equal _test-output-stream "" "F - test-length-with-wrong-output-type: output should be empty") +13720 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: output 'o' does not have the right type" "F - test-length-with-wrong-output-type: error message") +13721 # check that stop(1) was called +13722 (check-ints-equal *(edx+4) 2 "F - test-length-with-wrong-output-type: exit status") +13723 # don't restore from ebp +13724 81 0/subop/add %esp 8/imm32 +13725 # . epilogue +13726 5d/pop-to-ebp +13727 c3/return +13728 +13729 test-length-with-wrong-output-compound-type: +13730 # . prologue +13731 55/push-ebp +13732 89/<- %ebp 4/r32/esp +13733 # setup +13734 (clear-stream _test-input-stream) +13735 (clear-stream $_test-input-buffered-file->buffer) +13736 (clear-stream _test-output-stream) +13737 (clear-stream $_test-output-buffered-file->buffer) +13738 (clear-stream _test-error-stream) +13739 (clear-stream $_test-error-buffered-file->buffer) +13740 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13741 68/push 0/imm32 +13742 68/push 0/imm32 +13743 89/<- %edx 4/r32/esp +13744 (tailor-exit-descriptor %edx 0x10) +13745 # +13746 (write _test-input-stream "fn foo {\n") +13747 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n") +13748 (write _test-input-stream " var o/edi: (addr handle int) <- length a\n") +13749 (write _test-input-stream "}\n") +13750 # convert +13751 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13752 # registers except esp clobbered at this point +13753 # restore ed +13754 89/<- %edx 4/r32/esp +13755 (flush _test-output-buffered-file) +13756 (flush _test-error-buffered-file) +13757 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13763 # check output +13764 (check-stream-equal _test-output-stream "" "F - test-length-with-wrong-output-compound-type: output should be empty") +13765 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: output 'o' does not have the right type" "F - test-length-with-wrong-output-compound-type: error message") +13766 # check that stop(1) was called +13767 (check-ints-equal *(edx+4) 2 "F - test-length-with-wrong-output-compound-type: exit status") +13768 # don't restore from ebp +13769 81 0/subop/add %esp 8/imm32 +13770 # . epilogue +13771 5d/pop-to-ebp +13772 c3/return +13773 +13774 test-length-with-no-inouts: +13775 # . prologue +13776 55/push-ebp +13777 89/<- %ebp 4/r32/esp +13778 # setup +13779 (clear-stream _test-input-stream) +13780 (clear-stream $_test-input-buffered-file->buffer) +13781 (clear-stream _test-output-stream) +13782 (clear-stream $_test-output-buffered-file->buffer) +13783 (clear-stream _test-error-stream) +13784 (clear-stream $_test-error-buffered-file->buffer) +13785 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13786 68/push 0/imm32 +13787 68/push 0/imm32 +13788 89/<- %edx 4/r32/esp +13789 (tailor-exit-descriptor %edx 0x10) +13790 # +13791 (write _test-input-stream "fn foo {\n") +13792 (write _test-input-stream " var c/ecx: int <- length\n") +13793 (write _test-input-stream "}\n") +13794 # convert +13795 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13796 # registers except esp clobbered at this point +13797 # restore ed +13798 89/<- %edx 4/r32/esp +13799 (flush _test-output-buffered-file) +13800 (flush _test-error-buffered-file) +13801 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13807 # check output +13808 (check-stream-equal _test-output-stream "" "F - test-length-with-no-inouts: output should be empty") +13809 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too few inouts (1 required)" "F - test-length-with-no-inouts: error message") +13810 # check that stop(1) was called +13811 (check-ints-equal *(edx+4) 2 "F - test-length-with-no-inouts: exit status") +13812 # don't restore from ebp +13813 81 0/subop/add %esp 8/imm32 +13814 # . epilogue +13815 5d/pop-to-ebp +13816 c3/return +13817 +13818 test-length-with-too-many-inouts: +13819 # . prologue +13820 55/push-ebp +13821 89/<- %ebp 4/r32/esp +13822 # setup +13823 (clear-stream _test-input-stream) +13824 (clear-stream $_test-input-buffered-file->buffer) +13825 (clear-stream _test-output-stream) +13826 (clear-stream $_test-output-buffered-file->buffer) +13827 (clear-stream _test-error-stream) +13828 (clear-stream $_test-error-buffered-file->buffer) +13829 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13830 68/push 0/imm32 +13831 68/push 0/imm32 +13832 89/<- %edx 4/r32/esp +13833 (tailor-exit-descriptor %edx 0x10) +13834 # +13835 (write _test-input-stream "fn foo {\n") +13836 (write _test-input-stream " var a: (array int 3)\n") +13837 (write _test-input-stream " var c/ecx: int <- length a, 0, 0\n") +13838 (write _test-input-stream "}\n") +13839 # convert +13840 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13841 # registers except esp clobbered at this point +13842 # restore ed +13843 89/<- %edx 4/r32/esp +13844 (flush _test-output-buffered-file) +13845 (flush _test-error-buffered-file) +13846 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13852 # check output +13853 (check-stream-equal _test-output-stream "" "F - test-length-with-too-many-inouts: output should be empty") +13854 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too many inouts (1 required)" "F - test-length-with-too-many-inouts: error message") +13855 # check that stop(1) was called +13856 (check-ints-equal *(edx+4) 2 "F - test-length-with-too-many-inouts: exit status") +13857 # don't restore from ebp +13858 81 0/subop/add %esp 8/imm32 +13859 # . epilogue +13860 5d/pop-to-ebp +13861 c3/return +13862 +13863 test-length-with-no-output: +13864 # . prologue +13865 55/push-ebp +13866 89/<- %ebp 4/r32/esp +13867 # setup +13868 (clear-stream _test-input-stream) +13869 (clear-stream $_test-input-buffered-file->buffer) +13870 (clear-stream _test-output-stream) +13871 (clear-stream $_test-output-buffered-file->buffer) +13872 (clear-stream _test-error-stream) +13873 (clear-stream $_test-error-buffered-file->buffer) +13874 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13875 68/push 0/imm32 +13876 68/push 0/imm32 +13877 89/<- %edx 4/r32/esp +13878 (tailor-exit-descriptor %edx 0x10) +13879 # +13880 (write _test-input-stream "fn foo {\n") +13881 (write _test-input-stream " var a: (array int 3)\n") +13882 (write _test-input-stream " length a\n") +13883 (write _test-input-stream "}\n") +13884 # convert +13885 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13886 # registers except esp clobbered at this point +13887 # restore ed +13888 89/<- %edx 4/r32/esp +13889 (flush _test-output-buffered-file) +13890 (flush _test-error-buffered-file) +13891 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13897 # check output +13898 (check-stream-equal _test-output-stream "" "F - test-length-with-no-output: output should be empty") +13899 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: must have an output" "F - test-length-with-no-output: error message") +13900 # check that stop(1) was called +13901 (check-ints-equal *(edx+4) 2 "F - test-length-with-no-output: exit status") +13902 # don't restore from ebp +13903 81 0/subop/add %esp 8/imm32 +13904 # . epilogue +13905 5d/pop-to-ebp +13906 c3/return +13907 +13908 test-length-with-too-many-outputs: +13909 # . prologue +13910 55/push-ebp +13911 89/<- %ebp 4/r32/esp +13912 # setup +13913 (clear-stream _test-input-stream) +13914 (clear-stream $_test-input-buffered-file->buffer) +13915 (clear-stream _test-output-stream) +13916 (clear-stream $_test-output-buffered-file->buffer) +13917 (clear-stream _test-error-stream) +13918 (clear-stream $_test-error-buffered-file->buffer) +13919 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +13920 68/push 0/imm32 +13921 68/push 0/imm32 +13922 89/<- %edx 4/r32/esp +13923 (tailor-exit-descriptor %edx 0x10) +13924 # +13925 (write _test-input-stream "fn foo {\n") +13926 (write _test-input-stream " var a: (array int 3)\n") +13927 (write _test-input-stream " var b/eax: int <- copy 0\n") +13928 (write _test-input-stream " var c/ecx: int <- copy 0\n") +13929 (write _test-input-stream " b, c <- length a\n") +13930 (write _test-input-stream "}\n") +13931 # convert +13932 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +13933 # registers except esp clobbered at this point +13934 # restore ed +13935 89/<- %edx 4/r32/esp +13936 (flush _test-output-buffered-file) +13937 (flush _test-error-buffered-file) +13938 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +13944 # check output +13945 (check-stream-equal _test-output-stream "" "F - test-length-with-too-many-outputs: output should be empty") +13946 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too many outputs (1 required)" "F - test-length-with-too-many-outputs: error message") +13947 # check that stop(1) was called +13948 (check-ints-equal *(edx+4) 2 "F - test-length-with-too-many-outputs: exit status") +13949 # don't restore from ebp +13950 81 0/subop/add %esp 8/imm32 +13951 # . epilogue +13952 5d/pop-to-ebp +13953 c3/return +13954 +13955 test-convert-function-with-return-register-and-local: +13956 # . prologue +13957 55/push-ebp +13958 89/<- %ebp 4/r32/esp +13959 # setup +13960 (clear-stream _test-input-stream) +13961 (clear-stream $_test-input-buffered-file->buffer) +13962 (clear-stream _test-output-stream) +13963 (clear-stream $_test-output-buffered-file->buffer) +13964 # +13965 (write _test-input-stream "fn foo -> _/eax: int {\n") +13966 (write _test-input-stream " var y/eax: int <- copy 3\n") +13967 (write _test-input-stream " var z/ecx: int <- copy 4\n") +13968 (write _test-input-stream " return y\n") +13969 (write _test-input-stream "}\n") +13970 # convert +13971 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +13972 (flush _test-output-buffered-file) +13973 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +13979 # check output +13980 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register-and-local/0") +13981 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-register-and-local/1") +13982 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register-and-local/2") +13983 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register-and-local/3") +13984 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register-and-local/4") +13985 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register-and-local/5") +13986 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register-and-local/6") +13987 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register-and-local/7") +13988 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-return-register-and-local/8") +13989 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-return-register-and-local/9") +13990 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-return-register-and-local/10") +13991 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-return-register-and-local/11") +13992 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register-and-local/12") +13993 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register-and-local/13") +13994 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register-and-local/14") +13995 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register-and-local/15") +13996 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-register-and-local/16") +13997 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register-and-local/17") +13998 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register-and-local/18") +13999 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register-and-local/19") +14000 # . epilogue +14001 89/<- %esp 5/r32/ebp +14002 5d/pop-to-ebp +14003 c3/return +14004 +14005 test-convert-function-with-return-register-and-local-2: +14006 # . prologue +14007 55/push-ebp +14008 89/<- %ebp 4/r32/esp +14009 # setup +14010 (clear-stream _test-input-stream) +14011 (clear-stream $_test-input-buffered-file->buffer) +14012 (clear-stream _test-output-stream) +14013 (clear-stream $_test-output-buffered-file->buffer) +14014 # +14015 (write _test-input-stream "fn foo -> _/eax: int {\n") +14016 (write _test-input-stream " var y/eax: int <- copy 3\n") +14017 (write _test-input-stream " var z/ecx: int <- copy 4\n") +14018 (write _test-input-stream " return z\n") +14019 (write _test-input-stream "}\n") +14020 # convert +14021 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +14022 (flush _test-output-buffered-file) +14023 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +14029 # check output +14030 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register-and-local-2/0") +14031 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-register-and-local-2/1") +14032 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register-and-local-2/2") +14033 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register-and-local-2/3") +14034 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register-and-local-2/4") +14035 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register-and-local-2/5") +14036 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register-and-local-2/6") +14037 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register-and-local-2/7") +14038 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-return-register-and-local-2/8") +14039 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-return-register-and-local-2/9") +14040 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000000/r32" "F - test-convert-function-with-return-register-and-local-2/10") +14041 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-return-register-and-local-2/11") +14042 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register-and-local-2/12") +14043 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register-and-local-2/13") +14044 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register-and-local-2/14") +14045 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register-and-local-2/15") +14046 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-register-and-local-2/16") +14047 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register-and-local-2/17") +14048 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register-and-local-2/18") +14049 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register-and-local-2/19") +14050 # . epilogue +14051 89/<- %esp 5/r32/ebp +14052 5d/pop-to-ebp +14053 c3/return +14054 +14055 test-convert-function-with-return-float-register-and-local: +14056 # . prologue +14057 55/push-ebp +14058 89/<- %ebp 4/r32/esp +14059 # setup +14060 (clear-stream _test-input-stream) +14061 (clear-stream $_test-input-buffered-file->buffer) +14062 (clear-stream _test-output-stream) +14063 (clear-stream $_test-output-buffered-file->buffer) +14064 # +14065 (write _test-input-stream "fn foo -> _/xmm1: float {\n") +14066 (write _test-input-stream " var y/eax: int <- copy 3\n") +14067 (write _test-input-stream " var g/xmm0: float <- convert y\n") +14068 (write _test-input-stream " var h/xmm1: float <- convert y\n") +14069 (write _test-input-stream " return g\n") +14070 (write _test-input-stream "}\n") +14071 # convert +14072 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +14073 (flush _test-output-buffered-file) +14074 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +14080 # check output +14081 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-float-register-and-local/0") +14082 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-float-register-and-local/1") +14083 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-float-register-and-local/2") +14084 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-float-register-and-local/3") +14085 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-float-register-and-local/4") +14086 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-float-register-and-local/5") +14087 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-float-register-and-local/6") # var y +14088 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-float-register-and-local/7") +14089 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-function-with-return-float-register-and-local/8") # var g +14090 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 0/x32" "F - test-convert-function-with-return-float-register-and-local/9") +14091 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000000/x32" "F - test-convert-function-with-return-float-register-and-local/10") +14092 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-function-with-return-float-register-and-local/11") # var h +14093 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-function-with-return-float-register-and-local/12") +14094 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-function-with-return-float-register-and-local/13") +14095 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> %xmm0 0x00000001/x32" "F - test-convert-function-with-return-float-register-and-local/14") # return g +14096 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/15") # reclaim h +14097 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 0/x32" "F - test-convert-floating-point-dereferenced/16") # reclaim g +14098 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/17") +14099 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-return-float-register-and-local/18") # reclaim y +14100 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-float-register-and-local/19") +14101 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-float-register-and-local/20") +14102 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-float-register-and-local/21") +14103 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-float-register-and-local/22") +14104 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-float-register-and-local/23") +14105 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-float-register-and-local/24") +14106 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-float-register-and-local/25") +14107 # . epilogue +14108 89/<- %esp 5/r32/ebp +14109 5d/pop-to-ebp +14110 c3/return +14111 +14112 test-convert-function-with-return-and-local-vars: +14113 # . prologue +14114 55/push-ebp +14115 89/<- %ebp 4/r32/esp +14116 # setup +14117 (clear-stream _test-input-stream) +14118 (clear-stream $_test-input-buffered-file->buffer) +14119 (clear-stream _test-output-stream) +14120 (clear-stream $_test-output-buffered-file->buffer) +14121 # +14122 (write _test-input-stream "fn foo -> _/eax: int {\n") +14123 (write _test-input-stream " {\n") +14124 (write _test-input-stream " var x: int\n") +14125 (write _test-input-stream " {\n") +14126 (write _test-input-stream " var y: int\n") +14127 (write _test-input-stream " return y\n") +14128 (write _test-input-stream " increment x\n") +14129 (write _test-input-stream " }\n") +14130 (write _test-input-stream " }\n") +14131 (write _test-input-stream " return 0\n") +14132 (write _test-input-stream "}\n") +14133 # convert +14134 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +14135 (flush _test-output-buffered-file) +14136 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +14142 # check output +14143 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-and-local-vars/0") +14144 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-and-local-vars/1") +14145 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-and-local-vars/2") +14146 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-and-local-vars/3") +14147 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/4") +14148 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-and-local-vars/5") +14149 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/6") +14150 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-return-and-local-vars/7") +14151 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return-and-local-vars/8") # var x +14152 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/9") +14153 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-return-and-local-vars/10") +14154 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return-and-local-vars/11") # var y +14155 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-with-return-and-local-vars/12") +14156 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/13") +14157 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/14") +14158 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-and-local-vars/15") +14159 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/16") +14160 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-return-and-local-vars/17") +14161 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/18") +14162 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/19") +14163 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-return-and-local-vars/20") +14164 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy %eax 0/imm32" "F - test-convert-function-with-return-and-local-vars/21") +14165 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-and-local-vars/21") +14166 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/21") +14167 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-and-local-vars/22") +14168 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-and-local-vars/23") +14169 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-and-local-vars/24") +14170 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-and-local-vars/25") +14171 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-and-local-vars/26") +14172 # . epilogue +14173 89/<- %esp 5/r32/ebp +14174 5d/pop-to-ebp +14175 c3/return +14176 +14177 test-copy-object-with-no-inout: +14178 # . prologue +14179 55/push-ebp +14180 89/<- %ebp 4/r32/esp +14181 # setup +14182 (clear-stream _test-input-stream) +14183 (clear-stream $_test-input-buffered-file->buffer) +14184 (clear-stream _test-output-stream) +14185 (clear-stream $_test-output-buffered-file->buffer) +14186 (clear-stream _test-error-stream) +14187 (clear-stream $_test-error-buffered-file->buffer) +14188 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14189 68/push 0/imm32 +14190 68/push 0/imm32 +14191 89/<- %edx 4/r32/esp +14192 (tailor-exit-descriptor %edx 0x10) +14193 # +14194 (write _test-input-stream "fn foo {\n") +14195 (write _test-input-stream " copy-object\n") +14196 (write _test-input-stream "}\n") +14197 # convert +14198 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14199 # registers except esp clobbered at this point +14200 # restore ed +14201 89/<- %edx 4/r32/esp +14202 (flush _test-output-buffered-file) +14203 (flush _test-error-buffered-file) +14204 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14210 # check output +14211 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-no-inout: output should be empty") +14212 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-no-inout: error message") +14213 # check that stop(1) was called +14214 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-no-inout: exit status") +14215 # don't restore from ebp +14216 81 0/subop/add %esp 8/imm32 +14217 # . epilogue +14218 5d/pop-to-ebp +14219 c3/return +14220 +14221 test-copy-object-with-no-source: +14222 # . prologue +14223 55/push-ebp +14224 89/<- %ebp 4/r32/esp +14225 # setup +14226 (clear-stream _test-input-stream) +14227 (clear-stream $_test-input-buffered-file->buffer) +14228 (clear-stream _test-output-stream) +14229 (clear-stream $_test-output-buffered-file->buffer) +14230 (clear-stream _test-error-stream) +14231 (clear-stream $_test-error-buffered-file->buffer) +14232 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14233 68/push 0/imm32 +14234 68/push 0/imm32 +14235 89/<- %edx 4/r32/esp +14236 (tailor-exit-descriptor %edx 0x10) +14237 # +14238 (write _test-input-stream "fn foo {\n") +14239 (write _test-input-stream " var x: (addr int)\n") +14240 (write _test-input-stream " copy-object x\n") +14241 (write _test-input-stream "}\n") +14242 # convert +14243 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14244 # registers except esp clobbered at this point +14245 # restore ed +14246 89/<- %edx 4/r32/esp +14247 (flush _test-output-buffered-file) +14248 (flush _test-error-buffered-file) +14249 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14255 # check output +14256 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-no-source: output should be empty") +14257 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-no-source: error message") +14258 # check that stop(1) was called +14259 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-no-source: exit status") +14260 # don't restore from ebp +14261 81 0/subop/add %esp 8/imm32 +14262 # . epilogue +14263 5d/pop-to-ebp +14264 c3/return +14265 +14266 test-copy-object-with-too-many-inouts: +14267 # . prologue +14268 55/push-ebp +14269 89/<- %ebp 4/r32/esp +14270 # setup +14271 (clear-stream _test-input-stream) +14272 (clear-stream $_test-input-buffered-file->buffer) +14273 (clear-stream _test-output-stream) +14274 (clear-stream $_test-output-buffered-file->buffer) +14275 (clear-stream _test-error-stream) +14276 (clear-stream $_test-error-buffered-file->buffer) +14277 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14278 68/push 0/imm32 +14279 68/push 0/imm32 +14280 89/<- %edx 4/r32/esp +14281 (tailor-exit-descriptor %edx 0x10) +14282 # +14283 (write _test-input-stream "fn foo {\n") +14284 (write _test-input-stream " var x: (addr boolean)\n") +14285 (write _test-input-stream " copy-object x, x, x\n") +14286 (write _test-input-stream "}\n") +14287 # convert +14288 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14289 # registers except esp clobbered at this point +14290 # restore ed +14291 89/<- %edx 4/r32/esp +14292 (flush _test-output-buffered-file) +14293 (flush _test-error-buffered-file) +14294 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14300 # check output +14301 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-too-many-inouts: output should be empty") +14302 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-too-many-inouts: error message") +14303 # check that stop(1) was called +14304 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-too-many-inouts: exit status") +14305 # don't restore from ebp +14306 81 0/subop/add %esp 8/imm32 +14307 # . epilogue +14308 5d/pop-to-ebp +14309 c3/return +14310 +14311 test-copy-object-with-output: +14312 # . prologue +14313 55/push-ebp +14314 89/<- %ebp 4/r32/esp +14315 # setup +14316 (clear-stream _test-input-stream) +14317 (clear-stream $_test-input-buffered-file->buffer) +14318 (clear-stream _test-output-stream) +14319 (clear-stream $_test-output-buffered-file->buffer) +14320 (clear-stream _test-error-stream) +14321 (clear-stream $_test-error-buffered-file->buffer) +14322 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14323 68/push 0/imm32 +14324 68/push 0/imm32 +14325 89/<- %edx 4/r32/esp +14326 (tailor-exit-descriptor %edx 0x10) +14327 # +14328 (write _test-input-stream "fn foo {\n") +14329 (write _test-input-stream " var x/eax: (addr boolean) <- copy 0\n") +14330 (write _test-input-stream " var y/ecx: (addr boolean) <- copy 0\n") +14331 (write _test-input-stream " x <- copy-object x, y\n") +14332 (write _test-input-stream "}\n") +14333 # convert +14334 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14335 # registers except esp clobbered at this point +14336 # restore ed +14337 89/<- %edx 4/r32/esp +14338 (flush _test-output-buffered-file) +14339 (flush _test-error-buffered-file) +14340 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14346 # check output +14347 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-output: output should be empty") +14348 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must not have any outputs" "F - test-copy-object-with-output: error message") +14349 # check that stop(1) was called +14350 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-output: exit status") +14351 # don't restore from ebp +14352 81 0/subop/add %esp 8/imm32 14353 # . epilogue 14354 5d/pop-to-ebp 14355 c3/return 14356 -14357 test-copy-object-non-addr: +14357 test-copy-object-deref-address: 14358 # . prologue 14359 55/push-ebp 14360 89/<- %ebp 4/r32/esp @@ -13015,18091 +13015,18091 @@ if ('onhashchange' in window) { 14363 (clear-stream $_test-input-buffered-file->buffer) 14364 (clear-stream _test-output-stream) 14365 (clear-stream $_test-output-buffered-file->buffer) -14366 (clear-stream _test-error-stream) -14367 (clear-stream $_test-error-buffered-file->buffer) -14368 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14369 68/push 0/imm32 -14370 68/push 0/imm32 -14371 89/<- %edx 4/r32/esp -14372 (tailor-exit-descriptor %edx 0x10) -14373 # -14374 (write _test-input-stream "fn foo {\n") -14375 (write _test-input-stream " var x: int\n") -14376 (write _test-input-stream " var y: int\n") -14377 (write _test-input-stream " copy-object y, x\n") -14378 (write _test-input-stream "}\n") -14379 # convert -14380 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14381 # registers except esp clobbered at this point -14382 # restore ed -14383 89/<- %edx 4/r32/esp -14384 (flush _test-output-buffered-file) -14385 (flush _test-error-buffered-file) -14386 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14392 # check output -14393 (check-stream-equal _test-output-stream "" "F - test-copy-object-non-addr: output should be empty") -14394 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-object: two inouts with identical addr types expected" "F - test-copy-object-non-addr: error message") -14395 # check that stop(1) was called -14396 (check-ints-equal *(edx+4) 2 "F - test-copy-object-non-addr: exit status") -14397 # don't restore from ebp -14398 81 0/subop/add %esp 8/imm32 -14399 # . epilogue -14400 5d/pop-to-ebp -14401 c3/return -14402 -14403 test-copy-object-non-equal: -14404 # . prologue -14405 55/push-ebp -14406 89/<- %ebp 4/r32/esp -14407 # setup -14408 (clear-stream _test-input-stream) -14409 (clear-stream $_test-input-buffered-file->buffer) -14410 (clear-stream _test-output-stream) -14411 (clear-stream $_test-output-buffered-file->buffer) -14412 (clear-stream _test-error-stream) -14413 (clear-stream $_test-error-buffered-file->buffer) -14414 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14415 68/push 0/imm32 -14416 68/push 0/imm32 -14417 89/<- %edx 4/r32/esp -14418 (tailor-exit-descriptor %edx 0x10) -14419 # -14420 (write _test-input-stream "fn foo {\n") -14421 (write _test-input-stream " var x: (addr int)\n") -14422 (write _test-input-stream " var y: (addr boolean)\n") -14423 (write _test-input-stream " copy-object y, x\n") -14424 (write _test-input-stream "}\n") -14425 # convert -14426 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14427 # registers except esp clobbered at this point -14428 # restore ed -14429 89/<- %edx 4/r32/esp -14430 (flush _test-output-buffered-file) -14431 (flush _test-error-buffered-file) -14432 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14438 # check output -14439 (check-stream-equal _test-output-stream "" "F - test-copy-object-non-equal: output should be empty") -14440 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-object: two inouts with identical addr types expected" "F - test-copy-object-non-equal: error message") -14441 # check that stop(1) was called -14442 (check-ints-equal *(edx+4) 2 "F - test-copy-object-non-equal: exit status") -14443 # don't restore from ebp -14444 81 0/subop/add %esp 8/imm32 -14445 # . epilogue -14446 5d/pop-to-ebp -14447 c3/return -14448 -14449 test-allocate-with-no-inout: -14450 # . prologue -14451 55/push-ebp -14452 89/<- %ebp 4/r32/esp -14453 # setup -14454 (clear-stream _test-input-stream) -14455 (clear-stream $_test-input-buffered-file->buffer) -14456 (clear-stream _test-output-stream) -14457 (clear-stream $_test-output-buffered-file->buffer) -14458 (clear-stream _test-error-stream) -14459 (clear-stream $_test-error-buffered-file->buffer) -14460 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14461 68/push 0/imm32 -14462 68/push 0/imm32 -14463 89/<- %edx 4/r32/esp -14464 (tailor-exit-descriptor %edx 0x10) -14465 # -14466 (write _test-input-stream "fn foo {\n") -14467 (write _test-input-stream " allocate\n") -14468 (write _test-input-stream "}\n") -14469 # convert -14470 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14471 # registers except esp clobbered at this point -14472 # restore ed -14473 89/<- %edx 4/r32/esp -14474 (flush _test-output-buffered-file) -14475 (flush _test-error-buffered-file) -14476 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14482 # check output -14483 (check-stream-equal _test-output-stream "" "F - test-allocate-with-no-inout: output should be empty") -14484 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must have a single inout" "F - test-allocate-with-no-inout: error message") -14485 # check that stop(1) was called -14486 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-no-inout: exit status") -14487 # don't restore from ebp -14488 81 0/subop/add %esp 8/imm32 -14489 # . epilogue -14490 5d/pop-to-ebp -14491 c3/return -14492 -14493 test-allocate-with-too-many-inouts: -14494 # . prologue -14495 55/push-ebp -14496 89/<- %ebp 4/r32/esp -14497 # setup -14498 (clear-stream _test-input-stream) -14499 (clear-stream $_test-input-buffered-file->buffer) -14500 (clear-stream _test-output-stream) -14501 (clear-stream $_test-output-buffered-file->buffer) -14502 (clear-stream _test-error-stream) -14503 (clear-stream $_test-error-buffered-file->buffer) -14504 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14505 68/push 0/imm32 -14506 68/push 0/imm32 -14507 89/<- %edx 4/r32/esp -14508 (tailor-exit-descriptor %edx 0x10) -14509 # -14510 (write _test-input-stream "fn foo {\n") -14511 (write _test-input-stream " var x: (addr handle int)\n") -14512 (write _test-input-stream " allocate x, 0\n") -14513 (write _test-input-stream "}\n") -14514 # convert -14515 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14516 # registers except esp clobbered at this point -14517 # restore ed -14518 89/<- %edx 4/r32/esp -14519 (flush _test-output-buffered-file) -14520 (flush _test-error-buffered-file) -14521 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14527 # check output -14528 (check-stream-equal _test-output-stream "" "F - test-allocate-with-too-many-inouts: output should be empty") -14529 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must have a single inout" "F - test-allocate-with-too-many-inouts: error message") -14530 # check that stop(1) was called -14531 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-too-many-inouts: exit status") -14532 # don't restore from ebp -14533 81 0/subop/add %esp 8/imm32 -14534 # . epilogue -14535 5d/pop-to-ebp -14536 c3/return -14537 -14538 test-allocate-with-output: -14539 # . prologue -14540 55/push-ebp -14541 89/<- %ebp 4/r32/esp -14542 # setup -14543 (clear-stream _test-input-stream) -14544 (clear-stream $_test-input-buffered-file->buffer) -14545 (clear-stream _test-output-stream) -14546 (clear-stream $_test-output-buffered-file->buffer) -14547 (clear-stream _test-error-stream) -14548 (clear-stream $_test-error-buffered-file->buffer) -14549 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14550 68/push 0/imm32 -14551 68/push 0/imm32 -14552 89/<- %edx 4/r32/esp -14553 (tailor-exit-descriptor %edx 0x10) -14554 # -14555 (write _test-input-stream "fn foo {\n") -14556 (write _test-input-stream " var x/eax: boolean <- copy 0\n") -14557 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") -14558 (write _test-input-stream " x <- allocate y\n") -14559 (write _test-input-stream "}\n") -14560 # convert -14561 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14562 # registers except esp clobbered at this point -14563 # restore ed -14564 89/<- %edx 4/r32/esp -14565 (flush _test-output-buffered-file) -14566 (flush _test-error-buffered-file) -14567 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14573 # check output -14574 (check-stream-equal _test-output-stream "" "F - test-allocate-with-output: output should be empty") -14575 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must not have any outputs" "F - test-allocate-with-output: error message") -14576 # check that stop(1) was called -14577 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-output: exit status") -14578 # don't restore from ebp -14579 81 0/subop/add %esp 8/imm32 -14580 # . epilogue -14581 5d/pop-to-ebp -14582 c3/return -14583 -14584 test-allocate-non-addr: -14585 # . prologue -14586 55/push-ebp -14587 89/<- %ebp 4/r32/esp -14588 # setup -14589 (clear-stream _test-input-stream) -14590 (clear-stream $_test-input-buffered-file->buffer) -14591 (clear-stream _test-output-stream) -14592 (clear-stream $_test-output-buffered-file->buffer) -14593 (clear-stream _test-error-stream) -14594 (clear-stream $_test-error-buffered-file->buffer) -14595 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14596 68/push 0/imm32 -14597 68/push 0/imm32 -14598 89/<- %edx 4/r32/esp -14599 (tailor-exit-descriptor %edx 0x10) -14600 # -14601 (write _test-input-stream "fn foo {\n") -14602 (write _test-input-stream " var y: (handle int)\n") -14603 (write _test-input-stream " allocate y\n") -14604 (write _test-input-stream "}\n") -14605 # convert -14606 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14607 # registers except esp clobbered at this point -14608 # restore ed -14609 89/<- %edx 4/r32/esp -14610 (flush _test-output-buffered-file) -14611 (flush _test-error-buffered-file) -14612 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14618 # check output -14619 (check-stream-equal _test-output-stream "" "F - test-allocate-non-addr: output must be empty") -14620 (check-next-stream-line-equal _test-error-stream "fn foo: stmt allocate: inout 'y' must have type (addr handle ...)" "F - test-allocate-non-addr: error message") -14621 # check that stop(1) was called -14622 (check-ints-equal *(edx+4) 2 "F - test-allocate-non-addr: exit status") -14623 # don't restore from ebp -14624 81 0/subop/add %esp 8/imm32 -14625 # . epilogue -14626 5d/pop-to-ebp -14627 c3/return -14628 -14629 test-allocate-non-addr-handle: -14630 # . prologue -14631 55/push-ebp -14632 89/<- %ebp 4/r32/esp -14633 # setup -14634 (clear-stream _test-input-stream) -14635 (clear-stream $_test-input-buffered-file->buffer) -14636 (clear-stream _test-output-stream) -14637 (clear-stream $_test-output-buffered-file->buffer) -14638 (clear-stream _test-error-stream) -14639 (clear-stream $_test-error-buffered-file->buffer) -14640 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14641 68/push 0/imm32 -14642 68/push 0/imm32 -14643 89/<- %edx 4/r32/esp -14644 (tailor-exit-descriptor %edx 0x10) -14645 # -14646 (write _test-input-stream "fn foo {\n") -14647 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") -14648 (write _test-input-stream " allocate y\n") -14649 (write _test-input-stream "}\n") -14650 # convert -14651 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14652 # registers except esp clobbered at this point -14653 # restore ed -14654 89/<- %edx 4/r32/esp -14655 (flush _test-output-buffered-file) -14656 (flush _test-error-buffered-file) -14657 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14663 # check output -14664 (check-stream-equal _test-output-stream "" "F - test-allocate-non-addr-handle: output should be empty") -14665 (check-next-stream-line-equal _test-error-stream "fn foo: stmt allocate: inout 'y' must have type (addr handle ...)" "F - test-allocate-non-addr-handle: error message") -14666 # check that stop(1) was called -14667 (check-ints-equal *(edx+4) 2 "F - test-allocate-non-addr-handle: exit status") -14668 # don't restore from ebp -14669 81 0/subop/add %esp 8/imm32 -14670 # . epilogue -14671 5d/pop-to-ebp -14672 c3/return -14673 -14674 test-allocate-deref-address: -14675 # . prologue -14676 55/push-ebp -14677 89/<- %ebp 4/r32/esp -14678 # setup -14679 (clear-stream _test-input-stream) -14680 (clear-stream $_test-input-buffered-file->buffer) -14681 (clear-stream _test-output-stream) -14682 (clear-stream $_test-output-buffered-file->buffer) -14683 # -14684 (write _test-input-stream "fn foo {\n") -14685 (write _test-input-stream " var y/ecx: (addr addr handle int) <- copy 0\n") -14686 (write _test-input-stream " allocate *y\n") -14687 (write _test-input-stream "}\n") -14688 # convert -14689 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -14690 (flush _test-output-buffered-file) -14691 # no errors -14692 # . epilogue -14693 5d/pop-to-ebp -14694 c3/return -14695 -14696 test-populate-with-no-inout: -14697 # . prologue -14698 55/push-ebp -14699 89/<- %ebp 4/r32/esp -14700 # setup -14701 (clear-stream _test-input-stream) -14702 (clear-stream $_test-input-buffered-file->buffer) -14703 (clear-stream _test-output-stream) -14704 (clear-stream $_test-output-buffered-file->buffer) -14705 (clear-stream _test-error-stream) -14706 (clear-stream $_test-error-buffered-file->buffer) -14707 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14708 68/push 0/imm32 -14709 68/push 0/imm32 -14710 89/<- %edx 4/r32/esp -14711 (tailor-exit-descriptor %edx 0x10) -14712 # -14713 (write _test-input-stream "fn foo {\n") -14714 (write _test-input-stream " populate\n") -14715 (write _test-input-stream "}\n") -14716 # convert -14717 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14718 # registers except esp clobbered at this point -14719 # restore ed -14720 89/<- %edx 4/r32/esp -14721 (flush _test-output-buffered-file) -14722 (flush _test-error-buffered-file) -14723 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14729 # check output -14730 (check-stream-equal _test-output-stream "" "F - test-populate-with-no-inout: output should be empty") -14731 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must have two inouts" "F - test-populate-with-no-inout: error message") -14732 # check that stop(1) was called -14733 (check-ints-equal *(edx+4) 2 "F - test-populate-with-no-inout: exit status") -14734 # don't restore from ebp -14735 81 0/subop/add %esp 8/imm32 -14736 # . epilogue -14737 5d/pop-to-ebp -14738 c3/return -14739 -14740 test-populate-with-too-many-inouts: -14741 # . prologue -14742 55/push-ebp -14743 89/<- %ebp 4/r32/esp -14744 # setup -14745 (clear-stream _test-input-stream) -14746 (clear-stream $_test-input-buffered-file->buffer) -14747 (clear-stream _test-output-stream) -14748 (clear-stream $_test-output-buffered-file->buffer) -14749 (clear-stream _test-error-stream) -14750 (clear-stream $_test-error-buffered-file->buffer) -14751 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14752 68/push 0/imm32 -14753 68/push 0/imm32 -14754 89/<- %edx 4/r32/esp -14755 (tailor-exit-descriptor %edx 0x10) -14756 # -14757 (write _test-input-stream "fn foo {\n") -14758 (write _test-input-stream " var x: (addr handle int)\n") -14759 (write _test-input-stream " populate x, 3, 0\n") -14760 (write _test-input-stream "}\n") -14761 # convert -14762 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14763 # registers except esp clobbered at this point -14764 # restore ed -14765 89/<- %edx 4/r32/esp -14766 (flush _test-output-buffered-file) -14767 (flush _test-error-buffered-file) -14768 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14774 # check output -14775 (check-stream-equal _test-output-stream "" "F - test-populate-with-too-many-inouts: output should be empty") -14776 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must have two inouts" "F - test-populate-with-too-many-inouts: error message") -14777 # check that stop(1) was called -14778 (check-ints-equal *(edx+4) 2 "F - test-populate-with-too-many-inouts: exit status") -14779 # don't restore from ebp -14780 81 0/subop/add %esp 8/imm32 -14781 # . epilogue -14782 5d/pop-to-ebp -14783 c3/return -14784 -14785 test-populate-with-output: -14786 # . prologue -14787 55/push-ebp -14788 89/<- %ebp 4/r32/esp -14789 # setup -14790 (clear-stream _test-input-stream) -14791 (clear-stream $_test-input-buffered-file->buffer) -14792 (clear-stream _test-output-stream) -14793 (clear-stream $_test-output-buffered-file->buffer) -14794 (clear-stream _test-error-stream) -14795 (clear-stream $_test-error-buffered-file->buffer) -14796 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14797 68/push 0/imm32 -14798 68/push 0/imm32 -14799 89/<- %edx 4/r32/esp -14800 (tailor-exit-descriptor %edx 0x10) -14801 # -14802 (write _test-input-stream "fn foo {\n") -14803 (write _test-input-stream " var x/eax: boolean <- copy 0\n") -14804 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") -14805 (write _test-input-stream " x <- populate y\n") -14806 (write _test-input-stream "}\n") -14807 # convert -14808 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14809 # registers except esp clobbered at this point -14810 # restore ed -14811 89/<- %edx 4/r32/esp -14812 (flush _test-output-buffered-file) -14813 (flush _test-error-buffered-file) -14814 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14820 # check output -14821 (check-stream-equal _test-output-stream "" "F - test-populate-with-output: output should be empty") -14822 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must not have any outputs" "F - test-populate-with-output: error message") -14823 # check that stop(1) was called -14824 (check-ints-equal *(edx+4) 2 "F - test-populate-with-output: exit status") -14825 # don't restore from ebp -14826 81 0/subop/add %esp 8/imm32 -14827 # . epilogue -14828 5d/pop-to-ebp -14829 c3/return -14830 -14831 test-populate-non-addr: -14832 # . prologue -14833 55/push-ebp -14834 89/<- %ebp 4/r32/esp -14835 # setup -14836 (clear-stream _test-input-stream) -14837 (clear-stream $_test-input-buffered-file->buffer) -14838 (clear-stream _test-output-stream) -14839 (clear-stream $_test-output-buffered-file->buffer) -14840 (clear-stream _test-error-stream) -14841 (clear-stream $_test-error-buffered-file->buffer) -14842 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14843 68/push 0/imm32 -14844 68/push 0/imm32 -14845 89/<- %edx 4/r32/esp -14846 (tailor-exit-descriptor %edx 0x10) -14847 # -14848 (write _test-input-stream "fn foo {\n") -14849 (write _test-input-stream " var y: (handle int)\n") -14850 (write _test-input-stream " populate y, 3\n") -14851 (write _test-input-stream "}\n") -14852 # convert -14853 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14854 # registers except esp clobbered at this point -14855 # restore ed -14856 89/<- %edx 4/r32/esp -14857 (flush _test-output-buffered-file) -14858 (flush _test-error-buffered-file) -14859 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14865 # check output -14866 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr: output must be empty") -14867 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr: error message") -14868 # check that stop(1) was called -14869 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr: exit status") -14870 # don't restore from ebp -14871 81 0/subop/add %esp 8/imm32 -14872 # . epilogue -14873 5d/pop-to-ebp -14874 c3/return -14875 -14876 test-populate-non-addr-handle: -14877 # . prologue -14878 55/push-ebp -14879 89/<- %ebp 4/r32/esp -14880 # setup -14881 (clear-stream _test-input-stream) -14882 (clear-stream $_test-input-buffered-file->buffer) -14883 (clear-stream _test-output-stream) -14884 (clear-stream $_test-output-buffered-file->buffer) -14885 (clear-stream _test-error-stream) -14886 (clear-stream $_test-error-buffered-file->buffer) -14887 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14888 68/push 0/imm32 -14889 68/push 0/imm32 -14890 89/<- %edx 4/r32/esp -14891 (tailor-exit-descriptor %edx 0x10) -14892 # -14893 (write _test-input-stream "fn foo {\n") -14894 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") -14895 (write _test-input-stream " populate y, 3\n") -14896 (write _test-input-stream "}\n") -14897 # convert -14898 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14899 # registers except esp clobbered at this point -14900 # restore ed -14901 89/<- %edx 4/r32/esp -14902 (flush _test-output-buffered-file) -14903 (flush _test-error-buffered-file) -14904 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14910 # check output -14911 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr-handle: output should be empty") -14912 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr-handle: error message") -14913 # check that stop(1) was called -14914 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr-handle: exit status") -14915 # don't restore from ebp -14916 81 0/subop/add %esp 8/imm32 -14917 # . epilogue -14918 5d/pop-to-ebp -14919 c3/return -14920 -14921 test-populate-non-addr-handle-array: -14922 # . prologue -14923 55/push-ebp -14924 89/<- %ebp 4/r32/esp -14925 # setup -14926 (clear-stream _test-input-stream) -14927 (clear-stream $_test-input-buffered-file->buffer) -14928 (clear-stream _test-output-stream) -14929 (clear-stream $_test-output-buffered-file->buffer) -14930 (clear-stream _test-error-stream) -14931 (clear-stream $_test-error-buffered-file->buffer) -14932 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -14933 68/push 0/imm32 -14934 68/push 0/imm32 -14935 89/<- %edx 4/r32/esp -14936 (tailor-exit-descriptor %edx 0x10) -14937 # -14938 (write _test-input-stream "fn foo {\n") -14939 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") -14940 (write _test-input-stream " populate y, 3\n") -14941 (write _test-input-stream "}\n") -14942 # convert -14943 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -14944 # registers except esp clobbered at this point -14945 # restore ed -14946 89/<- %edx 4/r32/esp -14947 (flush _test-output-buffered-file) -14948 (flush _test-error-buffered-file) -14949 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -14955 # check output -14956 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr-handle-array: output should be empty") -14957 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr-handle-array: error message") -14958 # check that stop(1) was called -14959 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr-handle-array: exit status") -14960 # don't restore from ebp -14961 81 0/subop/add %esp 8/imm32 -14962 # . epilogue -14963 5d/pop-to-ebp -14964 c3/return -14965 -14966 test-populate-deref-address: -14967 # . prologue -14968 55/push-ebp -14969 89/<- %ebp 4/r32/esp -14970 # setup -14971 (clear-stream _test-input-stream) -14972 (clear-stream $_test-input-buffered-file->buffer) -14973 (clear-stream _test-output-stream) -14974 (clear-stream $_test-output-buffered-file->buffer) -14975 # -14976 (write _test-input-stream "fn foo {\n") -14977 (write _test-input-stream " var y/ecx: (addr addr handle array int) <- copy 0\n") -14978 (write _test-input-stream " populate *y, 3\n") -14979 (write _test-input-stream "}\n") -14980 # convert -14981 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -14982 (flush _test-output-buffered-file) -14983 # no errors -14984 # . epilogue -14985 5d/pop-to-ebp -14986 c3/return -14987 -14988 test-populate-stream-with-no-inout: -14989 # . prologue -14990 55/push-ebp -14991 89/<- %ebp 4/r32/esp -14992 # setup -14993 (clear-stream _test-input-stream) -14994 (clear-stream $_test-input-buffered-file->buffer) -14995 (clear-stream _test-output-stream) -14996 (clear-stream $_test-output-buffered-file->buffer) -14997 (clear-stream _test-error-stream) -14998 (clear-stream $_test-error-buffered-file->buffer) -14999 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15000 68/push 0/imm32 -15001 68/push 0/imm32 -15002 89/<- %edx 4/r32/esp -15003 (tailor-exit-descriptor %edx 0x10) -15004 # -15005 (write _test-input-stream "fn foo {\n") -15006 (write _test-input-stream " populate-stream\n") -15007 (write _test-input-stream "}\n") -15008 # convert -15009 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15010 # registers except esp clobbered at this point -15011 # restore ed -15012 89/<- %edx 4/r32/esp -15013 (flush _test-output-buffered-file) -15014 (flush _test-error-buffered-file) -15015 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15021 # check output -15022 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-no-inout: output should be empty") -15023 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must have two inouts" "F - test-populate-stream-with-no-inout: error message") -15024 # check that stop(1) was called -15025 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-no-inout: exit status") -15026 # don't restore from ebp -15027 81 0/subop/add %esp 8/imm32 -15028 # . epilogue -15029 5d/pop-to-ebp -15030 c3/return -15031 -15032 test-populate-stream-with-too-many-inouts: -15033 # . prologue -15034 55/push-ebp -15035 89/<- %ebp 4/r32/esp -15036 # setup -15037 (clear-stream _test-input-stream) -15038 (clear-stream $_test-input-buffered-file->buffer) -15039 (clear-stream _test-output-stream) -15040 (clear-stream $_test-output-buffered-file->buffer) -15041 (clear-stream _test-error-stream) -15042 (clear-stream $_test-error-buffered-file->buffer) -15043 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15044 68/push 0/imm32 -15045 68/push 0/imm32 -15046 89/<- %edx 4/r32/esp -15047 (tailor-exit-descriptor %edx 0x10) -15048 # -15049 (write _test-input-stream "fn foo {\n") -15050 (write _test-input-stream " var x: (addr handle int)\n") -15051 (write _test-input-stream " populate-stream x, 3, 0\n") -15052 (write _test-input-stream "}\n") -15053 # convert -15054 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15055 # registers except esp clobbered at this point -15056 # restore ed -15057 89/<- %edx 4/r32/esp -15058 (flush _test-output-buffered-file) -15059 (flush _test-error-buffered-file) -15060 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15066 # check output -15067 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-too-many-inouts: output should be empty") -15068 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must have two inouts" "F - test-populate-stream-with-too-many-inouts: error message") -15069 # check that stop(1) was called -15070 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-too-many-inouts: exit status") -15071 # don't restore from ebp -15072 81 0/subop/add %esp 8/imm32 -15073 # . epilogue -15074 5d/pop-to-ebp -15075 c3/return -15076 -15077 test-populate-stream-with-output: -15078 # . prologue -15079 55/push-ebp -15080 89/<- %ebp 4/r32/esp -15081 # setup -15082 (clear-stream _test-input-stream) -15083 (clear-stream $_test-input-buffered-file->buffer) -15084 (clear-stream _test-output-stream) -15085 (clear-stream $_test-output-buffered-file->buffer) -15086 (clear-stream _test-error-stream) -15087 (clear-stream $_test-error-buffered-file->buffer) -15088 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15089 68/push 0/imm32 -15090 68/push 0/imm32 -15091 89/<- %edx 4/r32/esp -15092 (tailor-exit-descriptor %edx 0x10) -15093 # -15094 (write _test-input-stream "fn foo {\n") -15095 (write _test-input-stream " var x/eax: boolean <- copy 0\n") -15096 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") -15097 (write _test-input-stream " x <- populate-stream y\n") -15098 (write _test-input-stream "}\n") -15099 # convert -15100 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15101 # registers except esp clobbered at this point -15102 # restore ed -15103 89/<- %edx 4/r32/esp -15104 (flush _test-output-buffered-file) -15105 (flush _test-error-buffered-file) -15106 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15112 # check output -15113 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-output: output should be empty") -15114 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must not have any outputs" "F - test-populate-stream-with-output: error message") -15115 # check that stop(1) was called -15116 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-output: exit status") -15117 # don't restore from ebp -15118 81 0/subop/add %esp 8/imm32 -15119 # . epilogue -15120 5d/pop-to-ebp -15121 c3/return -15122 -15123 test-populate-stream-non-addr: -15124 # . prologue -15125 55/push-ebp -15126 89/<- %ebp 4/r32/esp -15127 # setup -15128 (clear-stream _test-input-stream) -15129 (clear-stream $_test-input-buffered-file->buffer) -15130 (clear-stream _test-output-stream) -15131 (clear-stream $_test-output-buffered-file->buffer) -15132 (clear-stream _test-error-stream) -15133 (clear-stream $_test-error-buffered-file->buffer) -15134 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15135 68/push 0/imm32 -15136 68/push 0/imm32 -15137 89/<- %edx 4/r32/esp -15138 (tailor-exit-descriptor %edx 0x10) -15139 # -15140 (write _test-input-stream "fn foo {\n") -15141 (write _test-input-stream " var y: (handle int)\n") -15142 (write _test-input-stream " populate-stream y, 3\n") -15143 (write _test-input-stream "}\n") -15144 # convert -15145 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15146 # registers except esp clobbered at this point -15147 # restore ed -15148 89/<- %edx 4/r32/esp -15149 (flush _test-output-buffered-file) -15150 (flush _test-error-buffered-file) -15151 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15157 # check output -15158 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr: output must be empty") -15159 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr: error message") -15160 # check that stop(1) was called -15161 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr: exit status") -15162 # don't restore from ebp -15163 81 0/subop/add %esp 8/imm32 -15164 # . epilogue -15165 5d/pop-to-ebp -15166 c3/return -15167 -15168 test-populate-stream-non-addr-handle: -15169 # . prologue -15170 55/push-ebp -15171 89/<- %ebp 4/r32/esp -15172 # setup -15173 (clear-stream _test-input-stream) -15174 (clear-stream $_test-input-buffered-file->buffer) -15175 (clear-stream _test-output-stream) -15176 (clear-stream $_test-output-buffered-file->buffer) -15177 (clear-stream _test-error-stream) -15178 (clear-stream $_test-error-buffered-file->buffer) -15179 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15180 68/push 0/imm32 -15181 68/push 0/imm32 -15182 89/<- %edx 4/r32/esp -15183 (tailor-exit-descriptor %edx 0x10) -15184 # -15185 (write _test-input-stream "fn foo {\n") -15186 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") -15187 (write _test-input-stream " populate-stream y, 3\n") -15188 (write _test-input-stream "}\n") -15189 # convert -15190 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15191 # registers except esp clobbered at this point -15192 # restore ed -15193 89/<- %edx 4/r32/esp -15194 (flush _test-output-buffered-file) -15195 (flush _test-error-buffered-file) -15196 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15202 # check output -15203 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr-handle: output should be empty") -15204 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr-handle: error message") -15205 # check that stop(1) was called -15206 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr-handle: exit status") -15207 # don't restore from ebp -15208 81 0/subop/add %esp 8/imm32 -15209 # . epilogue -15210 5d/pop-to-ebp -15211 c3/return -15212 -15213 test-populate-stream-non-addr-handle-stream: -15214 # . prologue -15215 55/push-ebp -15216 89/<- %ebp 4/r32/esp -15217 # setup -15218 (clear-stream _test-input-stream) -15219 (clear-stream $_test-input-buffered-file->buffer) -15220 (clear-stream _test-output-stream) -15221 (clear-stream $_test-output-buffered-file->buffer) -15222 (clear-stream _test-error-stream) -15223 (clear-stream $_test-error-buffered-file->buffer) -15224 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15225 68/push 0/imm32 -15226 68/push 0/imm32 -15227 89/<- %edx 4/r32/esp -15228 (tailor-exit-descriptor %edx 0x10) -15229 # -15230 (write _test-input-stream "fn foo {\n") -15231 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") -15232 (write _test-input-stream " populate-stream y, 3\n") -15233 (write _test-input-stream "}\n") -15234 # convert -15235 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15236 # registers except esp clobbered at this point -15237 # restore ed -15238 89/<- %edx 4/r32/esp -15239 (flush _test-output-buffered-file) -15240 (flush _test-error-buffered-file) -15241 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15247 # check output -15248 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr-handle-stream: output should be empty") -15249 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr-handle-stream: error message") -15250 # check that stop(1) was called -15251 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr-handle-stream: exit status") -15252 # don't restore from ebp -15253 81 0/subop/add %esp 8/imm32 -15254 # . epilogue -15255 5d/pop-to-ebp -15256 c3/return -15257 -15258 test-populate-stream-deref-address: -15259 # . prologue -15260 55/push-ebp -15261 89/<- %ebp 4/r32/esp -15262 # setup -15263 (clear-stream _test-input-stream) -15264 (clear-stream $_test-input-buffered-file->buffer) -15265 (clear-stream _test-output-stream) -15266 (clear-stream $_test-output-buffered-file->buffer) -15267 # -15268 (write _test-input-stream "fn foo {\n") -15269 (write _test-input-stream " var y/ecx: (addr addr handle stream int) <- copy 0\n") -15270 (write _test-input-stream " populate-stream *y, 3\n") -15271 (write _test-input-stream "}\n") -15272 # convert -15273 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -15274 (flush _test-output-buffered-file) -15275 # no errors -15276 # . epilogue -15277 5d/pop-to-ebp -15278 c3/return -15279 -15280 test-convert-with-no-inout: -15281 # . prologue -15282 55/push-ebp -15283 89/<- %ebp 4/r32/esp -15284 # setup -15285 (clear-stream _test-input-stream) -15286 (clear-stream $_test-input-buffered-file->buffer) -15287 (clear-stream _test-output-stream) -15288 (clear-stream $_test-output-buffered-file->buffer) -15289 (clear-stream _test-error-stream) -15290 (clear-stream $_test-error-buffered-file->buffer) -15291 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15292 68/push 0/imm32 -15293 68/push 0/imm32 -15294 89/<- %edx 4/r32/esp -15295 (tailor-exit-descriptor %edx 0x10) -15296 # -15297 (write _test-input-stream "fn foo {\n") -15298 (write _test-input-stream " var x/eax: int <- convert\n") -15299 (write _test-input-stream "}\n") -15300 # convert -15301 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15302 # registers except esp clobbered at this point -15303 # restore ed -15304 89/<- %edx 4/r32/esp -15305 (flush _test-output-buffered-file) -15306 (flush _test-error-buffered-file) -15307 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15313 # check output -15314 (check-stream-equal _test-output-stream "" "F - test-convert-with-no-inout: output should be empty") -15315 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' expects an inout" "F - test-convert-with-no-inout: error message") -15316 # check that stop(1) was called -15317 (check-ints-equal *(edx+4) 2 "F - test-convert-with-no-inout: exit status") -15318 # don't restore from ebp -15319 81 0/subop/add %esp 8/imm32 -15320 # . epilogue -15321 5d/pop-to-ebp -15322 c3/return -15323 -15324 test-convert-with-multiple-inouts: -15325 # . prologue -15326 55/push-ebp -15327 89/<- %ebp 4/r32/esp -15328 # setup -15329 (clear-stream _test-input-stream) -15330 (clear-stream $_test-input-buffered-file->buffer) -15331 (clear-stream _test-output-stream) -15332 (clear-stream $_test-output-buffered-file->buffer) -15333 (clear-stream _test-error-stream) -15334 (clear-stream $_test-error-buffered-file->buffer) -15335 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15336 68/push 0/imm32 -15337 68/push 0/imm32 -15338 89/<- %edx 4/r32/esp -15339 (tailor-exit-descriptor %edx 0x10) -15340 # -15341 (write _test-input-stream "fn foo {\n") -15342 (write _test-input-stream " var x/eax: int <- convert 0, 0\n") -15343 (write _test-input-stream "}\n") -15344 # convert -15345 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15346 # registers except esp clobbered at this point -15347 # restore ed -15348 89/<- %edx 4/r32/esp -15349 (flush _test-output-buffered-file) -15350 (flush _test-error-buffered-file) -15351 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15357 # check output -15358 (check-stream-equal _test-output-stream "" "F - test-convert-with-multiple-inouts: output should be empty") -15359 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' must have just one inout" "F - test-convert-with-multiple-inouts: error message") -15360 # check that stop(1) was called -15361 (check-ints-equal *(edx+4) 2 "F - test-convert-with-multiple-inouts: exit status") -15362 # don't restore from ebp -15363 81 0/subop/add %esp 8/imm32 -15364 # . epilogue -15365 5d/pop-to-ebp -15366 c3/return -15367 -15368 test-convert-with-no-output: -15369 # . prologue -15370 55/push-ebp -15371 89/<- %ebp 4/r32/esp -15372 # setup -15373 (clear-stream _test-input-stream) -15374 (clear-stream $_test-input-buffered-file->buffer) -15375 (clear-stream _test-output-stream) -15376 (clear-stream $_test-output-buffered-file->buffer) -15377 (clear-stream _test-error-stream) -15378 (clear-stream $_test-error-buffered-file->buffer) -15379 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15380 68/push 0/imm32 -15381 68/push 0/imm32 -15382 89/<- %edx 4/r32/esp -15383 (tailor-exit-descriptor %edx 0x10) -15384 # -15385 (write _test-input-stream "fn foo {\n") -15386 (write _test-input-stream " convert 0\n") -15387 (write _test-input-stream "}\n") -15388 # convert -15389 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15390 # registers except esp clobbered at this point -15391 # restore ed -15392 89/<- %edx 4/r32/esp -15393 (flush _test-output-buffered-file) -15394 (flush _test-error-buffered-file) -15395 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15401 # check output -15402 (check-stream-equal _test-output-stream "" "F - test-convert-with-no-output: output should be empty") -15403 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' expects an output" "F - test-convert-with-no-output: error message") -15404 # check that stop(1) was called -15405 (check-ints-equal *(edx+4) 2 "F - test-convert-with-no-output: exit status") -15406 # don't restore from ebp -15407 81 0/subop/add %esp 8/imm32 -15408 # . epilogue -15409 5d/pop-to-ebp -15410 c3/return -15411 -15412 test-convert-with-multiple-outputs: -15413 # . prologue -15414 55/push-ebp -15415 89/<- %ebp 4/r32/esp -15416 # setup -15417 (clear-stream _test-input-stream) -15418 (clear-stream $_test-input-buffered-file->buffer) -15419 (clear-stream _test-output-stream) -15420 (clear-stream $_test-output-buffered-file->buffer) -15421 (clear-stream _test-error-stream) -15422 (clear-stream $_test-error-buffered-file->buffer) -15423 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15424 68/push 0/imm32 -15425 68/push 0/imm32 -15426 89/<- %edx 4/r32/esp -15427 (tailor-exit-descriptor %edx 0x10) -15428 # -15429 (write _test-input-stream "fn foo {\n") -15430 (write _test-input-stream " var x/eax: int <- copy 0\n") -15431 (write _test-input-stream " var y/ecx: int <- copy 0\n") -15432 (write _test-input-stream " x, y <- convert 0\n") -15433 (write _test-input-stream "}\n") -15434 # convert -15435 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15436 # registers except esp clobbered at this point -15437 # restore ed -15438 89/<- %edx 4/r32/esp -15439 (flush _test-output-buffered-file) -15440 (flush _test-error-buffered-file) -15441 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15447 # check output -15448 (check-stream-equal _test-output-stream "" "F - test-convert-with-multiple-outputs: output should be empty") -15449 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' must have just one output" "F - test-convert-with-multiple-outputs: error message") -15450 # check that stop(1) was called -15451 (check-ints-equal *(edx+4) 2 "F - test-convert-with-multiple-outputs: exit status") -15452 # don't restore from ebp -15453 81 0/subop/add %esp 8/imm32 -15454 # . epilogue -15455 5d/pop-to-ebp -15456 c3/return -15457 -15458 test-convert-deref-address: -15459 # . prologue -15460 55/push-ebp -15461 89/<- %ebp 4/r32/esp -15462 # setup -15463 (clear-stream _test-input-stream) -15464 (clear-stream $_test-input-buffered-file->buffer) -15465 (clear-stream _test-output-stream) -15466 (clear-stream $_test-output-buffered-file->buffer) -15467 # -15468 (write _test-input-stream "fn foo {\n") -15469 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") -15470 (write _test-input-stream " var y/xmm4: float <- convert *x\n") -15471 (write _test-input-stream "}\n") -15472 # convert -15473 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) -15474 (flush _test-output-buffered-file) -15475 # no errors -15476 # . epilogue -15477 5d/pop-to-ebp -15478 c3/return -15479 -15480 test-convert-to-non-register: -15481 # . prologue -15482 55/push-ebp -15483 89/<- %ebp 4/r32/esp -15484 # setup -15485 (clear-stream _test-input-stream) -15486 (clear-stream $_test-input-buffered-file->buffer) -15487 (clear-stream _test-output-stream) -15488 (clear-stream $_test-output-buffered-file->buffer) -15489 (clear-stream _test-error-stream) -15490 (clear-stream $_test-error-buffered-file->buffer) -15491 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15492 68/push 0/imm32 -15493 68/push 0/imm32 -15494 89/<- %edx 4/r32/esp -15495 (tailor-exit-descriptor %edx 0x10) -15496 # -15497 (write _test-input-stream "fn foo {\n") -15498 (write _test-input-stream " var x: float\n") -15499 (write _test-input-stream " var y: int\n") -15500 (write _test-input-stream " x <- convert y\n") -15501 (write _test-input-stream "}\n") -15502 # convert -15503 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15504 # registers except esp clobbered at this point -15505 # restore ed -15506 89/<- %edx 4/r32/esp -15507 (flush _test-output-buffered-file) -15508 (flush _test-error-buffered-file) -15509 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15515 # check output -15516 (check-stream-equal _test-output-stream "" "F - test-convert-to-non-register: output should be empty") -15517 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: output 'x' not in a register" "F - test-convert-to-non-register: error message") -15518 # check that stop(1) was called -15519 (check-ints-equal *(edx+4) 2 "F - test-convert-to-non-register: exit status") -15520 # don't restore from ebp -15521 81 0/subop/add %esp 8/imm32 -15522 # . epilogue -15523 5d/pop-to-ebp -15524 c3/return -15525 -15526 test-convert-invalid-inout-type: -15527 # . prologue -15528 55/push-ebp -15529 89/<- %ebp 4/r32/esp -15530 # setup -15531 (clear-stream _test-input-stream) -15532 (clear-stream $_test-input-buffered-file->buffer) -15533 (clear-stream _test-output-stream) -15534 (clear-stream $_test-output-buffered-file->buffer) -15535 (clear-stream _test-error-stream) -15536 (clear-stream $_test-error-buffered-file->buffer) -15537 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15538 68/push 0/imm32 -15539 68/push 0/imm32 -15540 89/<- %edx 4/r32/esp -15541 (tailor-exit-descriptor %edx 0x10) -15542 # -15543 (write _test-input-stream "fn foo {\n") -15544 (write _test-input-stream " var x: boolean\n") -15545 (write _test-input-stream " var y/xmm1: float <- convert x\n") -15546 (write _test-input-stream "}\n") -15547 # convert -15548 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15549 # registers except esp clobbered at this point -15550 # restore ed -15551 89/<- %edx 4/r32/esp -15552 (flush _test-output-buffered-file) -15553 (flush _test-error-buffered-file) -15554 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15560 # check output -15561 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-inout-type: output should be empty") -15562 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: inout 'x' must be an int or float" "F - test-convert-invalid-inout-type: error message") -15563 # check that stop(1) was called -15564 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-inout-type: exit status") -15565 # don't restore from ebp -15566 81 0/subop/add %esp 8/imm32 -15567 # . epilogue -15568 5d/pop-to-ebp -15569 c3/return -15570 -15571 test-convert-invalid-output-type: -15572 # . prologue -15573 55/push-ebp -15574 89/<- %ebp 4/r32/esp -15575 # setup -15576 (clear-stream _test-input-stream) -15577 (clear-stream $_test-input-buffered-file->buffer) -15578 (clear-stream _test-output-stream) -15579 (clear-stream $_test-output-buffered-file->buffer) -15580 (clear-stream _test-error-stream) -15581 (clear-stream $_test-error-buffered-file->buffer) -15582 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15583 68/push 0/imm32 -15584 68/push 0/imm32 -15585 89/<- %edx 4/r32/esp -15586 (tailor-exit-descriptor %edx 0x10) -15587 # -15588 (write _test-input-stream "fn foo {\n") -15589 (write _test-input-stream " var x: float\n") -15590 (write _test-input-stream " var y/eax: boolean <- convert x\n") -15591 (write _test-input-stream "}\n") -15592 # convert -15593 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15594 # registers except esp clobbered at this point -15595 # restore ed -15596 89/<- %edx 4/r32/esp -15597 (flush _test-output-buffered-file) -15598 (flush _test-error-buffered-file) -15599 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15605 # check output -15606 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-output-type: output should be empty") -15607 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: output 'y' must be an int or float" "F - test-convert-invalid-output-type: error message") -15608 # check that stop(1) was called -15609 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-output-type: exit status") -15610 # don't restore from ebp -15611 81 0/subop/add %esp 8/imm32 -15612 # . epilogue -15613 5d/pop-to-ebp -15614 c3/return -15615 -15616 test-convert-int-to-int: -15617 # . prologue -15618 55/push-ebp -15619 89/<- %ebp 4/r32/esp -15620 # setup -15621 (clear-stream _test-input-stream) -15622 (clear-stream $_test-input-buffered-file->buffer) -15623 (clear-stream _test-output-stream) -15624 (clear-stream $_test-output-buffered-file->buffer) -15625 (clear-stream _test-error-stream) -15626 (clear-stream $_test-error-buffered-file->buffer) -15627 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15628 68/push 0/imm32 -15629 68/push 0/imm32 -15630 89/<- %edx 4/r32/esp -15631 (tailor-exit-descriptor %edx 0x10) -15632 # -15633 (write _test-input-stream "fn foo {\n") -15634 (write _test-input-stream " var x: int\n") -15635 (write _test-input-stream " var y/eax: int <- convert x\n") -15636 (write _test-input-stream "}\n") -15637 # convert -15638 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15639 # registers except esp clobbered at this point -15640 # restore ed -15641 89/<- %edx 4/r32/esp -15642 (flush _test-output-buffered-file) -15643 (flush _test-error-buffered-file) -15644 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15650 # check output -15651 (check-stream-equal _test-output-stream "" "F - test-convert-int-to-int: output should be empty") -15652 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: no need to convert int to int" "F - test-convert-int-to-int: error message") -15653 # check that stop(1) was called -15654 (check-ints-equal *(edx+4) 2 "F - test-convert-int-to-int: exit status") -15655 # don't restore from ebp -15656 81 0/subop/add %esp 8/imm32 -15657 # . epilogue -15658 5d/pop-to-ebp -15659 c3/return -15660 -15661 test-convert-float-to-float: -15662 # . prologue -15663 55/push-ebp -15664 89/<- %ebp 4/r32/esp -15665 # setup -15666 (clear-stream _test-input-stream) -15667 (clear-stream $_test-input-buffered-file->buffer) -15668 (clear-stream _test-output-stream) -15669 (clear-stream $_test-output-buffered-file->buffer) -15670 (clear-stream _test-error-stream) -15671 (clear-stream $_test-error-buffered-file->buffer) -15672 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) -15673 68/push 0/imm32 -15674 68/push 0/imm32 -15675 89/<- %edx 4/r32/esp -15676 (tailor-exit-descriptor %edx 0x10) -15677 # -15678 (write _test-input-stream "fn foo {\n") -15679 (write _test-input-stream " var x: float\n") -15680 (write _test-input-stream " var y/xmm6: float <- convert x\n") -15681 (write _test-input-stream "}\n") -15682 # convert -15683 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) -15684 # registers except esp clobbered at this point -15685 # restore ed -15686 89/<- %edx 4/r32/esp -15687 (flush _test-output-buffered-file) -15688 (flush _test-error-buffered-file) -15689 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ -15695 # check output -15696 (check-stream-equal _test-output-stream "" "F - test-convert-float-to-float: output should be empty") -15697 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: no need to convert float to float" "F - test-convert-float-to-float: error message") -15698 # check that stop(1) was called -15699 (check-ints-equal *(edx+4) 2 "F - test-convert-float-to-float: exit status") -15700 # don't restore from ebp -15701 81 0/subop/add %esp 8/imm32 -15702 # . epilogue -15703 5d/pop-to-ebp -15704 c3/return -15705 -15706 ####################################################### -15707 # Parsing -15708 ####################################################### -15709 -15710 == data -15711 -15712 # Global state added to each var record when parsing a function -15713 Next-block-index: # (addr int) -15714 1/imm32 -15715 -15716 Curr-block-depth: # (addr int) -15717 1/imm32 -15718 -15719 == code -15720 -15721 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) -15722 # pseudocode -15723 # var curr-function: (addr handle function) = Program->functions -15724 # var curr-signature: (addr handle function) = Program->signatures -15725 # var curr-type: (addr handle typeinfo) = Program->types -15726 # var line: (stream byte 512) -15727 # var word-slice: slice -15728 # while true # line loop -15729 # clear-stream(line) -15730 # read-line-buffered(in, line) -15731 # if (line->write == 0) break # end of file -15732 # word-slice = next-mu-token(line) -15733 # if slice-empty?(word-slice) # end of line -15734 # continue -15735 # else if slice-starts-with?(word-slice, "#") # comment -15736 # continue # end of line -15737 # else if slice-equal?(word-slice, "fn") -15738 # var new-function: (handle function) = allocate(function) -15739 # var vars: (stack live-var 256) -15740 # populate-mu-function-header(line, new-function, vars) -15741 # populate-mu-function-body(in, new-function, vars) -15742 # assert(vars->top == 0) -15743 # *curr-function = new-function -15744 # curr-function = &new-function->next -15745 # else if slice-equal?(word-slice, "sig") -15746 # var new-function: (handle function) = allocate(function) -15747 # populate-mu-function-signature(line, new-function) -15748 # *curr-signature = new-function -15749 # curr-signature = &new-function->next -15750 # else if slice-equal?(word-slice, "type") -15751 # word-slice = next-mu-token(line) -15752 # type-id = pos-or-insert-slice(Type-id, word-slice) -15753 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) -15754 # assert(next-word(line) == "{") -15755 # populate-mu-type(in, new-type) -15756 # else -15757 # abort() -15758 # -15759 # . prologue -15760 55/push-ebp -15761 89/<- %ebp 4/r32/esp -15762 # var curr-signature: (addr handle function) at *(ebp-4) -15763 68/push _Program-signatures/imm32 -15764 # . save registers -15765 50/push-eax -15766 51/push-ecx -15767 52/push-edx -15768 53/push-ebx -15769 56/push-esi -15770 57/push-edi -15771 # var line/ecx: (stream byte 512) -15772 81 5/subop/subtract %esp 0x200/imm32 -15773 68/push 0x200/imm32/size -15774 68/push 0/imm32/read -15775 68/push 0/imm32/write -15776 89/<- %ecx 4/r32/esp -15777 # var word-slice/edx: slice -15778 68/push 0/imm32/end -15779 68/push 0/imm32/start -15780 89/<- %edx 4/r32/esp -15781 # var curr-function/edi: (addr handle function) -15782 bf/copy-to-edi _Program-functions/imm32 -15783 # var vars/ebx: (stack live-var 256) -15784 81 5/subop/subtract %esp 0xc00/imm32 -15785 68/push 0xc00/imm32/size -15786 68/push 0/imm32/top -15787 89/<- %ebx 4/r32/esp -15788 { -15789 $parse-mu:line-loop: -15790 (clear-stream %ecx) -15791 (read-line-buffered *(ebp+8) %ecx) -15792 # if (line->write == 0) break -15793 81 7/subop/compare *ecx 0/imm32 -15794 0f 84/jump-if-= break/disp32 -15795 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ -15801 (next-mu-token %ecx %edx) -15802 # if slice-empty?(word-slice) continue -15803 (slice-empty? %edx) # => eax -15804 3d/compare-eax-and 0/imm32/false -15805 0f 85/jump-if-!= loop/disp32 -15806 # if (*word-slice->start == "#") continue -15807 # . eax = *word-slice->start -15808 8b/-> *edx 0/r32/eax -15809 8a/copy-byte *eax 0/r32/AL -15810 25/and-eax-with 0xff/imm32 -15811 # . if (eax == '#') continue -15812 3d/compare-eax-and 0x23/imm32/hash -15813 0f 84/jump-if-= loop/disp32 -15814 # if (slice-equal?(word-slice, "fn")) parse a function -15815 { -15816 $parse-mu:fn: -15817 (slice-equal? %edx "fn") # => eax -15818 3d/compare-eax-and 0/imm32/false -15819 0f 84/jump-if-= break/disp32 -15820 # var new-function/esi: (handle function) -15821 68/push 0/imm32 -15822 68/push 0/imm32 -15823 89/<- %esi 4/r32/esp -15824 # populate-mu-function(line, in, vars, new-function) -15825 (allocate Heap *Function-size %esi) -15826 # var new-function-addr/eax: (addr function) -15827 (lookup *esi *(esi+4)) # => eax -15828 # initialize vars -15829 (clear-stack %ebx) -15830 # -15831 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10)) -15832 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10)) -15833 # *curr-function = new-function -15834 8b/-> *esi 0/r32/eax -15835 89/<- *edi 0/r32/eax -15836 8b/-> *(esi+4) 0/r32/eax -15837 89/<- *(edi+4) 0/r32/eax -15838 # curr-function = &new-function->next -15839 # . var tmp/eax: (addr function) = lookup(new-function) -15840 (lookup *esi *(esi+4)) # => eax -15841 # . curr-function = &tmp->next -15842 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next -15843 # reclaim new-function -15844 81 0/subop/add %esp 8/imm32 -15845 # -15846 e9/jump $parse-mu:line-loop/disp32 -15847 } -15848 # if (slice-equal?(word-slice, "sig")) parse a function signature -15849 # Function signatures are for providing types to SubX functions. -15850 { -15851 $parse-mu:sig: -15852 (slice-equal? %edx "sig") # => eax -15853 3d/compare-eax-and 0/imm32/false -15854 0f 84/jump-if-= break/disp32 -15855 # edi = curr-function -15856 57/push-edi -15857 8b/-> *(ebp-4) 7/r32/edi -15858 # var new-function/esi: (handle function) -15859 68/push 0/imm32 -15860 68/push 0/imm32 -15861 89/<- %esi 4/r32/esp -15862 # populate-mu-function(line, in, vars, new-function) -15863 (allocate Heap *Function-size %esi) -15864 # var new-function-addr/eax: (addr function) -15865 (lookup *esi *(esi+4)) # => eax -15866 # -15867 (populate-mu-function-signature %ecx %eax *(ebp+0xc) *(ebp+0x10)) -15868 # *curr-signature = new-function -15869 8b/-> *esi 0/r32/eax -15870 89/<- *edi 0/r32/eax -15871 8b/-> *(esi+4) 0/r32/eax -15872 89/<- *(edi+4) 0/r32/eax -15873 # curr-signature = &new-function->next -15874 # . var tmp/eax: (addr function) = lookup(new-function) -15875 (lookup *esi *(esi+4)) # => eax -15876 # . curr-function = &tmp->next -15877 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next -15878 # reclaim new-function -15879 81 0/subop/add %esp 8/imm32 -15880 # save curr-function -15881 89/<- *(ebp-4) 7/r32/edi -15882 # restore edi -15883 5f/pop-to-edi -15884 # -15885 e9/jump $parse-mu:line-loop/disp32 -15886 } -15887 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition -15888 { -15889 $parse-mu:type: -15890 (slice-equal? %edx "type") # => eax -15891 3d/compare-eax-and 0/imm32 -15892 0f 84/jump-if-= break/disp32 -15893 (next-mu-token %ecx %edx) -15894 # var type-id/eax: int -15895 (pos-or-insert-slice Type-id %edx) # => eax -15896 # spill -15897 51/push-ecx -15898 # var new-type/ecx: (handle typeinfo) -15899 68/push 0/imm32 -15900 68/push 0/imm32 -15901 89/<- %ecx 4/r32/esp -15902 (find-or-create-typeinfo %eax %ecx) -15903 # -15904 (lookup *ecx *(ecx+4)) # => eax -15905 # TODO: ensure that 'line' has nothing else but '{' -15906 #? (dump-typeinfos "=== aaa\n") -15907 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax -15908 #? (dump-typeinfos "=== zzz\n") -15909 # reclaim new-type -15910 81 0/subop/add %esp 8/imm32 -15911 # restore -15912 59/pop-to-ecx -15913 e9/jump $parse-mu:line-loop/disp32 -15914 } -15915 # otherwise abort -15916 e9/jump $parse-mu:error1/disp32 -15917 } # end line loop -15918 $parse-mu:end: -15919 # . reclaim locals -15920 81 0/subop/add %esp 0x20c/imm32 # line -15921 81 0/subop/add %esp 0xc08/imm32 # vars -15922 81 0/subop/add %esp 8/imm32 -15923 # . restore registers -15924 5f/pop-to-edi -15925 5e/pop-to-esi -15926 5b/pop-to-ebx -15927 5a/pop-to-edx -15928 59/pop-to-ecx -15929 58/pop-to-eax -15930 # . reclaim local -15931 81 0/subop/add %esp 4/imm32 -15932 # . epilogue -15933 89/<- %esp 5/r32/ebp -15934 5d/pop-to-ebp -15935 c3/return -15936 -15937 $parse-mu:error1: -15938 # error("unexpected top-level command: " word-slice "\n") -15939 (write-buffered *(ebp+0xc) "unexpected top-level command: ") -15940 (write-slice-buffered *(ebp+0xc) %edx) -15941 (write-buffered *(ebp+0xc) "\n") -15942 (flush *(ebp+0xc)) -15943 (stop *(ebp+0x10) 1) -15944 # never gets here -15945 -15946 $parse-mu:error2: -15947 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") -15948 (write-int32-hex-buffered *(ebp+0xc) *ebx) -15949 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '") -15950 (write-slice-buffered *(ebp+0xc) *eax) # Function-name -15951 (write-buffered *(ebp+0xc) "'\n") -15952 (flush *(ebp+0xc)) -15953 (stop *(ebp+0x10) 1) -15954 # never gets here -15955 -15956 # scenarios considered: -15957 # ✗ fn foo # no block -15958 # ✓ fn foo { -15959 # ✗ fn foo { { -15960 # ✗ fn foo { } -15961 # ✗ fn foo { } { -15962 # ✗ fn foo x { -15963 # ✗ fn foo x: { -15964 # ✓ fn foo x: int { -15965 # ✓ fn foo x: int { -15966 # ✓ fn foo x: int -> _/eax: int { -15967 # TODO: -15968 # disallow outputs of type `(... addr ...)` -15969 # disallow inputs of type `(... addr ... addr ...)` -15970 populate-mu-function-header: # first-line: (addr stream byte), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) -15971 # pseudocode: -15972 # var word-slice: slice -15973 # next-mu-token(first-line, word-slice) -15974 # if slice-empty?(word-slice) abort -15975 # assert(word-slice not in '{' '}' '->') -15976 # out->name = slice-to-string(word-slice) -15977 # ## inouts -15978 # while true -15979 # word-slice = next-mu-token(first-line) -15980 # if slice-empty?(word-slice) abort -15981 # if (word-slice == '{') goto done -15982 # if (word-slice == '->') break -15983 # assert(word-slice != '}') -15984 # var v: (handle var) = parse-var-with-type(word-slice, first-line) -15985 # assert(v->register == null) -15986 # # v->block-depth is implicitly 0 -15987 # out->inouts = append(v, out->inouts) -15988 # push(vars, {v, false}) -15989 # ## outputs -15990 # while true -15991 # word-slice = next-mu-token(first-line) -15992 # if slice-empty?(word-slice) abort -15993 # if (word-slice == '{') break -15994 # assert(word-slice not in '}' '->') -15995 # var v: (handle var) = parse-var-with-type(word-slice, first-line) -15996 # assert(v->register != null) -15997 # assert(v->name == "_") -15998 # out->outputs = append(v, out->outputs) -15999 # done: -16000 # -16001 # . prologue -16002 55/push-ebp -16003 89/<- %ebp 4/r32/esp -16004 # . save registers -16005 50/push-eax -16006 51/push-ecx -16007 52/push-edx -16008 53/push-ebx -16009 57/push-edi -16010 # edi = out -16011 8b/-> *(ebp+0xc) 7/r32/edi -16012 # var word-slice/ecx: slice -16013 68/push 0/imm32/end -16014 68/push 0/imm32/start -16015 89/<- %ecx 4/r32/esp -16016 # var v/ebx: (handle var) -16017 68/push 0/imm32 -16018 68/push 0/imm32 -16019 89/<- %ebx 4/r32/esp -16020 # read function name -16021 (next-mu-token *(ebp+8) %ecx) -16022 # error checking -16023 # if slice-empty?(word-slice) abort -16024 (slice-empty? %ecx) # => eax -16025 3d/compare-eax-and 0/imm32/false -16026 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16027 # if (word-slice == '{') abort -16028 (slice-equal? %ecx "{") # => eax -16029 3d/compare-eax-and 0/imm32/false -16030 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16031 # if (word-slice == '->') abort -16032 (slice-equal? %ecx "->") # => eax -16033 3d/compare-eax-and 0/imm32/false -16034 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16035 # if (word-slice == '}') abort -16036 (slice-equal? %ecx "}") # => eax -16037 3d/compare-eax-and 0/imm32/false -16038 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16039 # if word-slice already defined, abort -16040 (function-exists? %ecx) # => eax -16041 3d/compare-eax-and 0/imm32/false -16042 0f 85/jump-if-!= $populate-mu-function-header:error-duplicate/disp32 -16043 # -16044 (slice-starts-with? %ecx "break") # => eax -16045 3d/compare-eax-and 0/imm32/false -16046 0f 85/jump-if-!= $populate-mu-function-header:error-break/disp32 -16047 (slice-starts-with? %ecx "loop") # => eax +14366 # +14367 (write _test-input-stream "fn foo {\n") +14368 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") +14369 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n") +14370 (write _test-input-stream " copy-object *y, x\n") +14371 (write _test-input-stream "}\n") +14372 # convert +14373 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +14374 (flush _test-output-buffered-file) +14375 # no errors +14376 # . epilogue +14377 5d/pop-to-ebp +14378 c3/return +14379 +14380 test-copy-object-non-addr: +14381 # . prologue +14382 55/push-ebp +14383 89/<- %ebp 4/r32/esp +14384 # setup +14385 (clear-stream _test-input-stream) +14386 (clear-stream $_test-input-buffered-file->buffer) +14387 (clear-stream _test-output-stream) +14388 (clear-stream $_test-output-buffered-file->buffer) +14389 (clear-stream _test-error-stream) +14390 (clear-stream $_test-error-buffered-file->buffer) +14391 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14392 68/push 0/imm32 +14393 68/push 0/imm32 +14394 89/<- %edx 4/r32/esp +14395 (tailor-exit-descriptor %edx 0x10) +14396 # +14397 (write _test-input-stream "fn foo {\n") +14398 (write _test-input-stream " var x: int\n") +14399 (write _test-input-stream " var y: int\n") +14400 (write _test-input-stream " copy-object y, x\n") +14401 (write _test-input-stream "}\n") +14402 # convert +14403 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14404 # registers except esp clobbered at this point +14405 # restore ed +14406 89/<- %edx 4/r32/esp +14407 (flush _test-output-buffered-file) +14408 (flush _test-error-buffered-file) +14409 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14415 # check output +14416 (check-stream-equal _test-output-stream "" "F - test-copy-object-non-addr: output should be empty") +14417 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-object: two inouts with identical addr types expected" "F - test-copy-object-non-addr: error message") +14418 # check that stop(1) was called +14419 (check-ints-equal *(edx+4) 2 "F - test-copy-object-non-addr: exit status") +14420 # don't restore from ebp +14421 81 0/subop/add %esp 8/imm32 +14422 # . epilogue +14423 5d/pop-to-ebp +14424 c3/return +14425 +14426 test-copy-object-non-equal: +14427 # . prologue +14428 55/push-ebp +14429 89/<- %ebp 4/r32/esp +14430 # setup +14431 (clear-stream _test-input-stream) +14432 (clear-stream $_test-input-buffered-file->buffer) +14433 (clear-stream _test-output-stream) +14434 (clear-stream $_test-output-buffered-file->buffer) +14435 (clear-stream _test-error-stream) +14436 (clear-stream $_test-error-buffered-file->buffer) +14437 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14438 68/push 0/imm32 +14439 68/push 0/imm32 +14440 89/<- %edx 4/r32/esp +14441 (tailor-exit-descriptor %edx 0x10) +14442 # +14443 (write _test-input-stream "fn foo {\n") +14444 (write _test-input-stream " var x: (addr int)\n") +14445 (write _test-input-stream " var y: (addr boolean)\n") +14446 (write _test-input-stream " copy-object y, x\n") +14447 (write _test-input-stream "}\n") +14448 # convert +14449 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14450 # registers except esp clobbered at this point +14451 # restore ed +14452 89/<- %edx 4/r32/esp +14453 (flush _test-output-buffered-file) +14454 (flush _test-error-buffered-file) +14455 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14461 # check output +14462 (check-stream-equal _test-output-stream "" "F - test-copy-object-non-equal: output should be empty") +14463 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-object: two inouts with identical addr types expected" "F - test-copy-object-non-equal: error message") +14464 # check that stop(1) was called +14465 (check-ints-equal *(edx+4) 2 "F - test-copy-object-non-equal: exit status") +14466 # don't restore from ebp +14467 81 0/subop/add %esp 8/imm32 +14468 # . epilogue +14469 5d/pop-to-ebp +14470 c3/return +14471 +14472 test-allocate-with-no-inout: +14473 # . prologue +14474 55/push-ebp +14475 89/<- %ebp 4/r32/esp +14476 # setup +14477 (clear-stream _test-input-stream) +14478 (clear-stream $_test-input-buffered-file->buffer) +14479 (clear-stream _test-output-stream) +14480 (clear-stream $_test-output-buffered-file->buffer) +14481 (clear-stream _test-error-stream) +14482 (clear-stream $_test-error-buffered-file->buffer) +14483 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14484 68/push 0/imm32 +14485 68/push 0/imm32 +14486 89/<- %edx 4/r32/esp +14487 (tailor-exit-descriptor %edx 0x10) +14488 # +14489 (write _test-input-stream "fn foo {\n") +14490 (write _test-input-stream " allocate\n") +14491 (write _test-input-stream "}\n") +14492 # convert +14493 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14494 # registers except esp clobbered at this point +14495 # restore ed +14496 89/<- %edx 4/r32/esp +14497 (flush _test-output-buffered-file) +14498 (flush _test-error-buffered-file) +14499 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14505 # check output +14506 (check-stream-equal _test-output-stream "" "F - test-allocate-with-no-inout: output should be empty") +14507 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must have a single inout" "F - test-allocate-with-no-inout: error message") +14508 # check that stop(1) was called +14509 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-no-inout: exit status") +14510 # don't restore from ebp +14511 81 0/subop/add %esp 8/imm32 +14512 # . epilogue +14513 5d/pop-to-ebp +14514 c3/return +14515 +14516 test-allocate-with-too-many-inouts: +14517 # . prologue +14518 55/push-ebp +14519 89/<- %ebp 4/r32/esp +14520 # setup +14521 (clear-stream _test-input-stream) +14522 (clear-stream $_test-input-buffered-file->buffer) +14523 (clear-stream _test-output-stream) +14524 (clear-stream $_test-output-buffered-file->buffer) +14525 (clear-stream _test-error-stream) +14526 (clear-stream $_test-error-buffered-file->buffer) +14527 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14528 68/push 0/imm32 +14529 68/push 0/imm32 +14530 89/<- %edx 4/r32/esp +14531 (tailor-exit-descriptor %edx 0x10) +14532 # +14533 (write _test-input-stream "fn foo {\n") +14534 (write _test-input-stream " var x: (addr handle int)\n") +14535 (write _test-input-stream " allocate x, 0\n") +14536 (write _test-input-stream "}\n") +14537 # convert +14538 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14539 # registers except esp clobbered at this point +14540 # restore ed +14541 89/<- %edx 4/r32/esp +14542 (flush _test-output-buffered-file) +14543 (flush _test-error-buffered-file) +14544 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14550 # check output +14551 (check-stream-equal _test-output-stream "" "F - test-allocate-with-too-many-inouts: output should be empty") +14552 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must have a single inout" "F - test-allocate-with-too-many-inouts: error message") +14553 # check that stop(1) was called +14554 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-too-many-inouts: exit status") +14555 # don't restore from ebp +14556 81 0/subop/add %esp 8/imm32 +14557 # . epilogue +14558 5d/pop-to-ebp +14559 c3/return +14560 +14561 test-allocate-with-output: +14562 # . prologue +14563 55/push-ebp +14564 89/<- %ebp 4/r32/esp +14565 # setup +14566 (clear-stream _test-input-stream) +14567 (clear-stream $_test-input-buffered-file->buffer) +14568 (clear-stream _test-output-stream) +14569 (clear-stream $_test-output-buffered-file->buffer) +14570 (clear-stream _test-error-stream) +14571 (clear-stream $_test-error-buffered-file->buffer) +14572 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14573 68/push 0/imm32 +14574 68/push 0/imm32 +14575 89/<- %edx 4/r32/esp +14576 (tailor-exit-descriptor %edx 0x10) +14577 # +14578 (write _test-input-stream "fn foo {\n") +14579 (write _test-input-stream " var x/eax: boolean <- copy 0\n") +14580 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") +14581 (write _test-input-stream " x <- allocate y\n") +14582 (write _test-input-stream "}\n") +14583 # convert +14584 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14585 # registers except esp clobbered at this point +14586 # restore ed +14587 89/<- %edx 4/r32/esp +14588 (flush _test-output-buffered-file) +14589 (flush _test-error-buffered-file) +14590 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14596 # check output +14597 (check-stream-equal _test-output-stream "" "F - test-allocate-with-output: output should be empty") +14598 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must not have any outputs" "F - test-allocate-with-output: error message") +14599 # check that stop(1) was called +14600 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-output: exit status") +14601 # don't restore from ebp +14602 81 0/subop/add %esp 8/imm32 +14603 # . epilogue +14604 5d/pop-to-ebp +14605 c3/return +14606 +14607 test-allocate-non-addr: +14608 # . prologue +14609 55/push-ebp +14610 89/<- %ebp 4/r32/esp +14611 # setup +14612 (clear-stream _test-input-stream) +14613 (clear-stream $_test-input-buffered-file->buffer) +14614 (clear-stream _test-output-stream) +14615 (clear-stream $_test-output-buffered-file->buffer) +14616 (clear-stream _test-error-stream) +14617 (clear-stream $_test-error-buffered-file->buffer) +14618 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14619 68/push 0/imm32 +14620 68/push 0/imm32 +14621 89/<- %edx 4/r32/esp +14622 (tailor-exit-descriptor %edx 0x10) +14623 # +14624 (write _test-input-stream "fn foo {\n") +14625 (write _test-input-stream " var y: (handle int)\n") +14626 (write _test-input-stream " allocate y\n") +14627 (write _test-input-stream "}\n") +14628 # convert +14629 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14630 # registers except esp clobbered at this point +14631 # restore ed +14632 89/<- %edx 4/r32/esp +14633 (flush _test-output-buffered-file) +14634 (flush _test-error-buffered-file) +14635 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14641 # check output +14642 (check-stream-equal _test-output-stream "" "F - test-allocate-non-addr: output must be empty") +14643 (check-next-stream-line-equal _test-error-stream "fn foo: stmt allocate: inout 'y' must have type (addr handle ...)" "F - test-allocate-non-addr: error message") +14644 # check that stop(1) was called +14645 (check-ints-equal *(edx+4) 2 "F - test-allocate-non-addr: exit status") +14646 # don't restore from ebp +14647 81 0/subop/add %esp 8/imm32 +14648 # . epilogue +14649 5d/pop-to-ebp +14650 c3/return +14651 +14652 test-allocate-non-addr-handle: +14653 # . prologue +14654 55/push-ebp +14655 89/<- %ebp 4/r32/esp +14656 # setup +14657 (clear-stream _test-input-stream) +14658 (clear-stream $_test-input-buffered-file->buffer) +14659 (clear-stream _test-output-stream) +14660 (clear-stream $_test-output-buffered-file->buffer) +14661 (clear-stream _test-error-stream) +14662 (clear-stream $_test-error-buffered-file->buffer) +14663 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14664 68/push 0/imm32 +14665 68/push 0/imm32 +14666 89/<- %edx 4/r32/esp +14667 (tailor-exit-descriptor %edx 0x10) +14668 # +14669 (write _test-input-stream "fn foo {\n") +14670 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") +14671 (write _test-input-stream " allocate y\n") +14672 (write _test-input-stream "}\n") +14673 # convert +14674 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14675 # registers except esp clobbered at this point +14676 # restore ed +14677 89/<- %edx 4/r32/esp +14678 (flush _test-output-buffered-file) +14679 (flush _test-error-buffered-file) +14680 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14686 # check output +14687 (check-stream-equal _test-output-stream "" "F - test-allocate-non-addr-handle: output should be empty") +14688 (check-next-stream-line-equal _test-error-stream "fn foo: stmt allocate: inout 'y' must have type (addr handle ...)" "F - test-allocate-non-addr-handle: error message") +14689 # check that stop(1) was called +14690 (check-ints-equal *(edx+4) 2 "F - test-allocate-non-addr-handle: exit status") +14691 # don't restore from ebp +14692 81 0/subop/add %esp 8/imm32 +14693 # . epilogue +14694 5d/pop-to-ebp +14695 c3/return +14696 +14697 test-allocate-deref-address: +14698 # . prologue +14699 55/push-ebp +14700 89/<- %ebp 4/r32/esp +14701 # setup +14702 (clear-stream _test-input-stream) +14703 (clear-stream $_test-input-buffered-file->buffer) +14704 (clear-stream _test-output-stream) +14705 (clear-stream $_test-output-buffered-file->buffer) +14706 # +14707 (write _test-input-stream "fn foo {\n") +14708 (write _test-input-stream " var y/ecx: (addr addr handle int) <- copy 0\n") +14709 (write _test-input-stream " allocate *y\n") +14710 (write _test-input-stream "}\n") +14711 # convert +14712 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +14713 (flush _test-output-buffered-file) +14714 # no errors +14715 # . epilogue +14716 5d/pop-to-ebp +14717 c3/return +14718 +14719 test-populate-with-no-inout: +14720 # . prologue +14721 55/push-ebp +14722 89/<- %ebp 4/r32/esp +14723 # setup +14724 (clear-stream _test-input-stream) +14725 (clear-stream $_test-input-buffered-file->buffer) +14726 (clear-stream _test-output-stream) +14727 (clear-stream $_test-output-buffered-file->buffer) +14728 (clear-stream _test-error-stream) +14729 (clear-stream $_test-error-buffered-file->buffer) +14730 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14731 68/push 0/imm32 +14732 68/push 0/imm32 +14733 89/<- %edx 4/r32/esp +14734 (tailor-exit-descriptor %edx 0x10) +14735 # +14736 (write _test-input-stream "fn foo {\n") +14737 (write _test-input-stream " populate\n") +14738 (write _test-input-stream "}\n") +14739 # convert +14740 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14741 # registers except esp clobbered at this point +14742 # restore ed +14743 89/<- %edx 4/r32/esp +14744 (flush _test-output-buffered-file) +14745 (flush _test-error-buffered-file) +14746 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14752 # check output +14753 (check-stream-equal _test-output-stream "" "F - test-populate-with-no-inout: output should be empty") +14754 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must have two inouts" "F - test-populate-with-no-inout: error message") +14755 # check that stop(1) was called +14756 (check-ints-equal *(edx+4) 2 "F - test-populate-with-no-inout: exit status") +14757 # don't restore from ebp +14758 81 0/subop/add %esp 8/imm32 +14759 # . epilogue +14760 5d/pop-to-ebp +14761 c3/return +14762 +14763 test-populate-with-too-many-inouts: +14764 # . prologue +14765 55/push-ebp +14766 89/<- %ebp 4/r32/esp +14767 # setup +14768 (clear-stream _test-input-stream) +14769 (clear-stream $_test-input-buffered-file->buffer) +14770 (clear-stream _test-output-stream) +14771 (clear-stream $_test-output-buffered-file->buffer) +14772 (clear-stream _test-error-stream) +14773 (clear-stream $_test-error-buffered-file->buffer) +14774 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14775 68/push 0/imm32 +14776 68/push 0/imm32 +14777 89/<- %edx 4/r32/esp +14778 (tailor-exit-descriptor %edx 0x10) +14779 # +14780 (write _test-input-stream "fn foo {\n") +14781 (write _test-input-stream " var x: (addr handle int)\n") +14782 (write _test-input-stream " populate x, 3, 0\n") +14783 (write _test-input-stream "}\n") +14784 # convert +14785 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14786 # registers except esp clobbered at this point +14787 # restore ed +14788 89/<- %edx 4/r32/esp +14789 (flush _test-output-buffered-file) +14790 (flush _test-error-buffered-file) +14791 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14797 # check output +14798 (check-stream-equal _test-output-stream "" "F - test-populate-with-too-many-inouts: output should be empty") +14799 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must have two inouts" "F - test-populate-with-too-many-inouts: error message") +14800 # check that stop(1) was called +14801 (check-ints-equal *(edx+4) 2 "F - test-populate-with-too-many-inouts: exit status") +14802 # don't restore from ebp +14803 81 0/subop/add %esp 8/imm32 +14804 # . epilogue +14805 5d/pop-to-ebp +14806 c3/return +14807 +14808 test-populate-with-output: +14809 # . prologue +14810 55/push-ebp +14811 89/<- %ebp 4/r32/esp +14812 # setup +14813 (clear-stream _test-input-stream) +14814 (clear-stream $_test-input-buffered-file->buffer) +14815 (clear-stream _test-output-stream) +14816 (clear-stream $_test-output-buffered-file->buffer) +14817 (clear-stream _test-error-stream) +14818 (clear-stream $_test-error-buffered-file->buffer) +14819 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14820 68/push 0/imm32 +14821 68/push 0/imm32 +14822 89/<- %edx 4/r32/esp +14823 (tailor-exit-descriptor %edx 0x10) +14824 # +14825 (write _test-input-stream "fn foo {\n") +14826 (write _test-input-stream " var x/eax: boolean <- copy 0\n") +14827 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") +14828 (write _test-input-stream " x <- populate y\n") +14829 (write _test-input-stream "}\n") +14830 # convert +14831 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14832 # registers except esp clobbered at this point +14833 # restore ed +14834 89/<- %edx 4/r32/esp +14835 (flush _test-output-buffered-file) +14836 (flush _test-error-buffered-file) +14837 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14843 # check output +14844 (check-stream-equal _test-output-stream "" "F - test-populate-with-output: output should be empty") +14845 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must not have any outputs" "F - test-populate-with-output: error message") +14846 # check that stop(1) was called +14847 (check-ints-equal *(edx+4) 2 "F - test-populate-with-output: exit status") +14848 # don't restore from ebp +14849 81 0/subop/add %esp 8/imm32 +14850 # . epilogue +14851 5d/pop-to-ebp +14852 c3/return +14853 +14854 test-populate-non-addr: +14855 # . prologue +14856 55/push-ebp +14857 89/<- %ebp 4/r32/esp +14858 # setup +14859 (clear-stream _test-input-stream) +14860 (clear-stream $_test-input-buffered-file->buffer) +14861 (clear-stream _test-output-stream) +14862 (clear-stream $_test-output-buffered-file->buffer) +14863 (clear-stream _test-error-stream) +14864 (clear-stream $_test-error-buffered-file->buffer) +14865 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14866 68/push 0/imm32 +14867 68/push 0/imm32 +14868 89/<- %edx 4/r32/esp +14869 (tailor-exit-descriptor %edx 0x10) +14870 # +14871 (write _test-input-stream "fn foo {\n") +14872 (write _test-input-stream " var y: (handle int)\n") +14873 (write _test-input-stream " populate y, 3\n") +14874 (write _test-input-stream "}\n") +14875 # convert +14876 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14877 # registers except esp clobbered at this point +14878 # restore ed +14879 89/<- %edx 4/r32/esp +14880 (flush _test-output-buffered-file) +14881 (flush _test-error-buffered-file) +14882 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14888 # check output +14889 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr: output must be empty") +14890 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr: error message") +14891 # check that stop(1) was called +14892 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr: exit status") +14893 # don't restore from ebp +14894 81 0/subop/add %esp 8/imm32 +14895 # . epilogue +14896 5d/pop-to-ebp +14897 c3/return +14898 +14899 test-populate-non-addr-handle: +14900 # . prologue +14901 55/push-ebp +14902 89/<- %ebp 4/r32/esp +14903 # setup +14904 (clear-stream _test-input-stream) +14905 (clear-stream $_test-input-buffered-file->buffer) +14906 (clear-stream _test-output-stream) +14907 (clear-stream $_test-output-buffered-file->buffer) +14908 (clear-stream _test-error-stream) +14909 (clear-stream $_test-error-buffered-file->buffer) +14910 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14911 68/push 0/imm32 +14912 68/push 0/imm32 +14913 89/<- %edx 4/r32/esp +14914 (tailor-exit-descriptor %edx 0x10) +14915 # +14916 (write _test-input-stream "fn foo {\n") +14917 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") +14918 (write _test-input-stream " populate y, 3\n") +14919 (write _test-input-stream "}\n") +14920 # convert +14921 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14922 # registers except esp clobbered at this point +14923 # restore ed +14924 89/<- %edx 4/r32/esp +14925 (flush _test-output-buffered-file) +14926 (flush _test-error-buffered-file) +14927 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14933 # check output +14934 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr-handle: output should be empty") +14935 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr-handle: error message") +14936 # check that stop(1) was called +14937 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr-handle: exit status") +14938 # don't restore from ebp +14939 81 0/subop/add %esp 8/imm32 +14940 # . epilogue +14941 5d/pop-to-ebp +14942 c3/return +14943 +14944 test-populate-non-addr-handle-array: +14945 # . prologue +14946 55/push-ebp +14947 89/<- %ebp 4/r32/esp +14948 # setup +14949 (clear-stream _test-input-stream) +14950 (clear-stream $_test-input-buffered-file->buffer) +14951 (clear-stream _test-output-stream) +14952 (clear-stream $_test-output-buffered-file->buffer) +14953 (clear-stream _test-error-stream) +14954 (clear-stream $_test-error-buffered-file->buffer) +14955 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +14956 68/push 0/imm32 +14957 68/push 0/imm32 +14958 89/<- %edx 4/r32/esp +14959 (tailor-exit-descriptor %edx 0x10) +14960 # +14961 (write _test-input-stream "fn foo {\n") +14962 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") +14963 (write _test-input-stream " populate y, 3\n") +14964 (write _test-input-stream "}\n") +14965 # convert +14966 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +14967 # registers except esp clobbered at this point +14968 # restore ed +14969 89/<- %edx 4/r32/esp +14970 (flush _test-output-buffered-file) +14971 (flush _test-error-buffered-file) +14972 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +14978 # check output +14979 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr-handle-array: output should be empty") +14980 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr-handle-array: error message") +14981 # check that stop(1) was called +14982 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr-handle-array: exit status") +14983 # don't restore from ebp +14984 81 0/subop/add %esp 8/imm32 +14985 # . epilogue +14986 5d/pop-to-ebp +14987 c3/return +14988 +14989 test-populate-deref-address: +14990 # . prologue +14991 55/push-ebp +14992 89/<- %ebp 4/r32/esp +14993 # setup +14994 (clear-stream _test-input-stream) +14995 (clear-stream $_test-input-buffered-file->buffer) +14996 (clear-stream _test-output-stream) +14997 (clear-stream $_test-output-buffered-file->buffer) +14998 # +14999 (write _test-input-stream "fn foo {\n") +15000 (write _test-input-stream " var y/ecx: (addr addr handle array int) <- copy 0\n") +15001 (write _test-input-stream " populate *y, 3\n") +15002 (write _test-input-stream "}\n") +15003 # convert +15004 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +15005 (flush _test-output-buffered-file) +15006 # no errors +15007 # . epilogue +15008 5d/pop-to-ebp +15009 c3/return +15010 +15011 test-populate-stream-with-no-inout: +15012 # . prologue +15013 55/push-ebp +15014 89/<- %ebp 4/r32/esp +15015 # setup +15016 (clear-stream _test-input-stream) +15017 (clear-stream $_test-input-buffered-file->buffer) +15018 (clear-stream _test-output-stream) +15019 (clear-stream $_test-output-buffered-file->buffer) +15020 (clear-stream _test-error-stream) +15021 (clear-stream $_test-error-buffered-file->buffer) +15022 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15023 68/push 0/imm32 +15024 68/push 0/imm32 +15025 89/<- %edx 4/r32/esp +15026 (tailor-exit-descriptor %edx 0x10) +15027 # +15028 (write _test-input-stream "fn foo {\n") +15029 (write _test-input-stream " populate-stream\n") +15030 (write _test-input-stream "}\n") +15031 # convert +15032 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15033 # registers except esp clobbered at this point +15034 # restore ed +15035 89/<- %edx 4/r32/esp +15036 (flush _test-output-buffered-file) +15037 (flush _test-error-buffered-file) +15038 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15044 # check output +15045 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-no-inout: output should be empty") +15046 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must have two inouts" "F - test-populate-stream-with-no-inout: error message") +15047 # check that stop(1) was called +15048 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-no-inout: exit status") +15049 # don't restore from ebp +15050 81 0/subop/add %esp 8/imm32 +15051 # . epilogue +15052 5d/pop-to-ebp +15053 c3/return +15054 +15055 test-populate-stream-with-too-many-inouts: +15056 # . prologue +15057 55/push-ebp +15058 89/<- %ebp 4/r32/esp +15059 # setup +15060 (clear-stream _test-input-stream) +15061 (clear-stream $_test-input-buffered-file->buffer) +15062 (clear-stream _test-output-stream) +15063 (clear-stream $_test-output-buffered-file->buffer) +15064 (clear-stream _test-error-stream) +15065 (clear-stream $_test-error-buffered-file->buffer) +15066 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15067 68/push 0/imm32 +15068 68/push 0/imm32 +15069 89/<- %edx 4/r32/esp +15070 (tailor-exit-descriptor %edx 0x10) +15071 # +15072 (write _test-input-stream "fn foo {\n") +15073 (write _test-input-stream " var x: (addr handle int)\n") +15074 (write _test-input-stream " populate-stream x, 3, 0\n") +15075 (write _test-input-stream "}\n") +15076 # convert +15077 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15078 # registers except esp clobbered at this point +15079 # restore ed +15080 89/<- %edx 4/r32/esp +15081 (flush _test-output-buffered-file) +15082 (flush _test-error-buffered-file) +15083 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15089 # check output +15090 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-too-many-inouts: output should be empty") +15091 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must have two inouts" "F - test-populate-stream-with-too-many-inouts: error message") +15092 # check that stop(1) was called +15093 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-too-many-inouts: exit status") +15094 # don't restore from ebp +15095 81 0/subop/add %esp 8/imm32 +15096 # . epilogue +15097 5d/pop-to-ebp +15098 c3/return +15099 +15100 test-populate-stream-with-output: +15101 # . prologue +15102 55/push-ebp +15103 89/<- %ebp 4/r32/esp +15104 # setup +15105 (clear-stream _test-input-stream) +15106 (clear-stream $_test-input-buffered-file->buffer) +15107 (clear-stream _test-output-stream) +15108 (clear-stream $_test-output-buffered-file->buffer) +15109 (clear-stream _test-error-stream) +15110 (clear-stream $_test-error-buffered-file->buffer) +15111 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15112 68/push 0/imm32 +15113 68/push 0/imm32 +15114 89/<- %edx 4/r32/esp +15115 (tailor-exit-descriptor %edx 0x10) +15116 # +15117 (write _test-input-stream "fn foo {\n") +15118 (write _test-input-stream " var x/eax: boolean <- copy 0\n") +15119 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") +15120 (write _test-input-stream " x <- populate-stream y\n") +15121 (write _test-input-stream "}\n") +15122 # convert +15123 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15124 # registers except esp clobbered at this point +15125 # restore ed +15126 89/<- %edx 4/r32/esp +15127 (flush _test-output-buffered-file) +15128 (flush _test-error-buffered-file) +15129 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15135 # check output +15136 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-output: output should be empty") +15137 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must not have any outputs" "F - test-populate-stream-with-output: error message") +15138 # check that stop(1) was called +15139 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-output: exit status") +15140 # don't restore from ebp +15141 81 0/subop/add %esp 8/imm32 +15142 # . epilogue +15143 5d/pop-to-ebp +15144 c3/return +15145 +15146 test-populate-stream-non-addr: +15147 # . prologue +15148 55/push-ebp +15149 89/<- %ebp 4/r32/esp +15150 # setup +15151 (clear-stream _test-input-stream) +15152 (clear-stream $_test-input-buffered-file->buffer) +15153 (clear-stream _test-output-stream) +15154 (clear-stream $_test-output-buffered-file->buffer) +15155 (clear-stream _test-error-stream) +15156 (clear-stream $_test-error-buffered-file->buffer) +15157 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15158 68/push 0/imm32 +15159 68/push 0/imm32 +15160 89/<- %edx 4/r32/esp +15161 (tailor-exit-descriptor %edx 0x10) +15162 # +15163 (write _test-input-stream "fn foo {\n") +15164 (write _test-input-stream " var y: (handle int)\n") +15165 (write _test-input-stream " populate-stream y, 3\n") +15166 (write _test-input-stream "}\n") +15167 # convert +15168 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15169 # registers except esp clobbered at this point +15170 # restore ed +15171 89/<- %edx 4/r32/esp +15172 (flush _test-output-buffered-file) +15173 (flush _test-error-buffered-file) +15174 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15180 # check output +15181 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr: output must be empty") +15182 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr: error message") +15183 # check that stop(1) was called +15184 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr: exit status") +15185 # don't restore from ebp +15186 81 0/subop/add %esp 8/imm32 +15187 # . epilogue +15188 5d/pop-to-ebp +15189 c3/return +15190 +15191 test-populate-stream-non-addr-handle: +15192 # . prologue +15193 55/push-ebp +15194 89/<- %ebp 4/r32/esp +15195 # setup +15196 (clear-stream _test-input-stream) +15197 (clear-stream $_test-input-buffered-file->buffer) +15198 (clear-stream _test-output-stream) +15199 (clear-stream $_test-output-buffered-file->buffer) +15200 (clear-stream _test-error-stream) +15201 (clear-stream $_test-error-buffered-file->buffer) +15202 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15203 68/push 0/imm32 +15204 68/push 0/imm32 +15205 89/<- %edx 4/r32/esp +15206 (tailor-exit-descriptor %edx 0x10) +15207 # +15208 (write _test-input-stream "fn foo {\n") +15209 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n") +15210 (write _test-input-stream " populate-stream y, 3\n") +15211 (write _test-input-stream "}\n") +15212 # convert +15213 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15214 # registers except esp clobbered at this point +15215 # restore ed +15216 89/<- %edx 4/r32/esp +15217 (flush _test-output-buffered-file) +15218 (flush _test-error-buffered-file) +15219 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15225 # check output +15226 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr-handle: output should be empty") +15227 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr-handle: error message") +15228 # check that stop(1) was called +15229 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr-handle: exit status") +15230 # don't restore from ebp +15231 81 0/subop/add %esp 8/imm32 +15232 # . epilogue +15233 5d/pop-to-ebp +15234 c3/return +15235 +15236 test-populate-stream-non-addr-handle-stream: +15237 # . prologue +15238 55/push-ebp +15239 89/<- %ebp 4/r32/esp +15240 # setup +15241 (clear-stream _test-input-stream) +15242 (clear-stream $_test-input-buffered-file->buffer) +15243 (clear-stream _test-output-stream) +15244 (clear-stream $_test-output-buffered-file->buffer) +15245 (clear-stream _test-error-stream) +15246 (clear-stream $_test-error-buffered-file->buffer) +15247 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15248 68/push 0/imm32 +15249 68/push 0/imm32 +15250 89/<- %edx 4/r32/esp +15251 (tailor-exit-descriptor %edx 0x10) +15252 # +15253 (write _test-input-stream "fn foo {\n") +15254 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n") +15255 (write _test-input-stream " populate-stream y, 3\n") +15256 (write _test-input-stream "}\n") +15257 # convert +15258 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15259 # registers except esp clobbered at this point +15260 # restore ed +15261 89/<- %edx 4/r32/esp +15262 (flush _test-output-buffered-file) +15263 (flush _test-error-buffered-file) +15264 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15270 # check output +15271 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr-handle-stream: output should be empty") +15272 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr-handle-stream: error message") +15273 # check that stop(1) was called +15274 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr-handle-stream: exit status") +15275 # don't restore from ebp +15276 81 0/subop/add %esp 8/imm32 +15277 # . epilogue +15278 5d/pop-to-ebp +15279 c3/return +15280 +15281 test-populate-stream-deref-address: +15282 # . prologue +15283 55/push-ebp +15284 89/<- %ebp 4/r32/esp +15285 # setup +15286 (clear-stream _test-input-stream) +15287 (clear-stream $_test-input-buffered-file->buffer) +15288 (clear-stream _test-output-stream) +15289 (clear-stream $_test-output-buffered-file->buffer) +15290 # +15291 (write _test-input-stream "fn foo {\n") +15292 (write _test-input-stream " var y/ecx: (addr addr handle stream int) <- copy 0\n") +15293 (write _test-input-stream " populate-stream *y, 3\n") +15294 (write _test-input-stream "}\n") +15295 # convert +15296 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +15297 (flush _test-output-buffered-file) +15298 # no errors +15299 # . epilogue +15300 5d/pop-to-ebp +15301 c3/return +15302 +15303 test-convert-with-no-inout: +15304 # . prologue +15305 55/push-ebp +15306 89/<- %ebp 4/r32/esp +15307 # setup +15308 (clear-stream _test-input-stream) +15309 (clear-stream $_test-input-buffered-file->buffer) +15310 (clear-stream _test-output-stream) +15311 (clear-stream $_test-output-buffered-file->buffer) +15312 (clear-stream _test-error-stream) +15313 (clear-stream $_test-error-buffered-file->buffer) +15314 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15315 68/push 0/imm32 +15316 68/push 0/imm32 +15317 89/<- %edx 4/r32/esp +15318 (tailor-exit-descriptor %edx 0x10) +15319 # +15320 (write _test-input-stream "fn foo {\n") +15321 (write _test-input-stream " var x/eax: int <- convert\n") +15322 (write _test-input-stream "}\n") +15323 # convert +15324 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15325 # registers except esp clobbered at this point +15326 # restore ed +15327 89/<- %edx 4/r32/esp +15328 (flush _test-output-buffered-file) +15329 (flush _test-error-buffered-file) +15330 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15336 # check output +15337 (check-stream-equal _test-output-stream "" "F - test-convert-with-no-inout: output should be empty") +15338 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' expects an inout" "F - test-convert-with-no-inout: error message") +15339 # check that stop(1) was called +15340 (check-ints-equal *(edx+4) 2 "F - test-convert-with-no-inout: exit status") +15341 # don't restore from ebp +15342 81 0/subop/add %esp 8/imm32 +15343 # . epilogue +15344 5d/pop-to-ebp +15345 c3/return +15346 +15347 test-convert-with-multiple-inouts: +15348 # . prologue +15349 55/push-ebp +15350 89/<- %ebp 4/r32/esp +15351 # setup +15352 (clear-stream _test-input-stream) +15353 (clear-stream $_test-input-buffered-file->buffer) +15354 (clear-stream _test-output-stream) +15355 (clear-stream $_test-output-buffered-file->buffer) +15356 (clear-stream _test-error-stream) +15357 (clear-stream $_test-error-buffered-file->buffer) +15358 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15359 68/push 0/imm32 +15360 68/push 0/imm32 +15361 89/<- %edx 4/r32/esp +15362 (tailor-exit-descriptor %edx 0x10) +15363 # +15364 (write _test-input-stream "fn foo {\n") +15365 (write _test-input-stream " var x/eax: int <- convert 0, 0\n") +15366 (write _test-input-stream "}\n") +15367 # convert +15368 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15369 # registers except esp clobbered at this point +15370 # restore ed +15371 89/<- %edx 4/r32/esp +15372 (flush _test-output-buffered-file) +15373 (flush _test-error-buffered-file) +15374 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15380 # check output +15381 (check-stream-equal _test-output-stream "" "F - test-convert-with-multiple-inouts: output should be empty") +15382 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' must have just one inout" "F - test-convert-with-multiple-inouts: error message") +15383 # check that stop(1) was called +15384 (check-ints-equal *(edx+4) 2 "F - test-convert-with-multiple-inouts: exit status") +15385 # don't restore from ebp +15386 81 0/subop/add %esp 8/imm32 +15387 # . epilogue +15388 5d/pop-to-ebp +15389 c3/return +15390 +15391 test-convert-with-no-output: +15392 # . prologue +15393 55/push-ebp +15394 89/<- %ebp 4/r32/esp +15395 # setup +15396 (clear-stream _test-input-stream) +15397 (clear-stream $_test-input-buffered-file->buffer) +15398 (clear-stream _test-output-stream) +15399 (clear-stream $_test-output-buffered-file->buffer) +15400 (clear-stream _test-error-stream) +15401 (clear-stream $_test-error-buffered-file->buffer) +15402 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15403 68/push 0/imm32 +15404 68/push 0/imm32 +15405 89/<- %edx 4/r32/esp +15406 (tailor-exit-descriptor %edx 0x10) +15407 # +15408 (write _test-input-stream "fn foo {\n") +15409 (write _test-input-stream " convert 0\n") +15410 (write _test-input-stream "}\n") +15411 # convert +15412 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15413 # registers except esp clobbered at this point +15414 # restore ed +15415 89/<- %edx 4/r32/esp +15416 (flush _test-output-buffered-file) +15417 (flush _test-error-buffered-file) +15418 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15424 # check output +15425 (check-stream-equal _test-output-stream "" "F - test-convert-with-no-output: output should be empty") +15426 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' expects an output" "F - test-convert-with-no-output: error message") +15427 # check that stop(1) was called +15428 (check-ints-equal *(edx+4) 2 "F - test-convert-with-no-output: exit status") +15429 # don't restore from ebp +15430 81 0/subop/add %esp 8/imm32 +15431 # . epilogue +15432 5d/pop-to-ebp +15433 c3/return +15434 +15435 test-convert-with-multiple-outputs: +15436 # . prologue +15437 55/push-ebp +15438 89/<- %ebp 4/r32/esp +15439 # setup +15440 (clear-stream _test-input-stream) +15441 (clear-stream $_test-input-buffered-file->buffer) +15442 (clear-stream _test-output-stream) +15443 (clear-stream $_test-output-buffered-file->buffer) +15444 (clear-stream _test-error-stream) +15445 (clear-stream $_test-error-buffered-file->buffer) +15446 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15447 68/push 0/imm32 +15448 68/push 0/imm32 +15449 89/<- %edx 4/r32/esp +15450 (tailor-exit-descriptor %edx 0x10) +15451 # +15452 (write _test-input-stream "fn foo {\n") +15453 (write _test-input-stream " var x/eax: int <- copy 0\n") +15454 (write _test-input-stream " var y/ecx: int <- copy 0\n") +15455 (write _test-input-stream " x, y <- convert 0\n") +15456 (write _test-input-stream "}\n") +15457 # convert +15458 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15459 # registers except esp clobbered at this point +15460 # restore ed +15461 89/<- %edx 4/r32/esp +15462 (flush _test-output-buffered-file) +15463 (flush _test-error-buffered-file) +15464 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15470 # check output +15471 (check-stream-equal _test-output-stream "" "F - test-convert-with-multiple-outputs: output should be empty") +15472 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' must have just one output" "F - test-convert-with-multiple-outputs: error message") +15473 # check that stop(1) was called +15474 (check-ints-equal *(edx+4) 2 "F - test-convert-with-multiple-outputs: exit status") +15475 # don't restore from ebp +15476 81 0/subop/add %esp 8/imm32 +15477 # . epilogue +15478 5d/pop-to-ebp +15479 c3/return +15480 +15481 test-convert-deref-address: +15482 # . prologue +15483 55/push-ebp +15484 89/<- %ebp 4/r32/esp +15485 # setup +15486 (clear-stream _test-input-stream) +15487 (clear-stream $_test-input-buffered-file->buffer) +15488 (clear-stream _test-output-stream) +15489 (clear-stream $_test-output-buffered-file->buffer) +15490 # +15491 (write _test-input-stream "fn foo {\n") +15492 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n") +15493 (write _test-input-stream " var y/xmm4: float <- convert *x\n") +15494 (write _test-input-stream "}\n") +15495 # convert +15496 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) +15497 (flush _test-output-buffered-file) +15498 # no errors +15499 # . epilogue +15500 5d/pop-to-ebp +15501 c3/return +15502 +15503 test-convert-to-non-register: +15504 # . prologue +15505 55/push-ebp +15506 89/<- %ebp 4/r32/esp +15507 # setup +15508 (clear-stream _test-input-stream) +15509 (clear-stream $_test-input-buffered-file->buffer) +15510 (clear-stream _test-output-stream) +15511 (clear-stream $_test-output-buffered-file->buffer) +15512 (clear-stream _test-error-stream) +15513 (clear-stream $_test-error-buffered-file->buffer) +15514 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15515 68/push 0/imm32 +15516 68/push 0/imm32 +15517 89/<- %edx 4/r32/esp +15518 (tailor-exit-descriptor %edx 0x10) +15519 # +15520 (write _test-input-stream "fn foo {\n") +15521 (write _test-input-stream " var x: float\n") +15522 (write _test-input-stream " var y: int\n") +15523 (write _test-input-stream " x <- convert y\n") +15524 (write _test-input-stream "}\n") +15525 # convert +15526 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15527 # registers except esp clobbered at this point +15528 # restore ed +15529 89/<- %edx 4/r32/esp +15530 (flush _test-output-buffered-file) +15531 (flush _test-error-buffered-file) +15532 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15538 # check output +15539 (check-stream-equal _test-output-stream "" "F - test-convert-to-non-register: output should be empty") +15540 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: output 'x' not in a register" "F - test-convert-to-non-register: error message") +15541 # check that stop(1) was called +15542 (check-ints-equal *(edx+4) 2 "F - test-convert-to-non-register: exit status") +15543 # don't restore from ebp +15544 81 0/subop/add %esp 8/imm32 +15545 # . epilogue +15546 5d/pop-to-ebp +15547 c3/return +15548 +15549 test-convert-invalid-inout-type: +15550 # . prologue +15551 55/push-ebp +15552 89/<- %ebp 4/r32/esp +15553 # setup +15554 (clear-stream _test-input-stream) +15555 (clear-stream $_test-input-buffered-file->buffer) +15556 (clear-stream _test-output-stream) +15557 (clear-stream $_test-output-buffered-file->buffer) +15558 (clear-stream _test-error-stream) +15559 (clear-stream $_test-error-buffered-file->buffer) +15560 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15561 68/push 0/imm32 +15562 68/push 0/imm32 +15563 89/<- %edx 4/r32/esp +15564 (tailor-exit-descriptor %edx 0x10) +15565 # +15566 (write _test-input-stream "fn foo {\n") +15567 (write _test-input-stream " var x: boolean\n") +15568 (write _test-input-stream " var y/xmm1: float <- convert x\n") +15569 (write _test-input-stream "}\n") +15570 # convert +15571 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15572 # registers except esp clobbered at this point +15573 # restore ed +15574 89/<- %edx 4/r32/esp +15575 (flush _test-output-buffered-file) +15576 (flush _test-error-buffered-file) +15577 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15583 # check output +15584 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-inout-type: output should be empty") +15585 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: inout 'x' must be an int or float" "F - test-convert-invalid-inout-type: error message") +15586 # check that stop(1) was called +15587 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-inout-type: exit status") +15588 # don't restore from ebp +15589 81 0/subop/add %esp 8/imm32 +15590 # . epilogue +15591 5d/pop-to-ebp +15592 c3/return +15593 +15594 test-convert-invalid-output-type: +15595 # . prologue +15596 55/push-ebp +15597 89/<- %ebp 4/r32/esp +15598 # setup +15599 (clear-stream _test-input-stream) +15600 (clear-stream $_test-input-buffered-file->buffer) +15601 (clear-stream _test-output-stream) +15602 (clear-stream $_test-output-buffered-file->buffer) +15603 (clear-stream _test-error-stream) +15604 (clear-stream $_test-error-buffered-file->buffer) +15605 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15606 68/push 0/imm32 +15607 68/push 0/imm32 +15608 89/<- %edx 4/r32/esp +15609 (tailor-exit-descriptor %edx 0x10) +15610 # +15611 (write _test-input-stream "fn foo {\n") +15612 (write _test-input-stream " var x: float\n") +15613 (write _test-input-stream " var y/eax: boolean <- convert x\n") +15614 (write _test-input-stream "}\n") +15615 # convert +15616 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15617 # registers except esp clobbered at this point +15618 # restore ed +15619 89/<- %edx 4/r32/esp +15620 (flush _test-output-buffered-file) +15621 (flush _test-error-buffered-file) +15622 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15628 # check output +15629 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-output-type: output should be empty") +15630 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: output 'y' must be an int or float" "F - test-convert-invalid-output-type: error message") +15631 # check that stop(1) was called +15632 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-output-type: exit status") +15633 # don't restore from ebp +15634 81 0/subop/add %esp 8/imm32 +15635 # . epilogue +15636 5d/pop-to-ebp +15637 c3/return +15638 +15639 test-convert-int-to-int: +15640 # . prologue +15641 55/push-ebp +15642 89/<- %ebp 4/r32/esp +15643 # setup +15644 (clear-stream _test-input-stream) +15645 (clear-stream $_test-input-buffered-file->buffer) +15646 (clear-stream _test-output-stream) +15647 (clear-stream $_test-output-buffered-file->buffer) +15648 (clear-stream _test-error-stream) +15649 (clear-stream $_test-error-buffered-file->buffer) +15650 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15651 68/push 0/imm32 +15652 68/push 0/imm32 +15653 89/<- %edx 4/r32/esp +15654 (tailor-exit-descriptor %edx 0x10) +15655 # +15656 (write _test-input-stream "fn foo {\n") +15657 (write _test-input-stream " var x: int\n") +15658 (write _test-input-stream " var y/eax: int <- convert x\n") +15659 (write _test-input-stream "}\n") +15660 # convert +15661 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15662 # registers except esp clobbered at this point +15663 # restore ed +15664 89/<- %edx 4/r32/esp +15665 (flush _test-output-buffered-file) +15666 (flush _test-error-buffered-file) +15667 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15673 # check output +15674 (check-stream-equal _test-output-stream "" "F - test-convert-int-to-int: output should be empty") +15675 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: no need to convert int to int" "F - test-convert-int-to-int: error message") +15676 # check that stop(1) was called +15677 (check-ints-equal *(edx+4) 2 "F - test-convert-int-to-int: exit status") +15678 # don't restore from ebp +15679 81 0/subop/add %esp 8/imm32 +15680 # . epilogue +15681 5d/pop-to-ebp +15682 c3/return +15683 +15684 test-convert-float-to-float: +15685 # . prologue +15686 55/push-ebp +15687 89/<- %ebp 4/r32/esp +15688 # setup +15689 (clear-stream _test-input-stream) +15690 (clear-stream $_test-input-buffered-file->buffer) +15691 (clear-stream _test-output-stream) +15692 (clear-stream $_test-output-buffered-file->buffer) +15693 (clear-stream _test-error-stream) +15694 (clear-stream $_test-error-buffered-file->buffer) +15695 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) +15696 68/push 0/imm32 +15697 68/push 0/imm32 +15698 89/<- %edx 4/r32/esp +15699 (tailor-exit-descriptor %edx 0x10) +15700 # +15701 (write _test-input-stream "fn foo {\n") +15702 (write _test-input-stream " var x: float\n") +15703 (write _test-input-stream " var y/xmm6: float <- convert x\n") +15704 (write _test-input-stream "}\n") +15705 # convert +15706 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) +15707 # registers except esp clobbered at this point +15708 # restore ed +15709 89/<- %edx 4/r32/esp +15710 (flush _test-output-buffered-file) +15711 (flush _test-error-buffered-file) +15712 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ +15718 # check output +15719 (check-stream-equal _test-output-stream "" "F - test-convert-float-to-float: output should be empty") +15720 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: no need to convert float to float" "F - test-convert-float-to-float: error message") +15721 # check that stop(1) was called +15722 (check-ints-equal *(edx+4) 2 "F - test-convert-float-to-float: exit status") +15723 # don't restore from ebp +15724 81 0/subop/add %esp 8/imm32 +15725 # . epilogue +15726 5d/pop-to-ebp +15727 c3/return +15728 +15729 ####################################################### +15730 # Parsing +15731 ####################################################### +15732 +15733 == data +15734 +15735 # Global state added to each var record when parsing a function +15736 Next-block-index: # (addr int) +15737 1/imm32 +15738 +15739 Curr-block-depth: # (addr int) +15740 1/imm32 +15741 +15742 == code +15743 +15744 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) +15745 # pseudocode +15746 # var curr-function: (addr handle function) = Program->functions +15747 # var curr-signature: (addr handle function) = Program->signatures +15748 # var curr-type: (addr handle typeinfo) = Program->types +15749 # var line: (stream byte 512) +15750 # var word-slice: slice +15751 # while true # line loop +15752 # clear-stream(line) +15753 # read-line-buffered(in, line) +15754 # if (line->write == 0) break # end of file +15755 # word-slice = next-mu-token(line) +15756 # if slice-empty?(word-slice) # end of line +15757 # continue +15758 # else if slice-starts-with?(word-slice, "#") # comment +15759 # continue # end of line +15760 # else if slice-equal?(word-slice, "fn") +15761 # var new-function: (handle function) = allocate(function) +15762 # var vars: (stack live-var 256) +15763 # populate-mu-function-header(line, new-function, vars) +15764 # populate-mu-function-body(in, new-function, vars) +15765 # assert(vars->top == 0) +15766 # *curr-function = new-function +15767 # curr-function = &new-function->next +15768 # else if slice-equal?(word-slice, "sig") +15769 # var new-function: (handle function) = allocate(function) +15770 # populate-mu-function-signature(line, new-function) +15771 # *curr-signature = new-function +15772 # curr-signature = &new-function->next +15773 # else if slice-equal?(word-slice, "type") +15774 # word-slice = next-mu-token(line) +15775 # type-id = pos-or-insert-slice(Type-id, word-slice) +15776 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) +15777 # assert(next-word(line) == "{") +15778 # populate-mu-type(in, new-type) +15779 # else +15780 # abort() +15781 # +15782 # . prologue +15783 55/push-ebp +15784 89/<- %ebp 4/r32/esp +15785 # var curr-signature: (addr handle function) at *(ebp-4) +15786 68/push _Program-signatures/imm32 +15787 # . save registers +15788 50/push-eax +15789 51/push-ecx +15790 52/push-edx +15791 53/push-ebx +15792 56/push-esi +15793 57/push-edi +15794 # var line/ecx: (stream byte 512) +15795 81 5/subop/subtract %esp 0x200/imm32 +15796 68/push 0x200/imm32/size +15797 68/push 0/imm32/read +15798 68/push 0/imm32/write +15799 89/<- %ecx 4/r32/esp +15800 # var word-slice/edx: slice +15801 68/push 0/imm32/end +15802 68/push 0/imm32/start +15803 89/<- %edx 4/r32/esp +15804 # var curr-function/edi: (addr handle function) +15805 bf/copy-to-edi _Program-functions/imm32 +15806 # var vars/ebx: (stack live-var 256) +15807 81 5/subop/subtract %esp 0xc00/imm32 +15808 68/push 0xc00/imm32/size +15809 68/push 0/imm32/top +15810 89/<- %ebx 4/r32/esp +15811 { +15812 $parse-mu:line-loop: +15813 (clear-stream %ecx) +15814 (read-line-buffered *(ebp+8) %ecx) +15815 # if (line->write == 0) break +15816 81 7/subop/compare *ecx 0/imm32 +15817 0f 84/jump-if-= break/disp32 +15818 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ +15824 (next-mu-token %ecx %edx) +15825 # if slice-empty?(word-slice) continue +15826 (slice-empty? %edx) # => eax +15827 3d/compare-eax-and 0/imm32/false +15828 0f 85/jump-if-!= loop/disp32 +15829 # if (*word-slice->start == "#") continue +15830 # . eax = *word-slice->start +15831 8b/-> *edx 0/r32/eax +15832 8a/copy-byte *eax 0/r32/AL +15833 25/and-eax-with 0xff/imm32 +15834 # . if (eax == '#') continue +15835 3d/compare-eax-and 0x23/imm32/hash +15836 0f 84/jump-if-= loop/disp32 +15837 # if (slice-equal?(word-slice, "fn")) parse a function +15838 { +15839 $parse-mu:fn: +15840 (slice-equal? %edx "fn") # => eax +15841 3d/compare-eax-and 0/imm32/false +15842 0f 84/jump-if-= break/disp32 +15843 # var new-function/esi: (handle function) +15844 68/push 0/imm32 +15845 68/push 0/imm32 +15846 89/<- %esi 4/r32/esp +15847 # populate-mu-function(line, in, vars, new-function) +15848 (allocate Heap *Function-size %esi) +15849 # var new-function-addr/eax: (addr function) +15850 (lookup *esi *(esi+4)) # => eax +15851 # initialize vars +15852 (clear-stack %ebx) +15853 # +15854 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10)) +15855 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10)) +15856 # *curr-function = new-function +15857 8b/-> *esi 0/r32/eax +15858 89/<- *edi 0/r32/eax +15859 8b/-> *(esi+4) 0/r32/eax +15860 89/<- *(edi+4) 0/r32/eax +15861 # curr-function = &new-function->next +15862 # . var tmp/eax: (addr function) = lookup(new-function) +15863 (lookup *esi *(esi+4)) # => eax +15864 # . curr-function = &tmp->next +15865 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next +15866 # reclaim new-function +15867 81 0/subop/add %esp 8/imm32 +15868 # +15869 e9/jump $parse-mu:line-loop/disp32 +15870 } +15871 # if (slice-equal?(word-slice, "sig")) parse a function signature +15872 # Function signatures are for providing types to SubX functions. +15873 { +15874 $parse-mu:sig: +15875 (slice-equal? %edx "sig") # => eax +15876 3d/compare-eax-and 0/imm32/false +15877 0f 84/jump-if-= break/disp32 +15878 # edi = curr-function +15879 57/push-edi +15880 8b/-> *(ebp-4) 7/r32/edi +15881 # var new-function/esi: (handle function) +15882 68/push 0/imm32 +15883 68/push 0/imm32 +15884 89/<- %esi 4/r32/esp +15885 # populate-mu-function(line, in, vars, new-function) +15886 (allocate Heap *Function-size %esi) +15887 # var new-function-addr/eax: (addr function) +15888 (lookup *esi *(esi+4)) # => eax +15889 # +15890 (populate-mu-function-signature %ecx %eax *(ebp+0xc) *(ebp+0x10)) +15891 # *curr-signature = new-function +15892 8b/-> *esi 0/r32/eax +15893 89/<- *edi 0/r32/eax +15894 8b/-> *(esi+4) 0/r32/eax +15895 89/<- *(edi+4) 0/r32/eax +15896 # curr-signature = &new-function->next +15897 # . var tmp/eax: (addr function) = lookup(new-function) +15898 (lookup *esi *(esi+4)) # => eax +15899 # . curr-function = &tmp->next +15900 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next +15901 # reclaim new-function +15902 81 0/subop/add %esp 8/imm32 +15903 # save curr-function +15904 89/<- *(ebp-4) 7/r32/edi +15905 # restore edi +15906 5f/pop-to-edi +15907 # +15908 e9/jump $parse-mu:line-loop/disp32 +15909 } +15910 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition +15911 { +15912 $parse-mu:type: +15913 (slice-equal? %edx "type") # => eax +15914 3d/compare-eax-and 0/imm32 +15915 0f 84/jump-if-= break/disp32 +15916 (next-mu-token %ecx %edx) +15917 # var type-id/eax: int +15918 (pos-or-insert-slice Type-id %edx) # => eax +15919 # spill +15920 51/push-ecx +15921 # var new-type/ecx: (handle typeinfo) +15922 68/push 0/imm32 +15923 68/push 0/imm32 +15924 89/<- %ecx 4/r32/esp +15925 (find-or-create-typeinfo %eax %ecx) +15926 # +15927 (lookup *ecx *(ecx+4)) # => eax +15928 # TODO: ensure that 'line' has nothing else but '{' +15929 #? (dump-typeinfos "=== aaa\n") +15930 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax +15931 #? (dump-typeinfos "=== zzz\n") +15932 # reclaim new-type +15933 81 0/subop/add %esp 8/imm32 +15934 # restore +15935 59/pop-to-ecx +15936 e9/jump $parse-mu:line-loop/disp32 +15937 } +15938 # otherwise abort +15939 e9/jump $parse-mu:error1/disp32 +15940 } # end line loop +15941 $parse-mu:end: +15942 # . reclaim locals +15943 81 0/subop/add %esp 0x20c/imm32 # line +15944 81 0/subop/add %esp 0xc08/imm32 # vars +15945 81 0/subop/add %esp 8/imm32 +15946 # . restore registers +15947 5f/pop-to-edi +15948 5e/pop-to-esi +15949 5b/pop-to-ebx +15950 5a/pop-to-edx +15951 59/pop-to-ecx +15952 58/pop-to-eax +15953 # . reclaim local +15954 81 0/subop/add %esp 4/imm32 +15955 # . epilogue +15956 89/<- %esp 5/r32/ebp +15957 5d/pop-to-ebp +15958 c3/return +15959 +15960 $parse-mu:error1: +15961 # error("unexpected top-level command: " word-slice "\n") +15962 (write-buffered *(ebp+0xc) "unexpected top-level command: ") +15963 (write-slice-buffered *(ebp+0xc) %edx) +15964 (write-buffered *(ebp+0xc) "\n") +15965 (flush *(ebp+0xc)) +15966 (stop *(ebp+0x10) 1) +15967 # never gets here +15968 +15969 $parse-mu:error2: +15970 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") +15971 (write-int32-hex-buffered *(ebp+0xc) *ebx) +15972 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '") +15973 (write-slice-buffered *(ebp+0xc) *eax) # Function-name +15974 (write-buffered *(ebp+0xc) "'\n") +15975 (flush *(ebp+0xc)) +15976 (stop *(ebp+0x10) 1) +15977 # never gets here +15978 +15979 # scenarios considered: +15980 # ✗ fn foo # no block +15981 # ✓ fn foo { +15982 # ✗ fn foo { { +15983 # ✗ fn foo { } +15984 # ✗ fn foo { } { +15985 # ✗ fn foo x { +15986 # ✗ fn foo x: { +15987 # ✓ fn foo x: int { +15988 # ✓ fn foo x: int { +15989 # ✓ fn foo x: int -> _/eax: int { +15990 # TODO: +15991 # disallow outputs of type `(... addr ...)` +15992 # disallow inputs of type `(... addr ... addr ...)` +15993 populate-mu-function-header: # first-line: (addr stream byte), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) +15994 # pseudocode: +15995 # var word-slice: slice +15996 # next-mu-token(first-line, word-slice) +15997 # if slice-empty?(word-slice) abort +15998 # assert(word-slice not in '{' '}' '->') +15999 # out->name = slice-to-string(word-slice) +16000 # ## inouts +16001 # while true +16002 # word-slice = next-mu-token(first-line) +16003 # if slice-empty?(word-slice) abort +16004 # if (word-slice == '{') goto done +16005 # if (word-slice == '->') break +16006 # assert(word-slice != '}') +16007 # var v: (handle var) = parse-var-with-type(word-slice, first-line) +16008 # assert(v->register == null) +16009 # # v->block-depth is implicitly 0 +16010 # out->inouts = append(v, out->inouts) +16011 # push(vars, {v, false}) +16012 # ## outputs +16013 # while true +16014 # word-slice = next-mu-token(first-line) +16015 # if slice-empty?(word-slice) abort +16016 # if (word-slice == '{') break +16017 # assert(word-slice not in '}' '->') +16018 # var v: (handle var) = parse-var-with-type(word-slice, first-line) +16019 # assert(v->register != null) +16020 # assert(v->name == "_") +16021 # out->outputs = append(v, out->outputs) +16022 # done: +16023 # +16024 # . prologue +16025 55/push-ebp +16026 89/<- %ebp 4/r32/esp +16027 # . save registers +16028 50/push-eax +16029 51/push-ecx +16030 52/push-edx +16031 53/push-ebx +16032 57/push-edi +16033 # edi = out +16034 8b/-> *(ebp+0xc) 7/r32/edi +16035 # var word-slice/ecx: slice +16036 68/push 0/imm32/end +16037 68/push 0/imm32/start +16038 89/<- %ecx 4/r32/esp +16039 # var v/ebx: (handle var) +16040 68/push 0/imm32 +16041 68/push 0/imm32 +16042 89/<- %ebx 4/r32/esp +16043 # read function name +16044 (next-mu-token *(ebp+8) %ecx) +16045 # error checking +16046 # if slice-empty?(word-slice) abort +16047 (slice-empty? %ecx) # => eax 16048 3d/compare-eax-and 0/imm32/false -16049 0f 85/jump-if-!= $populate-mu-function-header:error-loop/disp32 -16050 (slice-equal? %ecx "lookup") # => eax -16051 3d/compare-eax-and 0/imm32/false -16052 0f 85/jump-if-!= $populate-mu-function-header:error-lookup/disp32 -16053 # save function name -16054 (slice-to-string Heap %ecx %edi) # Function-name -16055 # save function inouts -16056 { -16057 $populate-mu-function-header:check-for-inout: -16058 (next-mu-token *(ebp+8) %ecx) -16059 # if slice-empty?(word-slice) abort -16060 (slice-empty? %ecx) # => eax -16061 3d/compare-eax-and 0/imm32/false -16062 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16063 # if (word-slice == '{') goto done -16064 (slice-equal? %ecx "{") # => eax -16065 3d/compare-eax-and 0/imm32/false -16066 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 -16067 # if (word-slice == '->') break -16068 (slice-equal? %ecx "->") # => eax -16069 3d/compare-eax-and 0/imm32/false -16070 0f 85/jump-if-!= break/disp32 -16071 # if (word-slice == '}') abort -16072 (slice-equal? %ecx "}") # => eax -16073 3d/compare-eax-and 0/imm32/false -16074 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16075 # v = parse-var-with-type(word-slice, first-line) -16076 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16077 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x14) *(ebp+0x18)) -16078 # if (v->register != null) abort -16079 # . eax: (addr var) = lookup(v) -16080 (lookup *ebx *(ebx+4)) # => eax -16081 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -16082 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 -16083 # if function name is not "main" -16084 # and v->type contains an 'addr' anywhere except the start, abort -16085 { -16086 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16087 (string-equal? %eax "main") # => eax -16088 3d/compare-eax-and 0/imm32/false -16089 75/jump-if-!= break/disp8 -16090 (lookup *ebx *(ebx+4)) # => eax -16091 (addr-payload-contains-addr? %eax) # => eax -16092 3d/compare-eax-and 0/imm32/false -16093 0f 85/jump-if-!= $populate-mu-function-header:error-nested-addr-inout/disp32 -16094 } -16095 # v->block-depth is implicitly 0 -16096 # -16097 # out->inouts = append(v, out->inouts) -16098 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts -16099 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts -16100 # push(vars, {v, false}) -16101 (push *(ebp+0x10) *ebx) -16102 (push *(ebp+0x10) *(ebx+4)) -16103 (push *(ebp+0x10) 0) # false -16104 # -16105 e9/jump loop/disp32 -16106 } -16107 # save function outputs -16108 { -16109 $populate-mu-function-header:check-for-out: -16110 (next-mu-token *(ebp+8) %ecx) -16111 # if slice-empty?(word-slice) abort -16112 (slice-empty? %ecx) # => eax -16113 3d/compare-eax-and 0/imm32/false -16114 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16115 # if (word-slice == '{') break -16116 (slice-equal? %ecx "{") # => eax -16117 3d/compare-eax-and 0/imm32/false -16118 0f 85/jump-if-!= break/disp32 -16119 # if (word-slice == '->') abort -16120 (slice-equal? %ecx "->") # => eax -16121 3d/compare-eax-and 0/imm32/false -16122 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16123 # if (word-slice == '}') abort -16124 (slice-equal? %ecx "}") # => eax -16125 3d/compare-eax-and 0/imm32/false -16126 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 -16127 # v = parse-var-with-type(word-slice, first-line) -16128 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16129 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x14) *(ebp+0x18)) -16130 # assert(var->register != null) -16131 # . eax: (addr var) = lookup(v) -16132 (lookup *ebx *(ebx+4)) # => eax -16133 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -16134 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 -16135 # if (var->name != "_") abort -16136 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16137 (string-equal? %eax "_") # => eax -16138 3d/compare-eax-and 0/imm32/false -16139 0f 84/jump-if-= $populate-mu-function-header:error4/disp32 -16140 # if v->type is an addr, abort -16141 (lookup *ebx *(ebx+4)) # => eax -16142 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -16143 (mu-addr-type? %eax) # => eax +16049 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16050 # if (word-slice == '{') abort +16051 (slice-equal? %ecx "{") # => eax +16052 3d/compare-eax-and 0/imm32/false +16053 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16054 # if (word-slice == '->') abort +16055 (slice-equal? %ecx "->") # => eax +16056 3d/compare-eax-and 0/imm32/false +16057 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16058 # if (word-slice == '}') abort +16059 (slice-equal? %ecx "}") # => eax +16060 3d/compare-eax-and 0/imm32/false +16061 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16062 # if word-slice already defined, abort +16063 (function-exists? %ecx) # => eax +16064 3d/compare-eax-and 0/imm32/false +16065 0f 85/jump-if-!= $populate-mu-function-header:error-duplicate/disp32 +16066 # +16067 (slice-starts-with? %ecx "break") # => eax +16068 3d/compare-eax-and 0/imm32/false +16069 0f 85/jump-if-!= $populate-mu-function-header:error-break/disp32 +16070 (slice-starts-with? %ecx "loop") # => eax +16071 3d/compare-eax-and 0/imm32/false +16072 0f 85/jump-if-!= $populate-mu-function-header:error-loop/disp32 +16073 (slice-equal? %ecx "lookup") # => eax +16074 3d/compare-eax-and 0/imm32/false +16075 0f 85/jump-if-!= $populate-mu-function-header:error-lookup/disp32 +16076 # save function name +16077 (slice-to-string Heap %ecx %edi) # Function-name +16078 # save function inouts +16079 { +16080 $populate-mu-function-header:check-for-inout: +16081 (next-mu-token *(ebp+8) %ecx) +16082 # if slice-empty?(word-slice) abort +16083 (slice-empty? %ecx) # => eax +16084 3d/compare-eax-and 0/imm32/false +16085 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16086 # if (word-slice == '{') goto done +16087 (slice-equal? %ecx "{") # => eax +16088 3d/compare-eax-and 0/imm32/false +16089 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 +16090 # if (word-slice == '->') break +16091 (slice-equal? %ecx "->") # => eax +16092 3d/compare-eax-and 0/imm32/false +16093 0f 85/jump-if-!= break/disp32 +16094 # if (word-slice == '}') abort +16095 (slice-equal? %ecx "}") # => eax +16096 3d/compare-eax-and 0/imm32/false +16097 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16098 # v = parse-var-with-type(word-slice, first-line) +16099 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16100 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x14) *(ebp+0x18)) +16101 # if (v->register != null) abort +16102 # . eax: (addr var) = lookup(v) +16103 (lookup *ebx *(ebx+4)) # => eax +16104 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +16105 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 +16106 # if function name is not "main" +16107 # and v->type contains an 'addr' anywhere except the start, abort +16108 { +16109 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16110 (string-equal? %eax "main") # => eax +16111 3d/compare-eax-and 0/imm32/false +16112 75/jump-if-!= break/disp8 +16113 (lookup *ebx *(ebx+4)) # => eax +16114 (addr-payload-contains-addr? %eax) # => eax +16115 3d/compare-eax-and 0/imm32/false +16116 0f 85/jump-if-!= $populate-mu-function-header:error-nested-addr-inout/disp32 +16117 } +16118 # v->block-depth is implicitly 0 +16119 # +16120 # out->inouts = append(v, out->inouts) +16121 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts +16122 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts +16123 # push(vars, {v, false}) +16124 (push *(ebp+0x10) *ebx) +16125 (push *(ebp+0x10) *(ebx+4)) +16126 (push *(ebp+0x10) 0) # false +16127 # +16128 e9/jump loop/disp32 +16129 } +16130 # save function outputs +16131 { +16132 $populate-mu-function-header:check-for-out: +16133 (next-mu-token *(ebp+8) %ecx) +16134 # if slice-empty?(word-slice) abort +16135 (slice-empty? %ecx) # => eax +16136 3d/compare-eax-and 0/imm32/false +16137 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16138 # if (word-slice == '{') break +16139 (slice-equal? %ecx "{") # => eax +16140 3d/compare-eax-and 0/imm32/false +16141 0f 85/jump-if-!= break/disp32 +16142 # if (word-slice == '->') abort +16143 (slice-equal? %ecx "->") # => eax 16144 3d/compare-eax-and 0/imm32/false -16145 0f 85/jump-if-!= $populate-mu-function-header:error-addr-output/disp32 -16146 # out->outputs = append(v, out->outputs) -16147 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs -16148 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs -16149 # -16150 e9/jump loop/disp32 -16151 } -16152 $populate-mu-function-header:done: -16153 (check-no-tokens-left *(ebp+8)) -16154 $populate-mu-function-header:end: -16155 # . reclaim locals -16156 81 0/subop/add %esp 0x10/imm32 -16157 # . restore registers -16158 5f/pop-to-edi -16159 5b/pop-to-ebx -16160 5a/pop-to-edx -16161 59/pop-to-ecx -16162 58/pop-to-eax -16163 # . epilogue -16164 89/<- %esp 5/r32/ebp -16165 5d/pop-to-ebp -16166 c3/return -16167 -16168 $populate-mu-function-header:error1: -16169 # error("function header not in form 'fn <name> {'") -16170 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") -16171 (flush *(ebp+0x14)) -16172 (rewind-stream *(ebp+8)) -16173 (write-stream-data *(ebp+0x14) *(ebp+8)) -16174 (write-buffered *(ebp+0x14) "'\n") -16175 (flush *(ebp+0x14)) -16176 (stop *(ebp+0x18) 1) -16177 # never gets here -16178 -16179 $populate-mu-function-header:error2: -16180 # error("fn " fn ": function inout '" var "' cannot be in a register") -16181 (write-buffered *(ebp+0x14) "fn ") -16182 50/push-eax -16183 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16184 (write-buffered *(ebp+0x14) %eax) +16145 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16146 # if (word-slice == '}') abort +16147 (slice-equal? %ecx "}") # => eax +16148 3d/compare-eax-and 0/imm32/false +16149 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 +16150 # v = parse-var-with-type(word-slice, first-line) +16151 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16152 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x14) *(ebp+0x18)) +16153 # assert(var->register != null) +16154 # . eax: (addr var) = lookup(v) +16155 (lookup *ebx *(ebx+4)) # => eax +16156 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +16157 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 +16158 # if (var->name != "_") abort +16159 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16160 (string-equal? %eax "_") # => eax +16161 3d/compare-eax-and 0/imm32/false +16162 0f 84/jump-if-= $populate-mu-function-header:error4/disp32 +16163 # if v->type is an addr, abort +16164 (lookup *ebx *(ebx+4)) # => eax +16165 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +16166 (mu-addr-type? %eax) # => eax +16167 3d/compare-eax-and 0/imm32/false +16168 0f 85/jump-if-!= $populate-mu-function-header:error-addr-output/disp32 +16169 # out->outputs = append(v, out->outputs) +16170 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs +16171 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs +16172 # +16173 e9/jump loop/disp32 +16174 } +16175 $populate-mu-function-header:done: +16176 (check-no-tokens-left *(ebp+8)) +16177 $populate-mu-function-header:end: +16178 # . reclaim locals +16179 81 0/subop/add %esp 0x10/imm32 +16180 # . restore registers +16181 5f/pop-to-edi +16182 5b/pop-to-ebx +16183 5a/pop-to-edx +16184 59/pop-to-ecx 16185 58/pop-to-eax -16186 (write-buffered *(ebp+0x14) ": function inout '") -16187 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16188 (write-buffered *(ebp+0x14) %eax) -16189 (write-buffered *(ebp+0x14) "' cannot be in a register") -16190 (flush *(ebp+0x14)) -16191 (stop *(ebp+0x18) 1) -16192 # never gets here -16193 -16194 $populate-mu-function-header:error3: -16195 # error("fn " fn ": function output '" var "' must be in a register") -16196 (write-buffered *(ebp+0x14) "fn ") -16197 50/push-eax -16198 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16199 (write-buffered *(ebp+0x14) %eax) -16200 58/pop-to-eax -16201 (write-buffered *(ebp+0x14) ": function output '") -16202 (lookup *ebx *(ebx+4)) # => eax -16203 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16204 (write-buffered *(ebp+0x14) %eax) -16205 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '") -16206 (rewind-stream *(ebp+8)) -16207 (write-stream-data *(ebp+0x14) *(ebp+8)) -16208 (write-buffered *(ebp+0x14) "'\n") -16209 (flush *(ebp+0x14)) -16210 (stop *(ebp+0x18) 1) -16211 # never gets here -16212 -16213 $populate-mu-function-header:error4: -16214 # error("fn " fn ": function outputs cannot be named; rename '" var "' in the header to '_'") -16215 (write-buffered *(ebp+0x14) "fn ") -16216 50/push-eax -16217 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16218 (write-buffered *(ebp+0x14) %eax) -16219 58/pop-to-eax -16220 (write-buffered *(ebp+0x14) ": function outputs cannot be named; rename '") -16221 (lookup *ebx *(ebx+4)) # => eax -16222 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16223 (write-buffered *(ebp+0x14) %eax) -16224 (write-buffered *(ebp+0x14) "' in the header to '_'\n") -16225 (flush *(ebp+0x14)) -16226 (stop *(ebp+0x18) 1) -16227 # never gets here -16228 -16229 $populate-mu-function-header:error-duplicate: -16230 (write-buffered *(ebp+0x14) "fn ") -16231 (write-slice-buffered *(ebp+0x14) %ecx) -16232 (write-buffered *(ebp+0x14) " defined more than once\n") -16233 (flush *(ebp+0x14)) -16234 (stop *(ebp+0x18) 1) -16235 # never gets here -16236 -16237 $populate-mu-function-header:error-break: -16238 (write-buffered *(ebp+0x14) "Sorry, I've reserved all function names starting with 'break' for now. Please contact mu@akkartik.com.\n") -16239 (flush *(ebp+0x14)) -16240 (stop *(ebp+0x18) 1) -16241 # never gets here -16242 -16243 $populate-mu-function-header:error-loop: -16244 (write-buffered *(ebp+0x14) "Sorry, I've reserved all function names starting with 'loop' for now. Please contact mu@akkartik.com.\n") -16245 (flush *(ebp+0x14)) -16246 (stop *(ebp+0x18) 1) -16247 # never gets here -16248 -16249 $populate-mu-function-header:error-lookup: -16250 (write-buffered *(ebp+0x14) "cannot define a function called 'lookup'\n") -16251 (flush *(ebp+0x14)) -16252 (stop *(ebp+0x18) 1) -16253 # never gets here -16254 -16255 $populate-mu-function-header:error-addr-output: -16256 # error("fn " fn ": output cannot have an addr type; that could allow unsafe addresses to escape the function") -16257 (write-buffered *(ebp+0x14) "fn ") -16258 50/push-eax -16259 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16260 (write-buffered *(ebp+0x14) %eax) -16261 58/pop-to-eax -16262 (write-buffered *(ebp+0x14) ": output cannot have an addr type; that could allow unsafe addresses to escape the function\n") -16263 (flush *(ebp+0x14)) -16264 (stop *(ebp+0x18) 1) -16265 # never gets here -16266 -16267 $populate-mu-function-header:error-nested-addr-inout: -16268 # error("fn " fn ": inout '" var "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function") -16269 (write-buffered *(ebp+0x14) "fn ") -16270 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16271 (write-buffered *(ebp+0x14) %eax) -16272 (write-buffered *(ebp+0x14) ": inout '") -16273 (lookup *ebx *(ebx+4)) # => eax -16274 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16275 (write-buffered *(ebp+0x14) %eax) -16276 (write-buffered *(ebp+0x14) "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function\n") -16277 (flush *(ebp+0x14)) -16278 (stop *(ebp+0x18) 1) -16279 # never gets here -16280 -16281 # scenarios considered: -16282 # ✓ fn foo -16283 # ✗ fn foo { -16284 # ✓ fn foo x -16285 # ✓ fn foo x: int -16286 # ✓ fn foo x: int -> _/eax: int -16287 # TODO: -16288 # disallow outputs of type `(... addr ...)` -16289 # disallow inputs of type `(... addr ... addr ...)` -16290 populate-mu-function-signature: # first-line: (addr stream byte), out: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -16291 # pseudocode: -16292 # var word-slice: slice -16293 # next-mu-token(first-line, word-slice) -16294 # assert(word-slice not in '{' '}' '->') -16295 # out->name = slice-to-string(word-slice) -16296 # ## inouts -16297 # while true -16298 # word-slice = next-mu-token(first-line) -16299 # if slice-empty?(word-slice) break -16300 # if (word-slice == '->') break -16301 # assert(word-slice not in '{' '}') -16302 # var v: (handle var) = parse-var-with-type(word-slice, first-line) -16303 # assert(v->register == null) -16304 # # v->block-depth is implicitly 0 -16305 # out->inouts = append(v, out->inouts) -16306 # ## outputs -16307 # while true -16308 # word-slice = next-mu-token(first-line) -16309 # if slice-empty?(word-slice) break -16310 # assert(word-slice not in '{' '}' '->') -16311 # var v: (handle var) = parse-var-with-type(word-slice, first-line) -16312 # assert(v->register != null) -16313 # out->outputs = append(v, out->outputs) -16314 # -16315 # . prologue -16316 55/push-ebp -16317 89/<- %ebp 4/r32/esp -16318 # . save registers -16319 50/push-eax -16320 51/push-ecx -16321 52/push-edx -16322 53/push-ebx -16323 57/push-edi -16324 # edi = out -16325 8b/-> *(ebp+0xc) 7/r32/edi -16326 # var word-slice/ecx: slice -16327 68/push 0/imm32/end -16328 68/push 0/imm32/start -16329 89/<- %ecx 4/r32/esp -16330 # var v/ebx: (handle var) -16331 68/push 0/imm32 -16332 68/push 0/imm32 -16333 89/<- %ebx 4/r32/esp -16334 # read function name -16335 (next-mu-token *(ebp+8) %ecx) -16336 # error checking -16337 # if (word-slice == '{') abort -16338 (slice-equal? %ecx "{") # => eax -16339 3d/compare-eax-and 0/imm32/false -16340 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 -16341 # if (word-slice == '->') abort -16342 (slice-equal? %ecx "->") # => eax -16343 3d/compare-eax-and 0/imm32/false -16344 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 -16345 # if (word-slice == '}') abort -16346 (slice-equal? %ecx "}") # => eax -16347 3d/compare-eax-and 0/imm32/false -16348 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 -16349 # if word-slice already defined, abort -16350 (function-exists? %ecx) # => eax -16351 3d/compare-eax-and 0/imm32/false -16352 0f 85/jump-if-!= $populate-mu-function-signature:error-duplicate/disp32 -16353 # -16354 (slice-starts-with? %ecx "break") # => eax -16355 3d/compare-eax-and 0/imm32/false -16356 0f 85/jump-if-!= $populate-mu-function-signature:error-break/disp32 -16357 (slice-starts-with? %ecx "loop") # => eax -16358 3d/compare-eax-and 0/imm32/false -16359 0f 85/jump-if-!= $populate-mu-function-signature:error-loop/disp32 -16360 # save function name -16361 (slice-to-string Heap %ecx %edi) # Function-name -16362 # save function inouts -16363 { -16364 $populate-mu-function-signature:check-for-inout: -16365 (next-mu-token *(ebp+8) %ecx) -16366 (slice-empty? %ecx) # => eax -16367 3d/compare-eax-and 0/imm32/false -16368 0f 85/jump-if-!= break/disp32 -16369 # if (word-slice == '->') break -16370 (slice-equal? %ecx "->") # => eax -16371 3d/compare-eax-and 0/imm32/false -16372 0f 85/jump-if-!= break/disp32 -16373 # if (word-slice == '{') abort -16374 (slice-equal? %ecx "{") # => eax -16375 3d/compare-eax-and 0/imm32/false -16376 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 -16377 # if (word-slice == '}') abort -16378 (slice-equal? %ecx "}") # => eax -16379 3d/compare-eax-and 0/imm32/false -16380 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 -16381 # v = parse-var-with-type(word-slice, first-line) -16382 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16383 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x10) *(ebp+0x14)) -16384 # if (v->register != null) abort -16385 # . eax: (addr var) = lookup(v) -16386 (lookup *ebx *(ebx+4)) # => eax -16387 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -16388 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32 -16389 # if function name is not "main" -16390 # and v->type contains an 'addr' anywhere except the start, abort -16391 { -16392 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16393 (string-equal? %eax "main") # => eax -16394 3d/compare-eax-and 0/imm32/false -16395 75/jump-if-!= break/disp8 -16396 (lookup *ebx *(ebx+4)) # => eax -16397 (addr-payload-contains-addr? %eax) # => eax -16398 3d/compare-eax-and 0/imm32/false -16399 0f 85/jump-if-!= $populate-mu-function-signature:error-nested-addr-inout/disp32 -16400 } -16401 # assert(v->register == null) -16402 # . eax: (addr var) = lookup(v) -16403 (lookup *ebx *(ebx+4)) # => eax -16404 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -16405 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32 -16406 # v->block-depth is implicitly 0 -16407 # -16408 # out->inouts = append(v, out->inouts) -16409 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts -16410 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts -16411 # -16412 e9/jump loop/disp32 -16413 } -16414 # save function outputs -16415 { -16416 $populate-mu-function-signature:check-for-out: -16417 (next-mu-token *(ebp+8) %ecx) -16418 (slice-empty? %ecx) # => eax -16419 3d/compare-eax-and 0/imm32/false -16420 0f 85/jump-if-!= break/disp32 -16421 # if (word-slice == '{') abort -16422 (slice-equal? %ecx "{") # => eax -16423 3d/compare-eax-and 0/imm32/false -16424 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 -16425 # if (word-slice == '->') abort -16426 (slice-equal? %ecx "->") # => eax -16427 3d/compare-eax-and 0/imm32/false -16428 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 -16429 # if (word-slice == '}') abort -16430 (slice-equal? %ecx "}") # => eax -16431 3d/compare-eax-and 0/imm32/false -16432 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 -16433 # v = parse-var-with-type(word-slice, first-line) -16434 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16435 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x10) *(ebp+0x14)) -16436 # assert(var->register != null) -16437 # . eax: (addr var) = lookup(v) -16438 (lookup *ebx *(ebx+4)) # => eax -16439 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -16440 0f 84/jump-if-= $populate-mu-function-signature:error3/disp32 -16441 # if (var->name != "_") abort -16442 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16443 (string-equal? %eax "_") # => eax -16444 3d/compare-eax-and 0/imm32/false -16445 0f 84/jump-if-= $populate-mu-function-signature:error4/disp32 -16446 # if function name is not "lookup" -16447 # and v->type is an addr, abort -16448 { -16449 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16450 (string-equal? %eax "lookup") # => eax -16451 3d/compare-eax-and 0/imm32/false -16452 75/jump-if-!= break/disp8 -16453 (lookup *ebx *(ebx+4)) # => eax -16454 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -16455 (mu-addr-type? %eax) # => eax -16456 3d/compare-eax-and 0/imm32/false -16457 0f 85/jump-if-!= $populate-mu-function-signature:error-addr-output/disp32 -16458 } -16459 # out->outputs = append(v, out->outputs) -16460 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs -16461 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs -16462 # -16463 e9/jump loop/disp32 -16464 } -16465 $populate-mu-function-signature:done: -16466 (check-no-tokens-left *(ebp+8)) -16467 $populate-mu-function-signature:end: -16468 # . reclaim locals -16469 81 0/subop/add %esp 0x10/imm32 -16470 # . restore registers -16471 5f/pop-to-edi -16472 5b/pop-to-ebx -16473 5a/pop-to-edx -16474 59/pop-to-ecx -16475 58/pop-to-eax -16476 # . epilogue -16477 89/<- %esp 5/r32/ebp -16478 5d/pop-to-ebp -16479 c3/return -16480 -16481 $populate-mu-function-signature:error1: -16482 # error("function signature not in form 'fn <name> {'") -16483 (write-buffered *(ebp+0x10) "function signature not in form 'fn <name> [inouts] [-> outputs] {' -- '") -16484 (flush *(ebp+0x10)) -16485 (rewind-stream *(ebp+8)) -16486 (write-stream-data *(ebp+0x10) *(ebp+8)) -16487 (write-buffered *(ebp+0x10) "'\n") -16488 (flush *(ebp+0x10)) -16489 (stop *(ebp+0x14) 1) -16490 # never gets here -16491 -16492 $populate-mu-function-signature:error2: -16493 # error("fn " fn ": function inout '" var "' cannot be in a register") -16494 (write-buffered *(ebp+0x10) "fn ") -16495 50/push-eax -16496 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16497 (write-buffered *(ebp+0x10) %eax) +16186 # . epilogue +16187 89/<- %esp 5/r32/ebp +16188 5d/pop-to-ebp +16189 c3/return +16190 +16191 $populate-mu-function-header:error1: +16192 # error("function header not in form 'fn <name> {'") +16193 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") +16194 (flush *(ebp+0x14)) +16195 (rewind-stream *(ebp+8)) +16196 (write-stream-data *(ebp+0x14) *(ebp+8)) +16197 (write-buffered *(ebp+0x14) "'\n") +16198 (flush *(ebp+0x14)) +16199 (stop *(ebp+0x18) 1) +16200 # never gets here +16201 +16202 $populate-mu-function-header:error2: +16203 # error("fn " fn ": function inout '" var "' cannot be in a register") +16204 (write-buffered *(ebp+0x14) "fn ") +16205 50/push-eax +16206 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16207 (write-buffered *(ebp+0x14) %eax) +16208 58/pop-to-eax +16209 (write-buffered *(ebp+0x14) ": function inout '") +16210 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16211 (write-buffered *(ebp+0x14) %eax) +16212 (write-buffered *(ebp+0x14) "' cannot be in a register") +16213 (flush *(ebp+0x14)) +16214 (stop *(ebp+0x18) 1) +16215 # never gets here +16216 +16217 $populate-mu-function-header:error3: +16218 # error("fn " fn ": function output '" var "' must be in a register") +16219 (write-buffered *(ebp+0x14) "fn ") +16220 50/push-eax +16221 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16222 (write-buffered *(ebp+0x14) %eax) +16223 58/pop-to-eax +16224 (write-buffered *(ebp+0x14) ": function output '") +16225 (lookup *ebx *(ebx+4)) # => eax +16226 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16227 (write-buffered *(ebp+0x14) %eax) +16228 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '") +16229 (rewind-stream *(ebp+8)) +16230 (write-stream-data *(ebp+0x14) *(ebp+8)) +16231 (write-buffered *(ebp+0x14) "'\n") +16232 (flush *(ebp+0x14)) +16233 (stop *(ebp+0x18) 1) +16234 # never gets here +16235 +16236 $populate-mu-function-header:error4: +16237 # error("fn " fn ": function outputs cannot be named; rename '" var "' in the header to '_'") +16238 (write-buffered *(ebp+0x14) "fn ") +16239 50/push-eax +16240 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16241 (write-buffered *(ebp+0x14) %eax) +16242 58/pop-to-eax +16243 (write-buffered *(ebp+0x14) ": function outputs cannot be named; rename '") +16244 (lookup *ebx *(ebx+4)) # => eax +16245 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16246 (write-buffered *(ebp+0x14) %eax) +16247 (write-buffered *(ebp+0x14) "' in the header to '_'\n") +16248 (flush *(ebp+0x14)) +16249 (stop *(ebp+0x18) 1) +16250 # never gets here +16251 +16252 $populate-mu-function-header:error-duplicate: +16253 (write-buffered *(ebp+0x14) "fn ") +16254 (write-slice-buffered *(ebp+0x14) %ecx) +16255 (write-buffered *(ebp+0x14) " defined more than once\n") +16256 (flush *(ebp+0x14)) +16257 (stop *(ebp+0x18) 1) +16258 # never gets here +16259 +16260 $populate-mu-function-header:error-break: +16261 (write-buffered *(ebp+0x14) "Sorry, I've reserved all function names starting with 'break' for now. Please contact mu@akkartik.com.\n") +16262 (flush *(ebp+0x14)) +16263 (stop *(ebp+0x18) 1) +16264 # never gets here +16265 +16266 $populate-mu-function-header:error-loop: +16267 (write-buffered *(ebp+0x14) "Sorry, I've reserved all function names starting with 'loop' for now. Please contact mu@akkartik.com.\n") +16268 (flush *(ebp+0x14)) +16269 (stop *(ebp+0x18) 1) +16270 # never gets here +16271 +16272 $populate-mu-function-header:error-lookup: +16273 (write-buffered *(ebp+0x14) "cannot define a function called 'lookup'\n") +16274 (flush *(ebp+0x14)) +16275 (stop *(ebp+0x18) 1) +16276 # never gets here +16277 +16278 $populate-mu-function-header:error-addr-output: +16279 # error("fn " fn ": output cannot have an addr type; that could allow unsafe addresses to escape the function") +16280 (write-buffered *(ebp+0x14) "fn ") +16281 50/push-eax +16282 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16283 (write-buffered *(ebp+0x14) %eax) +16284 58/pop-to-eax +16285 (write-buffered *(ebp+0x14) ": output cannot have an addr type; that could allow unsafe addresses to escape the function\n") +16286 (flush *(ebp+0x14)) +16287 (stop *(ebp+0x18) 1) +16288 # never gets here +16289 +16290 $populate-mu-function-header:error-nested-addr-inout: +16291 # error("fn " fn ": inout '" var "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function") +16292 (write-buffered *(ebp+0x14) "fn ") +16293 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16294 (write-buffered *(ebp+0x14) %eax) +16295 (write-buffered *(ebp+0x14) ": inout '") +16296 (lookup *ebx *(ebx+4)) # => eax +16297 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16298 (write-buffered *(ebp+0x14) %eax) +16299 (write-buffered *(ebp+0x14) "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function\n") +16300 (flush *(ebp+0x14)) +16301 (stop *(ebp+0x18) 1) +16302 # never gets here +16303 +16304 # scenarios considered: +16305 # ✓ fn foo +16306 # ✗ fn foo { +16307 # ✓ fn foo x +16308 # ✓ fn foo x: int +16309 # ✓ fn foo x: int -> _/eax: int +16310 # TODO: +16311 # disallow outputs of type `(... addr ...)` +16312 # disallow inputs of type `(... addr ... addr ...)` +16313 populate-mu-function-signature: # first-line: (addr stream byte), out: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +16314 # pseudocode: +16315 # var word-slice: slice +16316 # next-mu-token(first-line, word-slice) +16317 # assert(word-slice not in '{' '}' '->') +16318 # out->name = slice-to-string(word-slice) +16319 # ## inouts +16320 # while true +16321 # word-slice = next-mu-token(first-line) +16322 # if slice-empty?(word-slice) break +16323 # if (word-slice == '->') break +16324 # assert(word-slice not in '{' '}') +16325 # var v: (handle var) = parse-var-with-type(word-slice, first-line) +16326 # assert(v->register == null) +16327 # # v->block-depth is implicitly 0 +16328 # out->inouts = append(v, out->inouts) +16329 # ## outputs +16330 # while true +16331 # word-slice = next-mu-token(first-line) +16332 # if slice-empty?(word-slice) break +16333 # assert(word-slice not in '{' '}' '->') +16334 # var v: (handle var) = parse-var-with-type(word-slice, first-line) +16335 # assert(v->register != null) +16336 # out->outputs = append(v, out->outputs) +16337 # +16338 # . prologue +16339 55/push-ebp +16340 89/<- %ebp 4/r32/esp +16341 # . save registers +16342 50/push-eax +16343 51/push-ecx +16344 52/push-edx +16345 53/push-ebx +16346 57/push-edi +16347 # edi = out +16348 8b/-> *(ebp+0xc) 7/r32/edi +16349 # var word-slice/ecx: slice +16350 68/push 0/imm32/end +16351 68/push 0/imm32/start +16352 89/<- %ecx 4/r32/esp +16353 # var v/ebx: (handle var) +16354 68/push 0/imm32 +16355 68/push 0/imm32 +16356 89/<- %ebx 4/r32/esp +16357 # read function name +16358 (next-mu-token *(ebp+8) %ecx) +16359 # error checking +16360 # if (word-slice == '{') abort +16361 (slice-equal? %ecx "{") # => eax +16362 3d/compare-eax-and 0/imm32/false +16363 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 +16364 # if (word-slice == '->') abort +16365 (slice-equal? %ecx "->") # => eax +16366 3d/compare-eax-and 0/imm32/false +16367 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 +16368 # if (word-slice == '}') abort +16369 (slice-equal? %ecx "}") # => eax +16370 3d/compare-eax-and 0/imm32/false +16371 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 +16372 # if word-slice already defined, abort +16373 (function-exists? %ecx) # => eax +16374 3d/compare-eax-and 0/imm32/false +16375 0f 85/jump-if-!= $populate-mu-function-signature:error-duplicate/disp32 +16376 # +16377 (slice-starts-with? %ecx "break") # => eax +16378 3d/compare-eax-and 0/imm32/false +16379 0f 85/jump-if-!= $populate-mu-function-signature:error-break/disp32 +16380 (slice-starts-with? %ecx "loop") # => eax +16381 3d/compare-eax-and 0/imm32/false +16382 0f 85/jump-if-!= $populate-mu-function-signature:error-loop/disp32 +16383 # save function name +16384 (slice-to-string Heap %ecx %edi) # Function-name +16385 # save function inouts +16386 { +16387 $populate-mu-function-signature:check-for-inout: +16388 (next-mu-token *(ebp+8) %ecx) +16389 (slice-empty? %ecx) # => eax +16390 3d/compare-eax-and 0/imm32/false +16391 0f 85/jump-if-!= break/disp32 +16392 # if (word-slice == '->') break +16393 (slice-equal? %ecx "->") # => eax +16394 3d/compare-eax-and 0/imm32/false +16395 0f 85/jump-if-!= break/disp32 +16396 # if (word-slice == '{') abort +16397 (slice-equal? %ecx "{") # => eax +16398 3d/compare-eax-and 0/imm32/false +16399 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 +16400 # if (word-slice == '}') abort +16401 (slice-equal? %ecx "}") # => eax +16402 3d/compare-eax-and 0/imm32/false +16403 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 +16404 # v = parse-var-with-type(word-slice, first-line) +16405 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16406 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x10) *(ebp+0x14)) +16407 # if (v->register != null) abort +16408 # . eax: (addr var) = lookup(v) +16409 (lookup *ebx *(ebx+4)) # => eax +16410 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +16411 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32 +16412 # if function name is not "main" +16413 # and v->type contains an 'addr' anywhere except the start, abort +16414 { +16415 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16416 (string-equal? %eax "main") # => eax +16417 3d/compare-eax-and 0/imm32/false +16418 75/jump-if-!= break/disp8 +16419 (lookup *ebx *(ebx+4)) # => eax +16420 (addr-payload-contains-addr? %eax) # => eax +16421 3d/compare-eax-and 0/imm32/false +16422 0f 85/jump-if-!= $populate-mu-function-signature:error-nested-addr-inout/disp32 +16423 } +16424 # assert(v->register == null) +16425 # . eax: (addr var) = lookup(v) +16426 (lookup *ebx *(ebx+4)) # => eax +16427 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +16428 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32 +16429 # v->block-depth is implicitly 0 +16430 # +16431 # out->inouts = append(v, out->inouts) +16432 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts +16433 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts +16434 # +16435 e9/jump loop/disp32 +16436 } +16437 # save function outputs +16438 { +16439 $populate-mu-function-signature:check-for-out: +16440 (next-mu-token *(ebp+8) %ecx) +16441 (slice-empty? %ecx) # => eax +16442 3d/compare-eax-and 0/imm32/false +16443 0f 85/jump-if-!= break/disp32 +16444 # if (word-slice == '{') abort +16445 (slice-equal? %ecx "{") # => eax +16446 3d/compare-eax-and 0/imm32/false +16447 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 +16448 # if (word-slice == '->') abort +16449 (slice-equal? %ecx "->") # => eax +16450 3d/compare-eax-and 0/imm32/false +16451 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 +16452 # if (word-slice == '}') abort +16453 (slice-equal? %ecx "}") # => eax +16454 3d/compare-eax-and 0/imm32/false +16455 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 +16456 # v = parse-var-with-type(word-slice, first-line) +16457 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16458 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x10) *(ebp+0x14)) +16459 # assert(var->register != null) +16460 # . eax: (addr var) = lookup(v) +16461 (lookup *ebx *(ebx+4)) # => eax +16462 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +16463 0f 84/jump-if-= $populate-mu-function-signature:error3/disp32 +16464 # if (var->name != "_") abort +16465 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16466 (string-equal? %eax "_") # => eax +16467 3d/compare-eax-and 0/imm32/false +16468 0f 84/jump-if-= $populate-mu-function-signature:error4/disp32 +16469 # if function name is not "lookup" +16470 # and v->type is an addr, abort +16471 { +16472 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16473 (string-equal? %eax "lookup") # => eax +16474 3d/compare-eax-and 0/imm32/false +16475 75/jump-if-!= break/disp8 +16476 (lookup *ebx *(ebx+4)) # => eax +16477 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +16478 (mu-addr-type? %eax) # => eax +16479 3d/compare-eax-and 0/imm32/false +16480 0f 85/jump-if-!= $populate-mu-function-signature:error-addr-output/disp32 +16481 } +16482 # out->outputs = append(v, out->outputs) +16483 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs +16484 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs +16485 # +16486 e9/jump loop/disp32 +16487 } +16488 $populate-mu-function-signature:done: +16489 (check-no-tokens-left *(ebp+8)) +16490 $populate-mu-function-signature:end: +16491 # . reclaim locals +16492 81 0/subop/add %esp 0x10/imm32 +16493 # . restore registers +16494 5f/pop-to-edi +16495 5b/pop-to-ebx +16496 5a/pop-to-edx +16497 59/pop-to-ecx 16498 58/pop-to-eax -16499 (write-buffered *(ebp+0x10) ": function inout '") -16500 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16501 (write-buffered *(ebp+0x10) %eax) -16502 (write-buffered *(ebp+0x10) "' cannot be in a register") -16503 (flush *(ebp+0x10)) -16504 (stop *(ebp+0x14) 1) -16505 # never gets here -16506 -16507 $populate-mu-function-signature:error3: -16508 # error("fn " fn ": function output '" var "' must be in a register") -16509 (write-buffered *(ebp+0x10) "fn ") -16510 50/push-eax -16511 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16512 (write-buffered *(ebp+0x10) %eax) -16513 58/pop-to-eax -16514 (write-buffered *(ebp+0x10) ": function output '") -16515 (lookup *ebx *(ebx+4)) # => eax -16516 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16517 (write-buffered *(ebp+0x10) %eax) -16518 (write-buffered *(ebp+0x10) "' must be in a register, in instruction '") -16519 (rewind-stream *(ebp+8)) -16520 (write-stream-data *(ebp+0x10) *(ebp+8)) -16521 (write-buffered *(ebp+0x10) "'\n") -16522 (flush *(ebp+0x10)) -16523 (stop *(ebp+0x14) 1) -16524 # never gets here -16525 -16526 $populate-mu-function-signature:error4: -16527 # error("fn " fn ": function outputs cannot be named; rename '" var "' in the header to '_'") -16528 (write-buffered *(ebp+0x10) "fn ") -16529 50/push-eax -16530 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16531 (write-buffered *(ebp+0x10) %eax) -16532 58/pop-to-eax -16533 (write-buffered *(ebp+0x10) ": function outputs cannot be named; rename '") -16534 (lookup *ebx *(ebx+4)) # => eax -16535 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16536 (write-buffered *(ebp+0x10) %eax) -16537 (write-buffered *(ebp+0x10) "' in the header to '_'\n") -16538 (flush *(ebp+0x10)) -16539 (stop *(ebp+0x14) 1) -16540 # never gets here -16541 -16542 $populate-mu-function-signature:error-duplicate: -16543 (write-buffered *(ebp+0x10) "fn ") -16544 (write-slice-buffered *(ebp+0x10) %ecx) -16545 (write-buffered *(ebp+0x10) " defined more than once\n") -16546 (flush *(ebp+0x10)) -16547 (stop *(ebp+0x14) 1) -16548 # never gets here -16549 -16550 $populate-mu-function-signature:error-break: -16551 (write-buffered *(ebp+0x10) "Sorry, I've reserved all function names starting with 'break' for now. Please contact mu@akkartik.com.\n") -16552 (flush *(ebp+0x10)) -16553 (stop *(ebp+0x14) 1) -16554 # never gets here -16555 -16556 $populate-mu-function-signature:error-loop: -16557 (write-buffered *(ebp+0x10) "Sorry, I've reserved all function names starting with 'loop' for now. Please contact mu@akkartik.com.\n") -16558 (flush *(ebp+0x10)) -16559 (stop *(ebp+0x14) 1) -16560 # never gets here -16561 -16562 $populate-mu-function-signature:error-addr-output: -16563 # error("fn " fn ": output cannot have an addr type; that could allow unsafe addresses to escape the function") -16564 (write-buffered *(ebp+0x10) "fn ") -16565 50/push-eax -16566 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16567 (write-buffered *(ebp+0x10) %eax) -16568 58/pop-to-eax -16569 (write-buffered *(ebp+0x10) ": output cannot have an addr type; that could allow unsafe addresses to escape the function\n") -16570 (flush *(ebp+0x10)) -16571 (stop *(ebp+0x14) 1) -16572 # never gets here -16573 -16574 $populate-mu-function-signature:error-nested-addr-inout: -16575 # error("fn " fn ": inout '" var "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function") -16576 (write-buffered *(ebp+0x10) "fn ") -16577 (lookup *edi *(edi+4)) # Function-name Function-name => eax -16578 (write-buffered *(ebp+0x10) %eax) -16579 (write-buffered *(ebp+0x10) ": inout '") -16580 (lookup *ebx *(ebx+4)) # => eax -16581 (lookup *eax *(eax+4)) # Var-name Var-name => eax -16582 (write-buffered *(ebp+0x10) %eax) -16583 (write-buffered *(ebp+0x10) "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function\n") -16584 (flush *(ebp+0x10)) -16585 (stop *(ebp+0x14) 1) -16586 # never gets here -16587 -16588 addr-payload-contains-addr?: # v: (addr var) -> result/eax: boolean -16589 # . prologue -16590 55/push-ebp -16591 89/<- %ebp 4/r32/esp -16592 # var t/eax: (addr type-tree) = v->type -16593 8b/-> *(ebp+8) 0/r32/eax -16594 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -16595 # if t->right contains addr, return true -16596 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -16597 (type-tree-contains? %eax 2) # addr => eax -16598 # we don't have to look at t->left as long as it's guaranteed to be an atom -16599 $addr-payload-contains-addr?:end: -16600 # . epilogue -16601 89/<- %esp 5/r32/ebp -16602 5d/pop-to-ebp -16603 c3/return -16604 -16605 type-tree-contains?: # t: (addr type-tree), n: type-id -> result/eax: boolean -16606 # . prologue -16607 55/push-ebp -16608 89/<- %ebp 4/r32/esp -16609 # . save registers -16610 51/push-ecx -16611 # if t is null, return false -16612 8b/-> *(ebp+8) 0/r32/eax -16613 3d/compare-eax-and 0/imm32 -16614 0f 84/jump-if-= $type-tree-contains?:end/disp32 # eax changes type -16615 # if t is an atom, return (t->value == n) -16616 81 7/subop/compare *eax 0/imm32/false -16617 { -16618 74/jump-if-= break/disp8 -16619 8b/-> *(ebp+0xc) 1/r32/ecx -16620 39/compare *(eax+4) 1/r32/ecx # Type-tree-value -16621 0f 94/set-if-= %al -16622 25/and-eax-with 0xff/imm32 -16623 eb/jump $type-tree-contains?:end/disp8 -16624 } -16625 # if t->left contains n, return true -16626 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -16627 (type-tree-contains? %eax *(ebp+0xc)) # => eax -16628 3d/compare-eax-and 0/imm32/false -16629 75/jump-if-!= $type-tree-contains?:end/disp8 -16630 # otherwise return whether t->right contains n -16631 8b/-> *(ebp+8) 0/r32/eax -16632 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -16633 (type-tree-contains? %eax *(ebp+0xc)) # => eax -16634 $type-tree-contains?:end: -16635 # . restore registers -16636 59/pop-to-ecx -16637 # . epilogue -16638 89/<- %esp 5/r32/ebp -16639 5d/pop-to-ebp -16640 c3/return -16641 -16642 function-exists?: # s: (addr slice) -> result/eax: boolean -16643 # . prologue -16644 55/push-ebp -16645 89/<- %ebp 4/r32/esp -16646 # . save registers -16647 51/push-ecx -16648 # var curr/ecx: (addr function) = functions -16649 (lookup *_Program-functions *_Program-functions->payload) # => eax -16650 89/<- %ecx 0/r32/eax -16651 { -16652 # if (curr == null) break -16653 81 7/subop/compare %ecx 0/imm32 -16654 74/jump-if-= break/disp8 -16655 # if (curr->name == s) return true -16656 { -16657 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -16658 (slice-equal? *(ebp+8) %eax) # => eax -16659 3d/compare-eax-and 0/imm32/false -16660 74/jump-if-= break/disp8 -16661 b8/copy-to-eax 1/imm32/true -16662 e9/jump $function-exists?:end/disp32 -16663 } -16664 # curr = curr->next -16665 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax -16666 89/<- %ecx 0/r32/eax -16667 # -16668 eb/jump loop/disp8 -16669 } -16670 # var curr/ecx: (addr function) = signatures -16671 (lookup *_Program-signatures *_Program-signatures->payload) # => eax -16672 89/<- %ecx 0/r32/eax -16673 { -16674 # if (curr == null) break -16675 81 7/subop/compare %ecx 0/imm32 -16676 74/jump-if-= break/disp8 -16677 # if (curr->name == s) return true -16678 { -16679 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -16680 (slice-equal? *(ebp+8) %eax) # => eax -16681 3d/compare-eax-and 0/imm32/false -16682 74/jump-if-= break/disp8 -16683 b8/copy-to-eax 1/imm32/true -16684 eb/jump $function-exists?:end/disp8 -16685 } -16686 # curr = curr->next -16687 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax -16688 89/<- %ecx 0/r32/eax -16689 # -16690 eb/jump loop/disp8 -16691 } -16692 # return false -16693 b8/copy-to-eax 0/imm32/false -16694 $function-exists?:end: -16695 # . restore registers -16696 59/pop-to-ecx -16697 # . epilogue -16698 89/<- %esp 5/r32/ebp -16699 5d/pop-to-ebp -16700 c3/return -16701 -16702 test-function-header-with-arg: -16703 # . prologue -16704 55/push-ebp -16705 89/<- %ebp 4/r32/esp -16706 # setup -16707 8b/-> *Primitive-type-ids 0/r32/eax -16708 89/<- *Type-id 0/r32/eax # stream-write -16709 c7 0/subop/copy *_Program-functions 0/imm32 -16710 c7 0/subop/copy *_Program-functions->payload 0/imm32 -16711 c7 0/subop/copy *_Program-types 0/imm32 -16712 c7 0/subop/copy *_Program-types->payload 0/imm32 -16713 c7 0/subop/copy *_Program-signatures 0/imm32 -16714 c7 0/subop/copy *_Program-signatures->payload 0/imm32 -16715 (clear-stream _test-input-stream) -16716 (write _test-input-stream "foo n: int {\n") -16717 # var result/ecx: function -16718 2b/subtract *Function-size 4/r32/esp -16719 89/<- %ecx 4/r32/esp -16720 (zero-out %ecx *Function-size) -16721 # var vars/ebx: (stack live-var 16) -16722 81 5/subop/subtract %esp 0xc0/imm32 -16723 68/push 0xc0/imm32/size -16724 68/push 0/imm32/top -16725 89/<- %ebx 4/r32/esp -16726 # convert -16727 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) -16728 # check result->name -16729 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -16730 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") -16731 # var v/edx: (addr var) = result->inouts->value -16732 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax -16733 (lookup *eax *(eax+4)) # List-value List-value => eax -16734 89/<- %edx 0/r32/eax -16735 # check v->name -16736 (lookup *edx *(edx+4)) # Var-name Var-name => eax -16737 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") -16738 # check v->type -16739 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -16740 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Type-tree-is-atom -16741 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Type-tree-value -16742 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Type-tree-right -16743 # . epilogue -16744 89/<- %esp 5/r32/ebp -16745 5d/pop-to-ebp -16746 c3/return -16747 -16748 test-function-header-with-multiple-args: -16749 # . prologue -16750 55/push-ebp -16751 89/<- %ebp 4/r32/esp -16752 # setup -16753 8b/-> *Primitive-type-ids 0/r32/eax -16754 89/<- *Type-id 0/r32/eax # stream-write -16755 c7 0/subop/copy *_Program-functions 0/imm32 -16756 c7 0/subop/copy *_Program-functions->payload 0/imm32 -16757 c7 0/subop/copy *_Program-types 0/imm32 -16758 c7 0/subop/copy *_Program-types->payload 0/imm32 -16759 c7 0/subop/copy *_Program-signatures 0/imm32 -16760 c7 0/subop/copy *_Program-signatures->payload 0/imm32 -16761 (clear-stream _test-input-stream) -16762 (write _test-input-stream "foo a: int, b: int c: int {\n") -16763 # result/ecx: function -16764 2b/subtract *Function-size 4/r32/esp -16765 89/<- %ecx 4/r32/esp -16766 (zero-out %ecx *Function-size) -16767 # var vars/ebx: (stack live-var 16) -16768 81 5/subop/subtract %esp 0xc0/imm32 -16769 68/push 0xc0/imm32/size -16770 68/push 0/imm32/top -16771 89/<- %ebx 4/r32/esp -16772 # convert -16773 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) -16774 # check result->name -16775 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -16776 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") -16777 # var inouts/edx: (addr list var) = lookup(result->inouts) -16778 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax -16779 89/<- %edx 0/r32/eax -16780 $test-function-header-with-multiple-args:inout0: -16781 # var v/ebx: (addr var) = lookup(inouts->value) -16782 (lookup *edx *(edx+4)) # List-value List-value => eax -16783 89/<- %ebx 0/r32/eax -16784 # check v->name -16785 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -16786 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name -16787 # check v->type -16788 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax -16789 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Type-tree-is-atom -16790 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Type-tree-value -16791 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Type-tree-right -16792 $test-function-header-with-multiple-args:inout1: -16793 # inouts = lookup(inouts->next) -16794 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -16795 89/<- %edx 0/r32/eax -16796 # v = lookup(inouts->value) -16797 (lookup *edx *(edx+4)) # List-value List-value => eax -16798 89/<- %ebx 0/r32/eax -16799 # check v->name -16800 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -16801 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name -16802 # check v->type -16803 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax -16804 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Type-tree-is-atom -16805 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Type-tree-value -16806 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Type-tree-right -16807 $test-function-header-with-multiple-args:inout2: -16808 # inouts = lookup(inouts->next) -16809 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -16810 89/<- %edx 0/r32/eax -16811 # v = lookup(inouts->value) -16812 (lookup *edx *(edx+4)) # List-value List-value => eax -16813 89/<- %ebx 0/r32/eax -16814 # check v->name -16815 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -16816 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name -16817 # check v->type -16818 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax -16819 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Type-tree-is-atom -16820 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Type-tree-value -16821 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Type-tree-right -16822 # . epilogue -16823 89/<- %esp 5/r32/ebp -16824 5d/pop-to-ebp -16825 c3/return -16826 -16827 test-function-header-with-multiple-args-and-outputs: -16828 # . prologue -16829 55/push-ebp -16830 89/<- %ebp 4/r32/esp -16831 # setup -16832 8b/-> *Primitive-type-ids 0/r32/eax -16833 89/<- *Type-id 0/r32/eax # stream-write -16834 c7 0/subop/copy *_Program-functions 0/imm32 -16835 c7 0/subop/copy *_Program-functions->payload 0/imm32 -16836 c7 0/subop/copy *_Program-types 0/imm32 -16837 c7 0/subop/copy *_Program-types->payload 0/imm32 -16838 c7 0/subop/copy *_Program-signatures 0/imm32 -16839 c7 0/subop/copy *_Program-signatures->payload 0/imm32 -16840 (clear-stream _test-input-stream) -16841 (write _test-input-stream "foo a: int, b: int, c: int -> _/ecx: int _/edx: int {\n") -16842 # result/ecx: function -16843 2b/subtract *Function-size 4/r32/esp -16844 89/<- %ecx 4/r32/esp -16845 (zero-out %ecx *Function-size) -16846 # var vars/ebx: (stack live-var 16) -16847 81 5/subop/subtract %esp 0xc0/imm32 -16848 68/push 0xc0/imm32/size -16849 68/push 0/imm32/top -16850 89/<- %ebx 4/r32/esp -16851 # convert -16852 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) -16853 # check result->name -16854 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -16855 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") -16856 # var inouts/edx: (addr list var) = lookup(result->inouts) -16857 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax -16858 89/<- %edx 0/r32/eax -16859 $test-function-header-with-multiple-args-and-outputs:inout0: -16860 # var v/ebx: (addr var) = lookup(inouts->value) -16861 (lookup *edx *(edx+4)) # List-value List-value => eax -16862 89/<- %ebx 0/r32/eax -16863 # check v->name -16864 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -16865 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") -16866 # check v->type -16867 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax -16868 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Type-tree-is-atom -16869 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Type-tree-value -16870 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Type-tree-right -16871 $test-function-header-with-multiple-args-and-outputs:inout1: -16872 # inouts = lookup(inouts->next) -16873 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -16874 89/<- %edx 0/r32/eax -16875 # v = lookup(inouts->value) -16876 (lookup *edx *(edx+4)) # List-value List-value => eax -16877 89/<- %ebx 0/r32/eax -16878 # check v->name -16879 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -16880 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") -16881 # check v->type -16882 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax -16883 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Type-tree-is-atom -16884 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Type-tree-value -16885 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Type-tree-right -16886 $test-function-header-with-multiple-args-and-outputs:inout2: -16887 # inouts = lookup(inouts->next) -16888 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -16889 89/<- %edx 0/r32/eax -16890 # v = lookup(inouts->value) -16891 (lookup *edx *(edx+4)) # List-value List-value => eax -16892 89/<- %ebx 0/r32/eax -16893 # check v->name -16894 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -16895 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") -16896 # check v->type -16897 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax -16898 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Type-tree-is-atom -16899 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Type-tree-value -16900 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Type-tree-right -16901 $test-function-header-with-multiple-args-and-outputs:out0: -16902 # var outputs/edx: (addr list var) = lookup(result->outputs) -16903 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax -16904 89/<- %edx 0/r32/eax -16905 # v = lookup(outputs->value) -16906 (lookup *edx *(edx+4)) # List-value List-value => eax -16907 89/<- %ebx 0/r32/eax -16908 # check v->name -16909 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -16910 (check-strings-equal %eax "_" "F - test-function-header-with-multiple-args-and-outputs/output:0") -16911 # check v->register -16912 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -16913 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") -16914 # check v->type -16915 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax -16916 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Type-tree-is-atom -16917 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Type-tree-value -16918 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Type-tree-right -16919 $test-function-header-with-multiple-args-and-outputs:out1: -16920 # outputs = lookup(outputs->next) -16921 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -16922 89/<- %edx 0/r32/eax -16923 # v = lookup(inouts->value) -16924 (lookup *edx *(edx+4)) # List-value List-value => eax -16925 89/<- %ebx 0/r32/eax -16926 # check v->name -16927 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -16928 (check-strings-equal %eax "_" "F - test-function-header-with-multiple-args-and-outputs/output:1") -16929 # check v->register -16930 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -16931 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") -16932 # check v->type -16933 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax -16934 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Type-tree-is-atom -16935 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Type-tree-value -16936 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Type-tree-right -16937 # . epilogue -16938 89/<- %esp 5/r32/ebp -16939 5d/pop-to-ebp -16940 c3/return -16941 -16942 # format for variables with types -16943 # x: int -16944 # x: int, -16945 # x/eax: int -16946 # x/eax: int, -16947 # ignores at most one trailing comma -16948 # does not support other, non-register metadata -16949 # WARNING: modifies name -16950 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), fn-name: (addr array byte), err: (addr buffered-file), ed: (addr exit-descriptor) -16951 # pseudocode: -16952 # var s: slice -16953 # if (!slice-ends-with(name, ":")) -16954 # abort -16955 # --name->end to skip ':' -16956 # next-token-from-slice(name->start, name->end, '/', s) -16957 # new-var-from-slice(s, out) -16958 # ## register -16959 # next-token-from-slice(s->end, name->end, '/', s) -16960 # if (!slice-empty?(s)) -16961 # out->register = slice-to-string(s) -16962 # ## type -16963 # var type: (handle type-tree) = parse-type(first-line) -16964 # out->type = type -16965 # -16966 # . prologue -16967 55/push-ebp -16968 89/<- %ebp 4/r32/esp -16969 # . save registers -16970 50/push-eax -16971 51/push-ecx -16972 52/push-edx -16973 53/push-ebx -16974 56/push-esi -16975 57/push-edi -16976 # esi = name -16977 8b/-> *(ebp+8) 6/r32/esi -16978 # if (!slice-ends-with?(name, ":")) abort -16979 8b/-> *(esi+4) 1/r32/ecx # Slice-end -16980 49/decrement-ecx -16981 8a/copy-byte *ecx 1/r32/CL -16982 81 4/subop/and %ecx 0xff/imm32 -16983 81 7/subop/compare %ecx 0x3a/imm32/colon -16984 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 -16985 # --name->end to skip ':' -16986 ff 1/subop/decrement *(esi+4) -16987 # var s/ecx: slice -16988 68/push 0/imm32/end -16989 68/push 0/imm32/start -16990 89/<- %ecx 4/r32/esp -16991 $parse-var-with-type:parse-name: -16992 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' -16993 $parse-var-with-type:create-var: -16994 # new-var-from-slice(s, out) -16995 (new-var-from-slice Heap %ecx *(ebp+0x10)) -16996 # save out->register -16997 $parse-var-with-type:save-register: -16998 # . var out-addr/edi: (addr var) = lookup(*out) -16999 8b/-> *(ebp+0x10) 7/r32/edi -17000 (lookup *edi *(edi+4)) # => eax -17001 89/<- %edi 0/r32/eax -17002 # . s = next-token(...) -17003 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' -17004 # . if (!slice-empty?(s)) out->register = slice-to-string(s) -17005 { -17006 $parse-var-with-type:write-register: -17007 (slice-empty? %ecx) # => eax -17008 3d/compare-eax-and 0/imm32/false -17009 75/jump-if-!= break/disp8 -17010 # out->register = slice-to-string(s) -17011 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register -17012 (slice-to-string Heap %ecx %eax) -17013 } -17014 $parse-var-with-type:save-type: -17015 8d/copy-address *(edi+8) 0/r32/eax # Var-type -17016 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x18) *(ebp+0x1c)) -17017 $parse-var-with-type:check-register: -17018 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -17019 3d/compare-eax-and 0/imm32 -17020 74/jump-if-= $parse-var-with-type:end/disp8 -17021 (float-register? %eax) # => eax -17022 { -17023 3d/compare-eax-and 0/imm32/false -17024 74/jump-if-= break/disp8 -17025 # var is in a float register; ensure type is float -17026 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -17027 (simple-mu-type? %eax 0xf) # float => eax -17028 3d/compare-eax-and 0/imm32/false -17029 0f 84/jump-if-= $parse-var-with-type:error-non-float-in-floating-point-register/disp32 -17030 eb/jump $parse-var-with-type:end/disp8 -17031 } -17032 # var is not in a float register; ensure type is not float -17033 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -17034 (simple-mu-type? %eax 0xf) # float => eax -17035 3d/compare-eax-and 0/imm32/false -17036 0f 85/jump-if-!= $parse-var-with-type:error-float-in-integer-register/disp32 -17037 $parse-var-with-type:end: -17038 # . reclaim locals -17039 81 0/subop/add %esp 8/imm32 -17040 # . restore registers -17041 5f/pop-to-edi -17042 5e/pop-to-esi -17043 5b/pop-to-ebx -17044 5a/pop-to-edx -17045 59/pop-to-ecx -17046 58/pop-to-eax -17047 # . epilogue -17048 89/<- %esp 5/r32/ebp -17049 5d/pop-to-ebp -17050 c3/return -17051 -17052 $parse-var-with-type:abort: -17053 # error("fn " fn ": var should have form 'name: type' in '" line "'\n") -17054 (write-buffered *(ebp+0x18) "fn ") -17055 (write-buffered *(ebp+0x18) *(ebp+0x14)) -17056 (write-buffered *(ebp+0x18) ": var should have form 'name: type' in '") -17057 (flush *(ebp+0x18)) -17058 (rewind-stream *(ebp+0xc)) -17059 (write-stream-data *(ebp+0x18) *(ebp+0xc)) -17060 (write-buffered *(ebp+0x18) "'\n") -17061 (flush *(ebp+0x18)) -17062 (stop *(ebp+0x1c) 1) -17063 # never gets here -17064 -17065 $parse-var-with-type:error-float-in-integer-register: -17066 # error("fn " fn ": float var '" var "' should be in a floating-point register\n") -17067 (write-buffered *(ebp+0x18) "fn ") -17068 (write-buffered *(ebp+0x18) *(ebp+0x14)) -17069 (write-buffered *(ebp+0x18) ": float var '") -17070 (lookup *edi *(edi+4)) # Var-name Var-name => eax -17071 (write-buffered *(ebp+0x18) %eax) -17072 (write-buffered *(ebp+0x18) "' should be in a floating-point register\n") -17073 (flush *(ebp+0x18)) -17074 (stop *(ebp+0x1c) 1) -17075 # never gets here -17076 -17077 $parse-var-with-type:error-non-float-in-floating-point-register: -17078 # error("fn " fn ": non-float var '" var "' should be in an integer register\n") -17079 (write-buffered *(ebp+0x18) "fn ") -17080 (write-buffered *(ebp+0x18) *(ebp+0x14)) -17081 (write-buffered *(ebp+0x18) ": non-float var '") -17082 (lookup *edi *(edi+4)) # Var-name Var-name => eax -17083 (write-buffered *(ebp+0x18) %eax) -17084 (write-buffered *(ebp+0x18) "' should be in an integer register\n") -17085 (flush *(ebp+0x18)) -17086 (stop *(ebp+0x1c) 1) -17087 # never gets here -17088 -17089 float-register?: # r: (addr array byte) -> result/eax: boolean -17090 # . prologue -17091 55/push-ebp -17092 89/<- %ebp 4/r32/esp -17093 # -17094 (get Mu-registers-unique *(ebp+8) 0xc "Mu-registers-unique") # => eax -17095 81 7/subop/compare *eax 8/imm32/start-of-floating-point-registers -17096 0f 9d/set-if->= %al -17097 25/and-eax-with 0xff/imm32 -17098 $float-register?:end: -17099 # . epilogue -17100 89/<- %esp 5/r32/ebp -17101 5d/pop-to-ebp -17102 c3/return -17103 -17104 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) -17105 # pseudocode: -17106 # var s: slice = next-mu-token(in) -17107 # assert s != "" -17108 # assert s != "->" -17109 # assert s != "{" -17110 # assert s != "}" -17111 # if s == ")" -17112 # return -17113 # out = allocate(Type-tree) -17114 # if s != "(" -17115 # HACK: if s is an int, parse and return it -17116 # out->is-atom? = true -17117 # if (s[0] == "_") -17118 # out->value = type-parameter -17119 # out->parameter-name = slice-to-string(ad, s) -17120 # else -17121 # out->value = pos-or-insert-slice(Type-id, s) -17122 # return -17123 # out->left = parse-type(ad, in) -17124 # out->right = parse-type-tree(ad, in) -17125 # -17126 # . prologue -17127 55/push-ebp -17128 89/<- %ebp 4/r32/esp -17129 # . save registers -17130 50/push-eax -17131 51/push-ecx -17132 52/push-edx -17133 # clear out -17134 (zero-out *(ebp+0x10) *Handle-size) -17135 # var s/ecx: slice -17136 68/push 0/imm32 -17137 68/push 0/imm32 -17138 89/<- %ecx 4/r32/esp -17139 # s = next-mu-token(in) -17140 (next-mu-token *(ebp+0xc) %ecx) -17141 #? (write-buffered Stderr "tok: ") -17142 #? (write-slice-buffered Stderr %ecx) -17143 #? (write-buffered Stderr "$\n") -17144 #? (flush Stderr) -17145 # assert s != "" -17146 (slice-equal? %ecx "") # => eax -17147 3d/compare-eax-and 0/imm32/false -17148 0f 85/jump-if-!= $parse-type:abort/disp32 -17149 # assert s != "{" -17150 (slice-equal? %ecx "{") # => eax -17151 3d/compare-eax-and 0/imm32/false -17152 0f 85/jump-if-!= $parse-type:abort/disp32 -17153 # assert s != "}" -17154 (slice-equal? %ecx "}") # => eax -17155 3d/compare-eax-and 0/imm32/false -17156 0f 85/jump-if-!= $parse-type:abort/disp32 -17157 # assert s != "->" -17158 (slice-equal? %ecx "->") # => eax -17159 3d/compare-eax-and 0/imm32/false -17160 0f 85/jump-if-!= $parse-type:abort/disp32 -17161 # if (s == ")") return -17162 (slice-equal? %ecx ")") # => eax -17163 3d/compare-eax-and 0/imm32/false -17164 0f 85/jump-if-!= $parse-type:end/disp32 -17165 # out = new tree -17166 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) -17167 # var out-addr/edx: (addr type-tree) = lookup(*out) -17168 8b/-> *(ebp+0x10) 2/r32/edx -17169 (lookup *edx *(edx+4)) # => eax -17170 89/<- %edx 0/r32/eax -17171 { -17172 # if (s != "(") break -17173 (slice-equal? %ecx "(") # => eax -17174 3d/compare-eax-and 0/imm32/false -17175 0f 85/jump-if-!= break/disp32 -17176 # if s is a number, store it in the type's size field -17177 { -17178 $parse-type:check-for-int: -17179 # var tmp/eax: byte = *s->slice -17180 8b/-> *ecx 0/r32/eax -17181 8a/copy-byte *eax 0/r32/AL -17182 25/and-eax-with 0xff/imm32 -17183 # TODO: raise an error on `var x: (array int a)` -17184 (decimal-digit? %eax) # => eax -17185 3d/compare-eax-and 0/imm32/false -17186 74/jump-if-= break/disp8 -17187 $parse-type:int: -17188 # strip out metadata -17189 (next-token-from-slice *ecx *(ecx+4) 0x2f %ecx) -17190 # -17191 (check-mu-hex-int %ecx *(ebp+0x14) *(ebp+0x18)) -17192 (parse-hex-int-from-slice %ecx) # => eax -17193 c7 0/subop/copy *(edx+4) 9/imm32/type-id-array-capacity # Type-tree-value -17194 89/<- *(edx+8) 0/r32/eax # Type-tree-value-size -17195 e9/jump $parse-type:end/disp32 -17196 } -17197 $parse-type:atom: -17198 # out->is-atom? = true -17199 c7 0/subop/copy *edx 1/imm32/true # Type-tree-is-atom +16499 # . epilogue +16500 89/<- %esp 5/r32/ebp +16501 5d/pop-to-ebp +16502 c3/return +16503 +16504 $populate-mu-function-signature:error1: +16505 # error("function signature not in form 'fn <name> {'") +16506 (write-buffered *(ebp+0x10) "function signature not in form 'fn <name> [inouts] [-> outputs] {' -- '") +16507 (flush *(ebp+0x10)) +16508 (rewind-stream *(ebp+8)) +16509 (write-stream-data *(ebp+0x10) *(ebp+8)) +16510 (write-buffered *(ebp+0x10) "'\n") +16511 (flush *(ebp+0x10)) +16512 (stop *(ebp+0x14) 1) +16513 # never gets here +16514 +16515 $populate-mu-function-signature:error2: +16516 # error("fn " fn ": function inout '" var "' cannot be in a register") +16517 (write-buffered *(ebp+0x10) "fn ") +16518 50/push-eax +16519 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16520 (write-buffered *(ebp+0x10) %eax) +16521 58/pop-to-eax +16522 (write-buffered *(ebp+0x10) ": function inout '") +16523 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16524 (write-buffered *(ebp+0x10) %eax) +16525 (write-buffered *(ebp+0x10) "' cannot be in a register") +16526 (flush *(ebp+0x10)) +16527 (stop *(ebp+0x14) 1) +16528 # never gets here +16529 +16530 $populate-mu-function-signature:error3: +16531 # error("fn " fn ": function output '" var "' must be in a register") +16532 (write-buffered *(ebp+0x10) "fn ") +16533 50/push-eax +16534 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16535 (write-buffered *(ebp+0x10) %eax) +16536 58/pop-to-eax +16537 (write-buffered *(ebp+0x10) ": function output '") +16538 (lookup *ebx *(ebx+4)) # => eax +16539 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16540 (write-buffered *(ebp+0x10) %eax) +16541 (write-buffered *(ebp+0x10) "' must be in a register, in instruction '") +16542 (rewind-stream *(ebp+8)) +16543 (write-stream-data *(ebp+0x10) *(ebp+8)) +16544 (write-buffered *(ebp+0x10) "'\n") +16545 (flush *(ebp+0x10)) +16546 (stop *(ebp+0x14) 1) +16547 # never gets here +16548 +16549 $populate-mu-function-signature:error4: +16550 # error("fn " fn ": function outputs cannot be named; rename '" var "' in the header to '_'") +16551 (write-buffered *(ebp+0x10) "fn ") +16552 50/push-eax +16553 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16554 (write-buffered *(ebp+0x10) %eax) +16555 58/pop-to-eax +16556 (write-buffered *(ebp+0x10) ": function outputs cannot be named; rename '") +16557 (lookup *ebx *(ebx+4)) # => eax +16558 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16559 (write-buffered *(ebp+0x10) %eax) +16560 (write-buffered *(ebp+0x10) "' in the header to '_'\n") +16561 (flush *(ebp+0x10)) +16562 (stop *(ebp+0x14) 1) +16563 # never gets here +16564 +16565 $populate-mu-function-signature:error-duplicate: +16566 (write-buffered *(ebp+0x10) "fn ") +16567 (write-slice-buffered *(ebp+0x10) %ecx) +16568 (write-buffered *(ebp+0x10) " defined more than once\n") +16569 (flush *(ebp+0x10)) +16570 (stop *(ebp+0x14) 1) +16571 # never gets here +16572 +16573 $populate-mu-function-signature:error-break: +16574 (write-buffered *(ebp+0x10) "Sorry, I've reserved all function names starting with 'break' for now. Please contact mu@akkartik.com.\n") +16575 (flush *(ebp+0x10)) +16576 (stop *(ebp+0x14) 1) +16577 # never gets here +16578 +16579 $populate-mu-function-signature:error-loop: +16580 (write-buffered *(ebp+0x10) "Sorry, I've reserved all function names starting with 'loop' for now. Please contact mu@akkartik.com.\n") +16581 (flush *(ebp+0x10)) +16582 (stop *(ebp+0x14) 1) +16583 # never gets here +16584 +16585 $populate-mu-function-signature:error-addr-output: +16586 # error("fn " fn ": output cannot have an addr type; that could allow unsafe addresses to escape the function") +16587 (write-buffered *(ebp+0x10) "fn ") +16588 50/push-eax +16589 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16590 (write-buffered *(ebp+0x10) %eax) +16591 58/pop-to-eax +16592 (write-buffered *(ebp+0x10) ": output cannot have an addr type; that could allow unsafe addresses to escape the function\n") +16593 (flush *(ebp+0x10)) +16594 (stop *(ebp+0x14) 1) +16595 # never gets here +16596 +16597 $populate-mu-function-signature:error-nested-addr-inout: +16598 # error("fn " fn ": inout '" var "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function") +16599 (write-buffered *(ebp+0x10) "fn ") +16600 (lookup *edi *(edi+4)) # Function-name Function-name => eax +16601 (write-buffered *(ebp+0x10) %eax) +16602 (write-buffered *(ebp+0x10) ": inout '") +16603 (lookup *ebx *(ebx+4)) # => eax +16604 (lookup *eax *(eax+4)) # Var-name Var-name => eax +16605 (write-buffered *(ebp+0x10) %eax) +16606 (write-buffered *(ebp+0x10) "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function\n") +16607 (flush *(ebp+0x10)) +16608 (stop *(ebp+0x14) 1) +16609 # never gets here +16610 +16611 addr-payload-contains-addr?: # v: (addr var) -> result/eax: boolean +16612 # . prologue +16613 55/push-ebp +16614 89/<- %ebp 4/r32/esp +16615 # var t/eax: (addr type-tree) = v->type +16616 8b/-> *(ebp+8) 0/r32/eax +16617 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +16618 # if t->right contains addr, return true +16619 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +16620 (type-tree-contains? %eax 2) # addr => eax +16621 # we don't have to look at t->left as long as it's guaranteed to be an atom +16622 $addr-payload-contains-addr?:end: +16623 # . epilogue +16624 89/<- %esp 5/r32/ebp +16625 5d/pop-to-ebp +16626 c3/return +16627 +16628 type-tree-contains?: # t: (addr type-tree), n: type-id -> result/eax: boolean +16629 # . prologue +16630 55/push-ebp +16631 89/<- %ebp 4/r32/esp +16632 # . save registers +16633 51/push-ecx +16634 # if t is null, return false +16635 8b/-> *(ebp+8) 0/r32/eax +16636 3d/compare-eax-and 0/imm32 +16637 0f 84/jump-if-= $type-tree-contains?:end/disp32 # eax changes type +16638 # if t is an atom, return (t->value == n) +16639 81 7/subop/compare *eax 0/imm32/false +16640 { +16641 74/jump-if-= break/disp8 +16642 8b/-> *(ebp+0xc) 1/r32/ecx +16643 39/compare *(eax+4) 1/r32/ecx # Type-tree-value +16644 0f 94/set-if-= %al +16645 25/and-eax-with 0xff/imm32 +16646 eb/jump $type-tree-contains?:end/disp8 +16647 } +16648 # if t->left contains n, return true +16649 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +16650 (type-tree-contains? %eax *(ebp+0xc)) # => eax +16651 3d/compare-eax-and 0/imm32/false +16652 75/jump-if-!= $type-tree-contains?:end/disp8 +16653 # otherwise return whether t->right contains n +16654 8b/-> *(ebp+8) 0/r32/eax +16655 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +16656 (type-tree-contains? %eax *(ebp+0xc)) # => eax +16657 $type-tree-contains?:end: +16658 # . restore registers +16659 59/pop-to-ecx +16660 # . epilogue +16661 89/<- %esp 5/r32/ebp +16662 5d/pop-to-ebp +16663 c3/return +16664 +16665 function-exists?: # s: (addr slice) -> result/eax: boolean +16666 # . prologue +16667 55/push-ebp +16668 89/<- %ebp 4/r32/esp +16669 # . save registers +16670 51/push-ecx +16671 # var curr/ecx: (addr function) = functions +16672 (lookup *_Program-functions *_Program-functions->payload) # => eax +16673 89/<- %ecx 0/r32/eax +16674 { +16675 # if (curr == null) break +16676 81 7/subop/compare %ecx 0/imm32 +16677 74/jump-if-= break/disp8 +16678 # if (curr->name == s) return true +16679 { +16680 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +16681 (slice-equal? *(ebp+8) %eax) # => eax +16682 3d/compare-eax-and 0/imm32/false +16683 74/jump-if-= break/disp8 +16684 b8/copy-to-eax 1/imm32/true +16685 e9/jump $function-exists?:end/disp32 +16686 } +16687 # curr = curr->next +16688 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax +16689 89/<- %ecx 0/r32/eax +16690 # +16691 eb/jump loop/disp8 +16692 } +16693 # var curr/ecx: (addr function) = signatures +16694 (lookup *_Program-signatures *_Program-signatures->payload) # => eax +16695 89/<- %ecx 0/r32/eax +16696 { +16697 # if (curr == null) break +16698 81 7/subop/compare %ecx 0/imm32 +16699 74/jump-if-= break/disp8 +16700 # if (curr->name == s) return true +16701 { +16702 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +16703 (slice-equal? *(ebp+8) %eax) # => eax +16704 3d/compare-eax-and 0/imm32/false +16705 74/jump-if-= break/disp8 +16706 b8/copy-to-eax 1/imm32/true +16707 eb/jump $function-exists?:end/disp8 +16708 } +16709 # curr = curr->next +16710 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax +16711 89/<- %ecx 0/r32/eax +16712 # +16713 eb/jump loop/disp8 +16714 } +16715 # return false +16716 b8/copy-to-eax 0/imm32/false +16717 $function-exists?:end: +16718 # . restore registers +16719 59/pop-to-ecx +16720 # . epilogue +16721 89/<- %esp 5/r32/ebp +16722 5d/pop-to-ebp +16723 c3/return +16724 +16725 test-function-header-with-arg: +16726 # . prologue +16727 55/push-ebp +16728 89/<- %ebp 4/r32/esp +16729 # setup +16730 8b/-> *Primitive-type-ids 0/r32/eax +16731 89/<- *Type-id 0/r32/eax # stream-write +16732 c7 0/subop/copy *_Program-functions 0/imm32 +16733 c7 0/subop/copy *_Program-functions->payload 0/imm32 +16734 c7 0/subop/copy *_Program-types 0/imm32 +16735 c7 0/subop/copy *_Program-types->payload 0/imm32 +16736 c7 0/subop/copy *_Program-signatures 0/imm32 +16737 c7 0/subop/copy *_Program-signatures->payload 0/imm32 +16738 (clear-stream _test-input-stream) +16739 (write _test-input-stream "foo n: int {\n") +16740 # var result/ecx: function +16741 2b/subtract *Function-size 4/r32/esp +16742 89/<- %ecx 4/r32/esp +16743 (zero-out %ecx *Function-size) +16744 # var vars/ebx: (stack live-var 16) +16745 81 5/subop/subtract %esp 0xc0/imm32 +16746 68/push 0xc0/imm32/size +16747 68/push 0/imm32/top +16748 89/<- %ebx 4/r32/esp +16749 # convert +16750 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) +16751 # check result->name +16752 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +16753 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") +16754 # var v/edx: (addr var) = result->inouts->value +16755 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax +16756 (lookup *eax *(eax+4)) # List-value List-value => eax +16757 89/<- %edx 0/r32/eax +16758 # check v->name +16759 (lookup *edx *(edx+4)) # Var-name Var-name => eax +16760 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") +16761 # check v->type +16762 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +16763 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Type-tree-is-atom +16764 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Type-tree-value +16765 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Type-tree-right +16766 # . epilogue +16767 89/<- %esp 5/r32/ebp +16768 5d/pop-to-ebp +16769 c3/return +16770 +16771 test-function-header-with-multiple-args: +16772 # . prologue +16773 55/push-ebp +16774 89/<- %ebp 4/r32/esp +16775 # setup +16776 8b/-> *Primitive-type-ids 0/r32/eax +16777 89/<- *Type-id 0/r32/eax # stream-write +16778 c7 0/subop/copy *_Program-functions 0/imm32 +16779 c7 0/subop/copy *_Program-functions->payload 0/imm32 +16780 c7 0/subop/copy *_Program-types 0/imm32 +16781 c7 0/subop/copy *_Program-types->payload 0/imm32 +16782 c7 0/subop/copy *_Program-signatures 0/imm32 +16783 c7 0/subop/copy *_Program-signatures->payload 0/imm32 +16784 (clear-stream _test-input-stream) +16785 (write _test-input-stream "foo a: int, b: int c: int {\n") +16786 # result/ecx: function +16787 2b/subtract *Function-size 4/r32/esp +16788 89/<- %ecx 4/r32/esp +16789 (zero-out %ecx *Function-size) +16790 # var vars/ebx: (stack live-var 16) +16791 81 5/subop/subtract %esp 0xc0/imm32 +16792 68/push 0xc0/imm32/size +16793 68/push 0/imm32/top +16794 89/<- %ebx 4/r32/esp +16795 # convert +16796 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) +16797 # check result->name +16798 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +16799 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") +16800 # var inouts/edx: (addr list var) = lookup(result->inouts) +16801 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax +16802 89/<- %edx 0/r32/eax +16803 $test-function-header-with-multiple-args:inout0: +16804 # var v/ebx: (addr var) = lookup(inouts->value) +16805 (lookup *edx *(edx+4)) # List-value List-value => eax +16806 89/<- %ebx 0/r32/eax +16807 # check v->name +16808 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +16809 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name +16810 # check v->type +16811 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax +16812 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Type-tree-is-atom +16813 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Type-tree-value +16814 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Type-tree-right +16815 $test-function-header-with-multiple-args:inout1: +16816 # inouts = lookup(inouts->next) +16817 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +16818 89/<- %edx 0/r32/eax +16819 # v = lookup(inouts->value) +16820 (lookup *edx *(edx+4)) # List-value List-value => eax +16821 89/<- %ebx 0/r32/eax +16822 # check v->name +16823 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +16824 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name +16825 # check v->type +16826 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax +16827 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Type-tree-is-atom +16828 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Type-tree-value +16829 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Type-tree-right +16830 $test-function-header-with-multiple-args:inout2: +16831 # inouts = lookup(inouts->next) +16832 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +16833 89/<- %edx 0/r32/eax +16834 # v = lookup(inouts->value) +16835 (lookup *edx *(edx+4)) # List-value List-value => eax +16836 89/<- %ebx 0/r32/eax +16837 # check v->name +16838 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +16839 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name +16840 # check v->type +16841 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax +16842 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Type-tree-is-atom +16843 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Type-tree-value +16844 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Type-tree-right +16845 # . epilogue +16846 89/<- %esp 5/r32/ebp +16847 5d/pop-to-ebp +16848 c3/return +16849 +16850 test-function-header-with-multiple-args-and-outputs: +16851 # . prologue +16852 55/push-ebp +16853 89/<- %ebp 4/r32/esp +16854 # setup +16855 8b/-> *Primitive-type-ids 0/r32/eax +16856 89/<- *Type-id 0/r32/eax # stream-write +16857 c7 0/subop/copy *_Program-functions 0/imm32 +16858 c7 0/subop/copy *_Program-functions->payload 0/imm32 +16859 c7 0/subop/copy *_Program-types 0/imm32 +16860 c7 0/subop/copy *_Program-types->payload 0/imm32 +16861 c7 0/subop/copy *_Program-signatures 0/imm32 +16862 c7 0/subop/copy *_Program-signatures->payload 0/imm32 +16863 (clear-stream _test-input-stream) +16864 (write _test-input-stream "foo a: int, b: int, c: int -> _/ecx: int _/edx: int {\n") +16865 # result/ecx: function +16866 2b/subtract *Function-size 4/r32/esp +16867 89/<- %ecx 4/r32/esp +16868 (zero-out %ecx *Function-size) +16869 # var vars/ebx: (stack live-var 16) +16870 81 5/subop/subtract %esp 0xc0/imm32 +16871 68/push 0xc0/imm32/size +16872 68/push 0/imm32/top +16873 89/<- %ebx 4/r32/esp +16874 # convert +16875 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) +16876 # check result->name +16877 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +16878 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") +16879 # var inouts/edx: (addr list var) = lookup(result->inouts) +16880 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax +16881 89/<- %edx 0/r32/eax +16882 $test-function-header-with-multiple-args-and-outputs:inout0: +16883 # var v/ebx: (addr var) = lookup(inouts->value) +16884 (lookup *edx *(edx+4)) # List-value List-value => eax +16885 89/<- %ebx 0/r32/eax +16886 # check v->name +16887 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +16888 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") +16889 # check v->type +16890 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax +16891 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Type-tree-is-atom +16892 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Type-tree-value +16893 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Type-tree-right +16894 $test-function-header-with-multiple-args-and-outputs:inout1: +16895 # inouts = lookup(inouts->next) +16896 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +16897 89/<- %edx 0/r32/eax +16898 # v = lookup(inouts->value) +16899 (lookup *edx *(edx+4)) # List-value List-value => eax +16900 89/<- %ebx 0/r32/eax +16901 # check v->name +16902 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +16903 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") +16904 # check v->type +16905 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax +16906 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Type-tree-is-atom +16907 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Type-tree-value +16908 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Type-tree-right +16909 $test-function-header-with-multiple-args-and-outputs:inout2: +16910 # inouts = lookup(inouts->next) +16911 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +16912 89/<- %edx 0/r32/eax +16913 # v = lookup(inouts->value) +16914 (lookup *edx *(edx+4)) # List-value List-value => eax +16915 89/<- %ebx 0/r32/eax +16916 # check v->name +16917 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +16918 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") +16919 # check v->type +16920 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax +16921 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Type-tree-is-atom +16922 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Type-tree-value +16923 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Type-tree-right +16924 $test-function-header-with-multiple-args-and-outputs:out0: +16925 # var outputs/edx: (addr list var) = lookup(result->outputs) +16926 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +16927 89/<- %edx 0/r32/eax +16928 # v = lookup(outputs->value) +16929 (lookup *edx *(edx+4)) # List-value List-value => eax +16930 89/<- %ebx 0/r32/eax +16931 # check v->name +16932 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +16933 (check-strings-equal %eax "_" "F - test-function-header-with-multiple-args-and-outputs/output:0") +16934 # check v->register +16935 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +16936 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") +16937 # check v->type +16938 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax +16939 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Type-tree-is-atom +16940 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Type-tree-value +16941 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Type-tree-right +16942 $test-function-header-with-multiple-args-and-outputs:out1: +16943 # outputs = lookup(outputs->next) +16944 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +16945 89/<- %edx 0/r32/eax +16946 # v = lookup(inouts->value) +16947 (lookup *edx *(edx+4)) # List-value List-value => eax +16948 89/<- %ebx 0/r32/eax +16949 # check v->name +16950 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +16951 (check-strings-equal %eax "_" "F - test-function-header-with-multiple-args-and-outputs/output:1") +16952 # check v->register +16953 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +16954 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") +16955 # check v->type +16956 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax +16957 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Type-tree-is-atom +16958 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Type-tree-value +16959 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Type-tree-right +16960 # . epilogue +16961 89/<- %esp 5/r32/ebp +16962 5d/pop-to-ebp +16963 c3/return +16964 +16965 # format for variables with types +16966 # x: int +16967 # x: int, +16968 # x/eax: int +16969 # x/eax: int, +16970 # ignores at most one trailing comma +16971 # does not support other, non-register metadata +16972 # WARNING: modifies name +16973 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), fn-name: (addr array byte), err: (addr buffered-file), ed: (addr exit-descriptor) +16974 # pseudocode: +16975 # var s: slice +16976 # if (!slice-ends-with(name, ":")) +16977 # abort +16978 # --name->end to skip ':' +16979 # next-token-from-slice(name->start, name->end, '/', s) +16980 # new-var-from-slice(s, out) +16981 # ## register +16982 # next-token-from-slice(s->end, name->end, '/', s) +16983 # if (!slice-empty?(s)) +16984 # out->register = slice-to-string(s) +16985 # ## type +16986 # var type: (handle type-tree) = parse-type(first-line) +16987 # out->type = type +16988 # +16989 # . prologue +16990 55/push-ebp +16991 89/<- %ebp 4/r32/esp +16992 # . save registers +16993 50/push-eax +16994 51/push-ecx +16995 52/push-edx +16996 53/push-ebx +16997 56/push-esi +16998 57/push-edi +16999 # esi = name +17000 8b/-> *(ebp+8) 6/r32/esi +17001 # if (!slice-ends-with?(name, ":")) abort +17002 8b/-> *(esi+4) 1/r32/ecx # Slice-end +17003 49/decrement-ecx +17004 8a/copy-byte *ecx 1/r32/CL +17005 81 4/subop/and %ecx 0xff/imm32 +17006 81 7/subop/compare %ecx 0x3a/imm32/colon +17007 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 +17008 # --name->end to skip ':' +17009 ff 1/subop/decrement *(esi+4) +17010 # var s/ecx: slice +17011 68/push 0/imm32/end +17012 68/push 0/imm32/start +17013 89/<- %ecx 4/r32/esp +17014 $parse-var-with-type:parse-name: +17015 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' +17016 $parse-var-with-type:create-var: +17017 # new-var-from-slice(s, out) +17018 (new-var-from-slice Heap %ecx *(ebp+0x10)) +17019 # save out->register +17020 $parse-var-with-type:save-register: +17021 # . var out-addr/edi: (addr var) = lookup(*out) +17022 8b/-> *(ebp+0x10) 7/r32/edi +17023 (lookup *edi *(edi+4)) # => eax +17024 89/<- %edi 0/r32/eax +17025 # . s = next-token(...) +17026 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' +17027 # . if (!slice-empty?(s)) out->register = slice-to-string(s) +17028 { +17029 $parse-var-with-type:write-register: +17030 (slice-empty? %ecx) # => eax +17031 3d/compare-eax-and 0/imm32/false +17032 75/jump-if-!= break/disp8 +17033 # out->register = slice-to-string(s) +17034 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register +17035 (slice-to-string Heap %ecx %eax) +17036 } +17037 $parse-var-with-type:save-type: +17038 8d/copy-address *(edi+8) 0/r32/eax # Var-type +17039 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x18) *(ebp+0x1c)) +17040 $parse-var-with-type:check-register: +17041 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +17042 3d/compare-eax-and 0/imm32 +17043 74/jump-if-= $parse-var-with-type:end/disp8 +17044 (float-register? %eax) # => eax +17045 { +17046 3d/compare-eax-and 0/imm32/false +17047 74/jump-if-= break/disp8 +17048 # var is in a float register; ensure type is float +17049 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +17050 (simple-mu-type? %eax 0xf) # float => eax +17051 3d/compare-eax-and 0/imm32/false +17052 0f 84/jump-if-= $parse-var-with-type:error-non-float-in-floating-point-register/disp32 +17053 eb/jump $parse-var-with-type:end/disp8 +17054 } +17055 # var is not in a float register; ensure type is not float +17056 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +17057 (simple-mu-type? %eax 0xf) # float => eax +17058 3d/compare-eax-and 0/imm32/false +17059 0f 85/jump-if-!= $parse-var-with-type:error-float-in-integer-register/disp32 +17060 $parse-var-with-type:end: +17061 # . reclaim locals +17062 81 0/subop/add %esp 8/imm32 +17063 # . restore registers +17064 5f/pop-to-edi +17065 5e/pop-to-esi +17066 5b/pop-to-ebx +17067 5a/pop-to-edx +17068 59/pop-to-ecx +17069 58/pop-to-eax +17070 # . epilogue +17071 89/<- %esp 5/r32/ebp +17072 5d/pop-to-ebp +17073 c3/return +17074 +17075 $parse-var-with-type:abort: +17076 # error("fn " fn ": var should have form 'name: type' in '" line "'\n") +17077 (write-buffered *(ebp+0x18) "fn ") +17078 (write-buffered *(ebp+0x18) *(ebp+0x14)) +17079 (write-buffered *(ebp+0x18) ": var should have form 'name: type' in '") +17080 (flush *(ebp+0x18)) +17081 (rewind-stream *(ebp+0xc)) +17082 (write-stream-data *(ebp+0x18) *(ebp+0xc)) +17083 (write-buffered *(ebp+0x18) "'\n") +17084 (flush *(ebp+0x18)) +17085 (stop *(ebp+0x1c) 1) +17086 # never gets here +17087 +17088 $parse-var-with-type:error-float-in-integer-register: +17089 # error("fn " fn ": float var '" var "' should be in a floating-point register\n") +17090 (write-buffered *(ebp+0x18) "fn ") +17091 (write-buffered *(ebp+0x18) *(ebp+0x14)) +17092 (write-buffered *(ebp+0x18) ": float var '") +17093 (lookup *edi *(edi+4)) # Var-name Var-name => eax +17094 (write-buffered *(ebp+0x18) %eax) +17095 (write-buffered *(ebp+0x18) "' should be in a floating-point register\n") +17096 (flush *(ebp+0x18)) +17097 (stop *(ebp+0x1c) 1) +17098 # never gets here +17099 +17100 $parse-var-with-type:error-non-float-in-floating-point-register: +17101 # error("fn " fn ": non-float var '" var "' should be in an integer register\n") +17102 (write-buffered *(ebp+0x18) "fn ") +17103 (write-buffered *(ebp+0x18) *(ebp+0x14)) +17104 (write-buffered *(ebp+0x18) ": non-float var '") +17105 (lookup *edi *(edi+4)) # Var-name Var-name => eax +17106 (write-buffered *(ebp+0x18) %eax) +17107 (write-buffered *(ebp+0x18) "' should be in an integer register\n") +17108 (flush *(ebp+0x18)) +17109 (stop *(ebp+0x1c) 1) +17110 # never gets here +17111 +17112 float-register?: # r: (addr array byte) -> result/eax: boolean +17113 # . prologue +17114 55/push-ebp +17115 89/<- %ebp 4/r32/esp +17116 # +17117 (get Mu-registers-unique *(ebp+8) 0xc "Mu-registers-unique") # => eax +17118 81 7/subop/compare *eax 8/imm32/start-of-floating-point-registers +17119 0f 9d/set-if->= %al +17120 25/and-eax-with 0xff/imm32 +17121 $float-register?:end: +17122 # . epilogue +17123 89/<- %esp 5/r32/ebp +17124 5d/pop-to-ebp +17125 c3/return +17126 +17127 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) +17128 # pseudocode: +17129 # var s: slice = next-mu-token(in) +17130 # assert s != "" +17131 # assert s != "->" +17132 # assert s != "{" +17133 # assert s != "}" +17134 # if s == ")" +17135 # return +17136 # out = allocate(Type-tree) +17137 # if s != "(" +17138 # HACK: if s is an int, parse and return it +17139 # out->is-atom? = true +17140 # if (s[0] == "_") +17141 # out->value = type-parameter +17142 # out->parameter-name = slice-to-string(ad, s) +17143 # else +17144 # out->value = pos-or-insert-slice(Type-id, s) +17145 # return +17146 # out->left = parse-type(ad, in) +17147 # out->right = parse-type-tree(ad, in) +17148 # +17149 # . prologue +17150 55/push-ebp +17151 89/<- %ebp 4/r32/esp +17152 # . save registers +17153 50/push-eax +17154 51/push-ecx +17155 52/push-edx +17156 # clear out +17157 (zero-out *(ebp+0x10) *Handle-size) +17158 # var s/ecx: slice +17159 68/push 0/imm32 +17160 68/push 0/imm32 +17161 89/<- %ecx 4/r32/esp +17162 # s = next-mu-token(in) +17163 (next-mu-token *(ebp+0xc) %ecx) +17164 #? (write-buffered Stderr "tok: ") +17165 #? (write-slice-buffered Stderr %ecx) +17166 #? (write-buffered Stderr "$\n") +17167 #? (flush Stderr) +17168 # assert s != "" +17169 (slice-equal? %ecx "") # => eax +17170 3d/compare-eax-and 0/imm32/false +17171 0f 85/jump-if-!= $parse-type:abort/disp32 +17172 # assert s != "{" +17173 (slice-equal? %ecx "{") # => eax +17174 3d/compare-eax-and 0/imm32/false +17175 0f 85/jump-if-!= $parse-type:abort/disp32 +17176 # assert s != "}" +17177 (slice-equal? %ecx "}") # => eax +17178 3d/compare-eax-and 0/imm32/false +17179 0f 85/jump-if-!= $parse-type:abort/disp32 +17180 # assert s != "->" +17181 (slice-equal? %ecx "->") # => eax +17182 3d/compare-eax-and 0/imm32/false +17183 0f 85/jump-if-!= $parse-type:abort/disp32 +17184 # if (s == ")") return +17185 (slice-equal? %ecx ")") # => eax +17186 3d/compare-eax-and 0/imm32/false +17187 0f 85/jump-if-!= $parse-type:end/disp32 +17188 # out = new tree +17189 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) +17190 # var out-addr/edx: (addr type-tree) = lookup(*out) +17191 8b/-> *(ebp+0x10) 2/r32/edx +17192 (lookup *edx *(edx+4)) # => eax +17193 89/<- %edx 0/r32/eax +17194 { +17195 # if (s != "(") break +17196 (slice-equal? %ecx "(") # => eax +17197 3d/compare-eax-and 0/imm32/false +17198 0f 85/jump-if-!= break/disp32 +17199 # if s is a number, store it in the type's size field 17200 { -17201 $parse-type:check-for-type-parameter: +17201 $parse-type:check-for-int: 17202 # var tmp/eax: byte = *s->slice 17203 8b/-> *ecx 0/r32/eax 17204 8a/copy-byte *eax 0/r32/AL 17205 25/and-eax-with 0xff/imm32 -17206 # if (tmp != '_') break -17207 3d/compare-eax-and 0x5f/imm32/_ -17208 75/jump-if-!= break/disp8 -17209 $parse-type:type-parameter: -17210 # out->value = type-parameter -17211 c7 0/subop/copy *(edx+4) 0xa/imm32/type-parameter # Type-tree-value -17212 # out->parameter-name = slice-to-string(ad, s) -17213 8d/copy-address *(edx+8) 0/r32/eax # Type-tree-parameter-name -17214 (slice-to-string *(ebp+8) %ecx %eax) -17215 e9/jump $parse-type:end/disp32 -17216 } -17217 $parse-type:non-type-parameter: -17218 # out->value = pos-or-insert-slice(Type-id, s) -17219 (pos-or-insert-slice Type-id %ecx) # => eax -17220 89/<- *(edx+4) 0/r32/eax # Type-tree-value -17221 e9/jump $parse-type:end/disp32 -17222 } -17223 $parse-type:non-atom: -17224 # otherwise s == "(" -17225 # out->left = parse-type(ad, in) -17226 8d/copy-address *(edx+4) 0/r32/eax # Type-tree-left -17227 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) -17228 # out->right = parse-type-tree(ad, in) -17229 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right -17230 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) -17231 $parse-type:end: -17232 # . reclaim locals -17233 81 0/subop/add %esp 8/imm32 -17234 # . restore registers -17235 5a/pop-to-edx -17236 59/pop-to-ecx -17237 58/pop-to-eax -17238 # . epilogue -17239 89/<- %esp 5/r32/ebp -17240 5d/pop-to-ebp -17241 c3/return -17242 -17243 $parse-type:abort: -17244 # error("unexpected token when parsing type: '" s "'\n") -17245 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '") -17246 (write-slice-buffered *(ebp+0x14) %ecx) -17247 (write-buffered *(ebp+0x14) "'\n") -17248 (flush *(ebp+0x14)) -17249 (stop *(ebp+0x18) 1) -17250 # never gets here -17251 -17252 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) -17253 # pseudocode: -17254 # var tmp: (handle type-tree) = parse-type(ad, in) -17255 # if tmp == 0 -17256 # return 0 -17257 # out = allocate(Type-tree) -17258 # out->left = tmp -17259 # out->right = parse-type-tree(ad, in) -17260 # -17261 # . prologue -17262 55/push-ebp -17263 89/<- %ebp 4/r32/esp -17264 # . save registers -17265 50/push-eax -17266 51/push-ecx -17267 52/push-edx -17268 # -17269 (zero-out *(ebp+0x10) *Handle-size) -17270 # var tmp/ecx: (handle type-tree) -17271 68/push 0/imm32 -17272 68/push 0/imm32 -17273 89/<- %ecx 4/r32/esp -17274 # tmp = parse-type(ad, in) -17275 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18)) -17276 # if (tmp == 0) return -17277 81 7/subop/compare *ecx 0/imm32 -17278 74/jump-if-= $parse-type-tree:end/disp8 -17279 # out = new tree -17280 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) -17281 # var out-addr/edx: (addr tree) = lookup(*out) -17282 8b/-> *(ebp+0x10) 2/r32/edx -17283 (lookup *edx *(edx+4)) # => eax -17284 89/<- %edx 0/r32/eax -17285 # out->left = tmp -17286 8b/-> *ecx 0/r32/eax -17287 89/<- *(edx+4) 0/r32/eax # Type-tree-left -17288 8b/-> *(ecx+4) 0/r32/eax -17289 89/<- *(edx+8) 0/r32/eax # Type-tree-left -17290 # out->right = parse-type-tree(ad, in) -17291 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right -17292 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) -17293 $parse-type-tree:end: -17294 # . reclaim locals -17295 81 0/subop/add %esp 8/imm32 -17296 # . restore registers -17297 5a/pop-to-edx -17298 59/pop-to-ecx -17299 58/pop-to-eax -17300 # . epilogue -17301 89/<- %esp 5/r32/ebp -17302 5d/pop-to-ebp -17303 c3/return -17304 -17305 next-mu-token: # in: (addr stream byte), out: (addr slice) -17306 # pseudocode: -17307 # start: -17308 # skip-chars-matching-whitespace(in) -17309 # if in->read >= in->write # end of in -17310 # out = {0, 0} -17311 # return -17312 # out->start = &in->data[in->read] -17313 # var curr-byte/eax: byte = in->data[in->read] -17314 # if curr->byte == ',' # comment token -17315 # ++in->read -17316 # goto start -17317 # if curr-byte == '#' # comment -17318 # goto done # treat as eof -17319 # if curr-byte == '"' # string literal -17320 # skip-string(in) -17321 # goto done # no metadata -17322 # if curr-byte == '(' -17323 # ++in->read -17324 # goto done -17325 # if curr-byte == ')' -17326 # ++in->read -17327 # goto done -17328 # # read a word -17329 # while true -17330 # if in->read >= in->write -17331 # break -17332 # curr-byte = in->data[in->read] -17333 # if curr-byte == ' ' -17334 # break -17335 # if curr-byte == '\r' -17336 # break -17337 # if curr-byte == '\n' -17338 # break -17339 # if curr-byte == '(' -17340 # break -17341 # if curr-byte == ')' -17342 # break -17343 # if curr-byte == ',' -17344 # break -17345 # ++in->read -17346 # done: -17347 # out->end = &in->data[in->read] -17348 # -17349 # . prologue -17350 55/push-ebp -17351 89/<- %ebp 4/r32/esp -17352 # . save registers -17353 50/push-eax -17354 51/push-ecx -17355 56/push-esi -17356 57/push-edi -17357 # esi = in -17358 8b/-> *(ebp+8) 6/r32/esi -17359 # edi = out -17360 8b/-> *(ebp+0xc) 7/r32/edi -17361 $next-mu-token:start: -17362 (skip-chars-matching-whitespace %esi) -17363 $next-mu-token:check0: -17364 # if (in->read >= in->write) return out = {0, 0} -17365 # . ecx = in->read -17366 8b/-> *(esi+4) 1/r32/ecx -17367 # . if (ecx >= in->write) return out = {0, 0} -17368 3b/compare<- *esi 1/r32/ecx -17369 c7 0/subop/copy *edi 0/imm32 -17370 c7 0/subop/copy *(edi+4) 0/imm32 -17371 0f 8d/jump-if->= $next-mu-token:end/disp32 -17372 # out->start = &in->data[in->read] -17373 8d/copy-address *(esi+ecx+0xc) 0/r32/eax -17374 89/<- *edi 0/r32/eax -17375 # var curr-byte/eax: byte = in->data[in->read] -17376 31/xor-with %eax 0/r32/eax -17377 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL -17378 { -17379 $next-mu-token:check-for-comma: -17380 # if (curr-byte != ',') break -17381 3d/compare-eax-and 0x2c/imm32/comma -17382 75/jump-if-!= break/disp8 -17383 # ++in->read -17384 ff 0/subop/increment *(esi+4) -17385 # restart -17386 e9/jump $next-mu-token:start/disp32 -17387 } -17388 { -17389 $next-mu-token:check-for-comment: -17390 # if (curr-byte != '#') break -17391 3d/compare-eax-and 0x23/imm32/pound -17392 75/jump-if-!= break/disp8 -17393 # return eof -17394 e9/jump $next-mu-token:done/disp32 -17395 } -17396 { -17397 $next-mu-token:check-for-string-literal: -17398 # if (curr-byte != '"') break -17399 3d/compare-eax-and 0x22/imm32/dquote -17400 75/jump-if-!= break/disp8 -17401 (skip-string %esi) -17402 # return -17403 e9/jump $next-mu-token:done/disp32 -17404 } -17405 { -17406 $next-mu-token:check-for-open-paren: -17407 # if (curr-byte != '(') break -17408 3d/compare-eax-and 0x28/imm32/open-paren -17409 75/jump-if-!= break/disp8 -17410 # ++in->read -17411 ff 0/subop/increment *(esi+4) -17412 # return -17413 e9/jump $next-mu-token:done/disp32 -17414 } -17415 { -17416 $next-mu-token:check-for-close-paren: -17417 # if (curr-byte != ')') break -17418 3d/compare-eax-and 0x29/imm32/close-paren -17419 75/jump-if-!= break/disp8 -17420 # ++in->read -17421 ff 0/subop/increment *(esi+4) -17422 # return -17423 e9/jump $next-mu-token:done/disp32 -17424 } -17425 { -17426 $next-mu-token:regular-word-without-metadata: -17427 # if (in->read >= in->write) break -17428 # . ecx = in->read -17429 8b/-> *(esi+4) 1/r32/ecx -17430 # . if (ecx >= in->write) break -17431 3b/compare<- *esi 1/r32/ecx -17432 7d/jump-if->= break/disp8 -17433 # var c/eax: byte = in->data[in->read] -17434 31/xor-with %eax 0/r32/eax -17435 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL -17436 # if (c == ' ') break -17437 3d/compare-eax-and 0x20/imm32/space -17438 74/jump-if-= break/disp8 -17439 # if (c == '\r') break -17440 3d/compare-eax-and 0xd/imm32/carriage-return -17441 74/jump-if-= break/disp8 -17442 # if (c == '\n') break -17443 3d/compare-eax-and 0xa/imm32/newline -17444 74/jump-if-= break/disp8 -17445 # if (c == '(') break -17446 3d/compare-eax-and 0x28/imm32/open-paren -17447 0f 84/jump-if-= break/disp32 -17448 # if (c == ')') break -17449 3d/compare-eax-and 0x29/imm32/close-paren -17450 0f 84/jump-if-= break/disp32 -17451 # if (c == ',') break -17452 3d/compare-eax-and 0x2c/imm32/comma -17453 0f 84/jump-if-= break/disp32 -17454 # ++in->read -17455 ff 0/subop/increment *(esi+4) -17456 # -17457 e9/jump loop/disp32 -17458 } -17459 $next-mu-token:done: -17460 # out->end = &in->data[in->read] -17461 8b/-> *(esi+4) 1/r32/ecx -17462 8d/copy-address *(esi+ecx+0xc) 0/r32/eax -17463 89/<- *(edi+4) 0/r32/eax -17464 $next-mu-token:end: -17465 # . restore registers -17466 5f/pop-to-edi -17467 5e/pop-to-esi -17468 59/pop-to-ecx -17469 58/pop-to-eax -17470 # . epilogue -17471 89/<- %esp 5/r32/ebp -17472 5d/pop-to-ebp -17473 c3/return -17474 -17475 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int -17476 # . prologue -17477 55/push-ebp -17478 89/<- %ebp 4/r32/esp -17479 # if (pos-slice(arr, s) != -1) return it -17480 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax -17481 3d/compare-eax-and -1/imm32 -17482 75/jump-if-!= $pos-or-insert-slice:end/disp8 -17483 $pos-or-insert-slice:insert: -17484 # var s2/eax: (handle array byte) -17485 68/push 0/imm32 -17486 68/push 0/imm32 -17487 89/<- %eax 4/r32/esp -17488 (slice-to-string Heap *(ebp+0xc) %eax) -17489 # throw away alloc-id -17490 (lookup *eax *(eax+4)) # => eax -17491 (write-int *(ebp+8) %eax) -17492 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax -17493 $pos-or-insert-slice:end: -17494 # . reclaim locals -17495 81 0/subop/add %esp 8/imm32 -17496 # . epilogue -17497 89/<- %esp 5/r32/ebp -17498 5d/pop-to-ebp -17499 c3/return -17500 -17501 # return the index in an array of strings matching 's', -1 if not found -17502 # index is denominated in elements, not bytes -17503 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int -17504 # . prologue -17505 55/push-ebp -17506 89/<- %ebp 4/r32/esp -17507 # . save registers -17508 51/push-ecx -17509 52/push-edx -17510 53/push-ebx -17511 56/push-esi -17512 #? (write-buffered Stderr "pos-slice: ") -17513 #? (write-slice-buffered Stderr *(ebp+0xc)) -17514 #? (write-buffered Stderr "\n") -17515 #? (flush Stderr) -17516 # esi = arr -17517 8b/-> *(ebp+8) 6/r32/esi -17518 # var index/ecx: int = 0 -17519 b9/copy-to-ecx 0/imm32 -17520 # var curr/edx: (addr (addr array byte)) = arr->data -17521 8d/copy-address *(esi+0xc) 2/r32/edx -17522 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] -17523 8b/-> *esi 3/r32/ebx -17524 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx -17525 { -17526 #? (write-buffered Stderr " ") -17527 #? (write-int32-hex-buffered Stderr %ecx) -17528 #? (write-buffered Stderr "\n") -17529 #? (flush Stderr) -17530 # if (curr >= max) return -1 -17531 39/compare %edx 3/r32/ebx -17532 b8/copy-to-eax -1/imm32 -17533 73/jump-if-addr>= $pos-slice:end/disp8 -17534 # if (slice-equal?(s, *curr)) break -17535 (slice-equal? *(ebp+0xc) *edx) # => eax -17536 3d/compare-eax-and 0/imm32/false -17537 75/jump-if-!= break/disp8 -17538 # ++index -17539 41/increment-ecx -17540 # curr += 4 -17541 81 0/subop/add %edx 4/imm32 -17542 # -17543 eb/jump loop/disp8 -17544 } -17545 # return index -17546 89/<- %eax 1/r32/ecx -17547 $pos-slice:end: -17548 #? (write-buffered Stderr "=> ") -17549 #? (write-int32-hex-buffered Stderr %eax) -17550 #? (write-buffered Stderr "\n") -17551 # . restore registers -17552 5e/pop-to-esi -17553 5b/pop-to-ebx -17554 5a/pop-to-edx -17555 59/pop-to-ecx -17556 # . epilogue -17557 89/<- %esp 5/r32/ebp -17558 5d/pop-to-ebp -17559 c3/return -17560 -17561 test-parse-var-with-type: -17562 # . prologue -17563 55/push-ebp -17564 89/<- %ebp 4/r32/esp -17565 # setup -17566 8b/-> *Primitive-type-ids 0/r32/eax -17567 89/<- *Type-id 0/r32/eax # stream-write -17568 # (eax..ecx) = "x:" -17569 b8/copy-to-eax "x:"/imm32 -17570 8b/-> *eax 1/r32/ecx -17571 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17572 05/add-to-eax 4/imm32 -17573 # var slice/ecx: slice = {eax, ecx} -17574 51/push-ecx -17575 50/push-eax -17576 89/<- %ecx 4/r32/esp -17577 # _test-input-stream contains "int" -17578 (clear-stream _test-input-stream) -17579 (write _test-input-stream "int") -17580 # var v/edx: (handle var) -17581 68/push 0/imm32 -17582 68/push 0/imm32 -17583 89/<- %edx 4/r32/esp -17584 # -17585 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) -17586 # var v-addr/edx: (addr var) = lookup(v) -17587 (lookup *edx *(edx+4)) # => eax -17588 89/<- %edx 0/r32/eax -17589 # check v-addr->name -17590 (lookup *edx *(edx+4)) # Var-name Var-name => eax -17591 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") -17592 # check v-addr->type -17593 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -17594 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Type-tree-is-atom -17595 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Type-tree-value -17596 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Type-tree-right -17597 # . epilogue -17598 89/<- %esp 5/r32/ebp -17599 5d/pop-to-ebp -17600 c3/return -17601 -17602 test-parse-var-with-type-and-register: -17603 # . prologue -17604 55/push-ebp -17605 89/<- %ebp 4/r32/esp -17606 # setup -17607 8b/-> *Primitive-type-ids 0/r32/eax -17608 89/<- *Type-id 0/r32/eax # stream-write -17609 # (eax..ecx) = "x/eax:" -17610 b8/copy-to-eax "x/eax:"/imm32 -17611 8b/-> *eax 1/r32/ecx -17612 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17613 05/add-to-eax 4/imm32 -17614 # var slice/ecx: slice = {eax, ecx} -17615 51/push-ecx -17616 50/push-eax -17617 89/<- %ecx 4/r32/esp -17618 # _test-input-stream contains "int" -17619 (clear-stream _test-input-stream) -17620 (write _test-input-stream "int") -17621 # var v/edx: (handle var) -17622 68/push 0/imm32 -17623 68/push 0/imm32 -17624 89/<- %edx 4/r32/esp -17625 # -17626 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) -17627 # var v-addr/edx: (addr var) = lookup(v) -17628 (lookup *edx *(edx+4)) # => eax -17629 89/<- %edx 0/r32/eax -17630 # check v-addr->name -17631 (lookup *edx *(edx+4)) # Var-name Var-name => eax -17632 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") -17633 # check v-addr->register -17634 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -17635 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") -17636 # check v-addr->type -17637 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -17638 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Type-tree-is-atom -17639 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Type-tree-left -17640 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Type-tree-right -17641 # . epilogue -17642 89/<- %esp 5/r32/ebp -17643 5d/pop-to-ebp -17644 c3/return -17645 -17646 test-parse-var-with-trailing-characters: -17647 # . prologue -17648 55/push-ebp -17649 89/<- %ebp 4/r32/esp -17650 # setup -17651 8b/-> *Primitive-type-ids 0/r32/eax -17652 89/<- *Type-id 0/r32/eax # stream-write -17653 # (eax..ecx) = "x:" -17654 b8/copy-to-eax "x:"/imm32 -17655 8b/-> *eax 1/r32/ecx -17656 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17657 05/add-to-eax 4/imm32 -17658 # var slice/ecx: slice = {eax, ecx} -17659 51/push-ecx -17660 50/push-eax -17661 89/<- %ecx 4/r32/esp -17662 # _test-input-stream contains "int," -17663 (clear-stream _test-input-stream) -17664 (write _test-input-stream "int,") -17665 # var v/edx: (handle var) -17666 68/push 0/imm32 -17667 68/push 0/imm32 -17668 89/<- %edx 4/r32/esp -17669 # -17670 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) -17671 # var v-addr/edx: (addr var) = lookup(v) -17672 (lookup *edx *(edx+4)) # => eax -17673 89/<- %edx 0/r32/eax -17674 # check v-addr->name -17675 (lookup *edx *(edx+4)) # Var-name Var-name => eax -17676 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") -17677 # check v-addr->register -17678 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register -17679 # check v-addr->type -17680 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -17681 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Type-tree-is-atom -17682 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-left -17683 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-right -17684 # . epilogue -17685 89/<- %esp 5/r32/ebp -17686 5d/pop-to-ebp -17687 c3/return -17688 -17689 test-parse-var-with-register-and-trailing-characters: -17690 # . prologue -17691 55/push-ebp -17692 89/<- %ebp 4/r32/esp -17693 # setup -17694 8b/-> *Primitive-type-ids 0/r32/eax -17695 89/<- *Type-id 0/r32/eax # stream-write -17696 # (eax..ecx) = "x/eax:" -17697 b8/copy-to-eax "x/eax:"/imm32 -17698 8b/-> *eax 1/r32/ecx -17699 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17700 05/add-to-eax 4/imm32 -17701 # var slice/ecx: slice = {eax, ecx} -17702 51/push-ecx -17703 50/push-eax -17704 89/<- %ecx 4/r32/esp -17705 # _test-input-stream contains "int," -17706 (clear-stream _test-input-stream) -17707 (write _test-input-stream "int,") -17708 # var v/edx: (handle var) -17709 68/push 0/imm32 -17710 68/push 0/imm32 -17711 89/<- %edx 4/r32/esp -17712 # -17713 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) -17714 # var v-addr/edx: (addr var) = lookup(v) -17715 (lookup *edx *(edx+4)) # => eax -17716 89/<- %edx 0/r32/eax -17717 # check v-addr->name -17718 (lookup *edx *(edx+4)) # Var-name Var-name => eax -17719 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") -17720 # check v-addr->register -17721 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -17722 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") -17723 # check v-addr->type -17724 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -17725 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Type-tree-is-atom -17726 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Type-tree-left -17727 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Type-tree-right -17728 # . epilogue -17729 89/<- %esp 5/r32/ebp -17730 5d/pop-to-ebp -17731 c3/return -17732 -17733 test-parse-var-with-compound-type: -17734 # . prologue -17735 55/push-ebp -17736 89/<- %ebp 4/r32/esp -17737 # setup -17738 8b/-> *Primitive-type-ids 0/r32/eax -17739 89/<- *Type-id 0/r32/eax # stream-write -17740 # (eax..ecx) = "x:" -17741 b8/copy-to-eax "x:"/imm32 -17742 8b/-> *eax 1/r32/ecx -17743 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17744 05/add-to-eax 4/imm32 -17745 # var slice/ecx: slice = {eax, ecx} -17746 51/push-ecx -17747 50/push-eax -17748 89/<- %ecx 4/r32/esp -17749 # _test-input-stream contains "(addr int)" -17750 (clear-stream _test-input-stream) -17751 (write _test-input-stream "(addr int)") -17752 # var v/edx: (handle var) -17753 68/push 0/imm32 -17754 68/push 0/imm32 -17755 89/<- %edx 4/r32/esp -17756 # -17757 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) -17758 # var v-addr/edx: (addr var) = lookup(v) -17759 (lookup *edx *(edx+4)) # => eax -17760 89/<- %edx 0/r32/eax -17761 # check v-addr->name -17762 (lookup *edx *(edx+4)) # Var-name Var-name => eax -17763 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") -17764 # check v-addr->register -17765 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register -17766 # - check v-addr->type -17767 # var type/edx: (addr type-tree) = var->type -17768 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -17769 89/<- %edx 0/r32/eax -17770 # type is a non-atom -17771 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Type-tree-is-atom -17772 # type->left == atom(addr) -17773 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -17774 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Type-tree-is-atom -17775 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Type-tree-value -17776 # type->right->left == atom(int) -17777 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax -17778 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -17779 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Type-tree-is-atom -17780 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Type-tree-value -17781 # type->right->right == null -17782 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Type-tree-right -17783 # . epilogue -17784 89/<- %esp 5/r32/ebp -17785 5d/pop-to-ebp -17786 c3/return -17787 -17788 # identifier starts with a letter or '$' or '_' -17789 # no constraints at the moment on later letters -17790 # all we really want to do so far is exclude '{', '}' and '->' -17791 identifier?: # in: (addr slice) -> result/eax: boolean -17792 # . prologue -17793 55/push-ebp -17794 89/<- %ebp 4/r32/esp -17795 # if (slice-empty?(in)) return false -17796 (slice-empty? *(ebp+8)) # => eax -17797 3d/compare-eax-and 0/imm32/false -17798 75/jump-if-!= $identifier?:false/disp8 -17799 # var c/eax: byte = *in->start -17800 8b/-> *(ebp+8) 0/r32/eax -17801 8b/-> *eax 0/r32/eax -17802 8a/copy-byte *eax 0/r32/AL -17803 25/and-eax-with 0xff/imm32 -17804 # if (c == '$') return true -17805 3d/compare-eax-and 0x24/imm32/$ -17806 74/jump-if-= $identifier?:true/disp8 -17807 # if (c == '_') return true -17808 3d/compare-eax-and 0x5f/imm32/_ -17809 74/jump-if-= $identifier?:true/disp8 -17810 # drop case -17811 25/and-eax-with 0x5f/imm32 -17812 # if (c < 'A') return false -17813 3d/compare-eax-and 0x41/imm32/A -17814 7c/jump-if-< $identifier?:false/disp8 -17815 # if (c > 'Z') return false -17816 3d/compare-eax-and 0x5a/imm32/Z -17817 7f/jump-if-> $identifier?:false/disp8 -17818 # otherwise return true -17819 $identifier?:true: -17820 b8/copy-to-eax 1/imm32/true -17821 eb/jump $identifier?:end/disp8 -17822 $identifier?:false: -17823 b8/copy-to-eax 0/imm32/false -17824 $identifier?:end: -17825 # . epilogue -17826 89/<- %esp 5/r32/ebp -17827 5d/pop-to-ebp -17828 c3/return -17829 -17830 test-is-identifier-dollar: -17831 # . prologue -17832 55/push-ebp -17833 89/<- %ebp 4/r32/esp -17834 # (eax..ecx) = "$a" -17835 b8/copy-to-eax "$a"/imm32 -17836 8b/-> *eax 1/r32/ecx -17837 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17838 05/add-to-eax 4/imm32 -17839 # var slice/ecx: slice = {eax, ecx} -17840 51/push-ecx -17841 50/push-eax -17842 89/<- %ecx 4/r32/esp -17843 # -17844 (identifier? %ecx) -17845 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") -17846 # . epilogue -17847 89/<- %esp 5/r32/ebp -17848 5d/pop-to-ebp -17849 c3/return -17850 -17851 test-is-identifier-underscore: -17852 # . prologue -17853 55/push-ebp -17854 89/<- %ebp 4/r32/esp -17855 # (eax..ecx) = "_a" -17856 b8/copy-to-eax "_a"/imm32 -17857 8b/-> *eax 1/r32/ecx -17858 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17859 05/add-to-eax 4/imm32 -17860 # var slice/ecx: slice = {eax, ecx} -17861 51/push-ecx -17862 50/push-eax -17863 89/<- %ecx 4/r32/esp -17864 # -17865 (identifier? %ecx) -17866 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") -17867 # . epilogue -17868 89/<- %esp 5/r32/ebp -17869 5d/pop-to-ebp -17870 c3/return -17871 -17872 test-is-identifier-a: -17873 # . prologue -17874 55/push-ebp -17875 89/<- %ebp 4/r32/esp -17876 # (eax..ecx) = "a$" -17877 b8/copy-to-eax "a$"/imm32 -17878 8b/-> *eax 1/r32/ecx -17879 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17880 05/add-to-eax 4/imm32 -17881 # var slice/ecx: slice = {eax, ecx} -17882 51/push-ecx -17883 50/push-eax -17884 89/<- %ecx 4/r32/esp -17885 # -17886 (identifier? %ecx) -17887 (check-ints-equal %eax 1 "F - test-is-identifier-a") -17888 # . epilogue -17889 89/<- %esp 5/r32/ebp -17890 5d/pop-to-ebp -17891 c3/return -17892 -17893 test-is-identifier-z: -17894 # . prologue -17895 55/push-ebp -17896 89/<- %ebp 4/r32/esp -17897 # (eax..ecx) = "z$" -17898 b8/copy-to-eax "z$"/imm32 -17899 8b/-> *eax 1/r32/ecx -17900 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17901 05/add-to-eax 4/imm32 -17902 # var slice/ecx: slice = {eax, ecx} -17903 51/push-ecx -17904 50/push-eax -17905 89/<- %ecx 4/r32/esp -17906 # -17907 (identifier? %ecx) -17908 (check-ints-equal %eax 1 "F - test-is-identifier-z") -17909 # . epilogue -17910 89/<- %esp 5/r32/ebp -17911 5d/pop-to-ebp -17912 c3/return -17913 -17914 test-is-identifier-A: -17915 # . prologue -17916 55/push-ebp -17917 89/<- %ebp 4/r32/esp -17918 # (eax..ecx) = "A$" -17919 b8/copy-to-eax "A$"/imm32 -17920 8b/-> *eax 1/r32/ecx -17921 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17922 05/add-to-eax 4/imm32 -17923 # var slice/ecx: slice = {eax, ecx} -17924 51/push-ecx -17925 50/push-eax -17926 89/<- %ecx 4/r32/esp -17927 # -17928 (identifier? %ecx) -17929 (check-ints-equal %eax 1 "F - test-is-identifier-A") -17930 # . epilogue -17931 89/<- %esp 5/r32/ebp -17932 5d/pop-to-ebp -17933 c3/return -17934 -17935 test-is-identifier-Z: -17936 # . prologue -17937 55/push-ebp -17938 89/<- %ebp 4/r32/esp -17939 # (eax..ecx) = "Z$" -17940 b8/copy-to-eax "Z$"/imm32 -17941 8b/-> *eax 1/r32/ecx -17942 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17943 05/add-to-eax 4/imm32 -17944 # var slice/ecx: slice = {eax, ecx} -17945 51/push-ecx -17946 50/push-eax -17947 89/<- %ecx 4/r32/esp -17948 # -17949 (identifier? %ecx) -17950 (check-ints-equal %eax 1 "F - test-is-identifier-Z") -17951 # . epilogue -17952 89/<- %esp 5/r32/ebp -17953 5d/pop-to-ebp -17954 c3/return -17955 -17956 test-is-identifier-at: -17957 # character before 'A' is invalid -17958 # . prologue -17959 55/push-ebp -17960 89/<- %ebp 4/r32/esp -17961 # (eax..ecx) = "@a" -17962 b8/copy-to-eax "@a"/imm32 -17963 8b/-> *eax 1/r32/ecx -17964 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17965 05/add-to-eax 4/imm32 -17966 # var slice/ecx: slice = {eax, ecx} -17967 51/push-ecx -17968 50/push-eax -17969 89/<- %ecx 4/r32/esp -17970 # -17971 (identifier? %ecx) -17972 (check-ints-equal %eax 0 "F - test-is-identifier-@") -17973 # . epilogue -17974 89/<- %esp 5/r32/ebp -17975 5d/pop-to-ebp -17976 c3/return -17977 -17978 test-is-identifier-square-bracket: -17979 # character after 'Z' is invalid -17980 # . prologue -17981 55/push-ebp -17982 89/<- %ebp 4/r32/esp -17983 # (eax..ecx) = "[a" -17984 b8/copy-to-eax "[a"/imm32 -17985 8b/-> *eax 1/r32/ecx -17986 8d/copy-address *(eax+ecx+4) 1/r32/ecx -17987 05/add-to-eax 4/imm32 -17988 # var slice/ecx: slice = {eax, ecx} -17989 51/push-ecx -17990 50/push-eax -17991 89/<- %ecx 4/r32/esp -17992 # -17993 (identifier? %ecx) -17994 (check-ints-equal %eax 0 "F - test-is-identifier-@") -17995 # . epilogue -17996 89/<- %esp 5/r32/ebp -17997 5d/pop-to-ebp -17998 c3/return -17999 -18000 test-is-identifier-backtick: -18001 # character before 'a' is invalid -18002 # . prologue -18003 55/push-ebp -18004 89/<- %ebp 4/r32/esp -18005 # (eax..ecx) = "`a" -18006 b8/copy-to-eax "`a"/imm32 -18007 8b/-> *eax 1/r32/ecx -18008 8d/copy-address *(eax+ecx+4) 1/r32/ecx -18009 05/add-to-eax 4/imm32 -18010 # var slice/ecx: slice = {eax, ecx} -18011 51/push-ecx -18012 50/push-eax -18013 89/<- %ecx 4/r32/esp -18014 # -18015 (identifier? %ecx) -18016 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") -18017 # . epilogue -18018 89/<- %esp 5/r32/ebp -18019 5d/pop-to-ebp -18020 c3/return -18021 -18022 test-is-identifier-curly-brace-open: -18023 # character after 'z' is invalid; also used for blocks -18024 # . prologue -18025 55/push-ebp -18026 89/<- %ebp 4/r32/esp -18027 # (eax..ecx) = "{a" -18028 b8/copy-to-eax "{a"/imm32 -18029 8b/-> *eax 1/r32/ecx -18030 8d/copy-address *(eax+ecx+4) 1/r32/ecx -18031 05/add-to-eax 4/imm32 -18032 # var slice/ecx: slice = {eax, ecx} -18033 51/push-ecx -18034 50/push-eax -18035 89/<- %ecx 4/r32/esp -18036 # -18037 (identifier? %ecx) -18038 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") -18039 # . epilogue -18040 89/<- %esp 5/r32/ebp -18041 5d/pop-to-ebp -18042 c3/return -18043 -18044 test-is-identifier-curly-brace-close: -18045 # . prologue -18046 55/push-ebp -18047 89/<- %ebp 4/r32/esp -18048 # (eax..ecx) = "}a" -18049 b8/copy-to-eax "}a"/imm32 -18050 8b/-> *eax 1/r32/ecx -18051 8d/copy-address *(eax+ecx+4) 1/r32/ecx -18052 05/add-to-eax 4/imm32 -18053 # var slice/ecx: slice = {eax, ecx} -18054 51/push-ecx -18055 50/push-eax -18056 89/<- %ecx 4/r32/esp -18057 # -18058 (identifier? %ecx) -18059 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") -18060 # . epilogue -18061 89/<- %esp 5/r32/ebp -18062 5d/pop-to-ebp -18063 c3/return -18064 -18065 test-is-identifier-hyphen: -18066 # disallow leading '-' since '->' has special meaning -18067 # . prologue -18068 55/push-ebp -18069 89/<- %ebp 4/r32/esp -18070 # (eax..ecx) = "-a" -18071 b8/copy-to-eax "-a"/imm32 -18072 8b/-> *eax 1/r32/ecx -18073 8d/copy-address *(eax+ecx+4) 1/r32/ecx -18074 05/add-to-eax 4/imm32 -18075 # var slice/ecx: slice = {eax, ecx} -18076 51/push-ecx -18077 50/push-eax -18078 89/<- %ecx 4/r32/esp -18079 # -18080 (identifier? %ecx) -18081 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") -18082 # . epilogue -18083 89/<- %esp 5/r32/ebp -18084 5d/pop-to-ebp -18085 c3/return -18086 -18087 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) -18088 # . prologue -18089 55/push-ebp -18090 89/<- %ebp 4/r32/esp -18091 # . save registers -18092 50/push-eax -18093 56/push-esi -18094 57/push-edi -18095 # esi = in -18096 8b/-> *(ebp+8) 6/r32/esi -18097 # edi = out -18098 8b/-> *(ebp+0xc) 7/r32/edi -18099 # initialize some global state -18100 c7 0/subop/copy *Curr-block-depth 1/imm32 -18101 # parse-mu-block(in, vars, out, out->body) -18102 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body -18103 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18)) -18104 $populate-mu-function-body:end: -18105 # . restore registers -18106 5f/pop-to-edi -18107 5e/pop-to-esi -18108 58/pop-to-eax -18109 # . epilogue -18110 89/<- %esp 5/r32/ebp -18111 5d/pop-to-ebp -18112 c3/return -18113 -18114 # parses a block, assuming that the leading '{' has already been read by the caller -18115 parse-mu-block: # in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle block), err: (addr buffered-file), ed: (addr exit-descriptor) -18116 # pseudocode: -18117 # var line: (stream byte 512) -18118 # var word-slice: slice -18119 # allocate(Heap, Stmt-size, out) -18120 # var out-addr: (addr block) = lookup(*out) -18121 # out-addr->tag = 0/block -18122 # out-addr->var = some unique name -18123 # push(vars, {out-addr->var, false}) -18124 # while true # line loop -18125 # clear-stream(line) -18126 # read-line-buffered(in, line) -18127 # if (line->write == 0) break # end of file -18128 # word-slice = next-mu-token(line) -18129 # if slice-empty?(word-slice) # end of line -18130 # continue -18131 # else if slice-starts-with?(word-slice, "#") -18132 # continue -18133 # else if slice-equal?(word-slice, "{") -18134 # assert(no-tokens-in(line)) -18135 # block = parse-mu-block(in, vars, fn) -18136 # append-to-block(out-addr, block) -18137 # else if slice-equal?(word-slice, "}") -18138 # break -18139 # else if slice-ends-with?(word-slice, ":") -18140 # # TODO: error-check the rest of 'line' -18141 # --word-slice->end to skip ':' -18142 # named-block = parse-mu-named-block(word-slice, in, vars, fn) -18143 # append-to-block(out-addr, named-block) -18144 # else if slice-equal?(word-slice, "var") -18145 # var-def = parse-mu-var-def(line, vars, fn) -18146 # append-to-block(out-addr, var-def) -18147 # else -18148 # stmt = parse-mu-stmt(line, vars, fn) -18149 # append-to-block(out-addr, stmt) -18150 # pop(vars) -18151 # -18152 # . prologue -18153 55/push-ebp -18154 89/<- %ebp 4/r32/esp -18155 # . save registers -18156 50/push-eax -18157 51/push-ecx -18158 52/push-edx -18159 53/push-ebx -18160 57/push-edi -18161 # var line/ecx: (stream byte 512) -18162 81 5/subop/subtract %esp 0x200/imm32 -18163 68/push 0x200/imm32/size -18164 68/push 0/imm32/read -18165 68/push 0/imm32/write -18166 89/<- %ecx 4/r32/esp -18167 # var word-slice/edx: slice -18168 68/push 0/imm32/end -18169 68/push 0/imm32/start -18170 89/<- %edx 4/r32/esp -18171 # allocate into out -18172 (allocate Heap *Stmt-size *(ebp+0x14)) -18173 # var out-addr/edi: (addr block) = lookup(*out) -18174 8b/-> *(ebp+0x14) 7/r32/edi -18175 (lookup *edi *(edi+4)) # => eax -18176 89/<- %edi 0/r32/eax -18177 # out-addr->tag is 0 (block) by default -18178 # set out-addr->var -18179 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var -18180 (new-block-name *(ebp+0x10) %eax) -18181 # push(vars, out-addr->var) -18182 (push *(ebp+0xc) *(edi+0xc)) # Block-var -18183 (push *(ebp+0xc) *(edi+0x10)) # Block-var -18184 (push *(ebp+0xc) 0) # false -18185 # increment *Curr-block-depth -18186 ff 0/subop/increment *Curr-block-depth -18187 { -18188 $parse-mu-block:line-loop: -18189 # line = read-line-buffered(in) -18190 (clear-stream %ecx) -18191 (read-line-buffered *(ebp+8) %ecx) -18192 #? (write-buffered Stderr "line: ") -18193 #? (write-stream-data Stderr %ecx) -18194 #? #? (write-buffered Stderr Newline) # line has its own newline -18195 #? (flush Stderr) -18196 #? (rewind-stream %ecx) -18197 # if (line->write == 0) break -18198 81 7/subop/compare *ecx 0/imm32 -18199 0f 84/jump-if-= break/disp32 -18200 #? (write-buffered Stderr "vars:\n") -18201 #? (dump-vars *(ebp+0xc)) -18202 # word-slice = next-mu-token(line) -18203 (next-mu-token %ecx %edx) -18204 #? (write-buffered Stderr "word: ") -18205 #? (write-slice-buffered Stderr %edx) -18206 #? (write-buffered Stderr Newline) -18207 #? (flush Stderr) -18208 # if slice-empty?(word-slice) continue -18209 (slice-empty? %edx) -18210 3d/compare-eax-and 0/imm32/false -18211 0f 85/jump-if-!= loop/disp32 -18212 # if (slice-starts-with?(word-slice, '#') continue -18213 # . eax = *word-slice->start -18214 8b/-> *edx 0/r32/eax -18215 8a/copy-byte *eax 0/r32/AL -18216 25/and-eax-with 0xff/imm32 -18217 # . if (eax == '#') continue -18218 3d/compare-eax-and 0x23/imm32/hash -18219 0f 84/jump-if-= loop/disp32 -18220 # if slice-equal?(word-slice, "{") -18221 { -18222 $parse-mu-block:check-for-block: -18223 (slice-equal? %edx "{") -18224 3d/compare-eax-and 0/imm32/false -18225 74/jump-if-= break/disp8 -18226 (check-no-tokens-left %ecx) -18227 # parse new block and append -18228 # . var tmp/eax: (handle block) -18229 68/push 0/imm32 -18230 68/push 0/imm32 -18231 89/<- %eax 4/r32/esp -18232 # . -18233 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) -18234 (append-to-block Heap %edi *eax *(eax+4)) -18235 # . reclaim tmp -18236 81 0/subop/add %esp 8/imm32 -18237 # . -18238 e9/jump $parse-mu-block:line-loop/disp32 -18239 } -18240 # if slice-equal?(word-slice, "}") break -18241 $parse-mu-block:check-for-end: -18242 (slice-equal? %edx "}") -18243 3d/compare-eax-and 0/imm32/false -18244 0f 85/jump-if-!= break/disp32 -18245 # if slice-ends-with?(word-slice, ":") parse named block and append -18246 { -18247 $parse-mu-block:check-for-named-block: -18248 # . eax = *(word-slice->end-1) -18249 8b/-> *(edx+4) 0/r32/eax -18250 48/decrement-eax -18251 8a/copy-byte *eax 0/r32/AL -18252 25/and-eax-with 0xff/imm32 -18253 # . if (eax != ':') break -18254 3d/compare-eax-and 0x3a/imm32/colon -18255 0f 85/jump-if-!= break/disp32 -18256 # TODO: error-check the rest of 'line' -18257 # -18258 # skip ':' -18259 ff 1/subop/decrement *(edx+4) # Slice-end -18260 # var tmp/eax: (handle block) -18261 68/push 0/imm32 -18262 68/push 0/imm32 -18263 89/<- %eax 4/r32/esp -18264 # -18265 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) -18266 (append-to-block Heap %edi *eax *(eax+4)) -18267 # reclaim tmp -18268 81 0/subop/add %esp 8/imm32 -18269 # -18270 e9/jump $parse-mu-block:line-loop/disp32 -18271 } -18272 # if slice-equal?(word-slice, "var") -18273 { -18274 $parse-mu-block:check-for-var: -18275 (slice-equal? %edx "var") -18276 3d/compare-eax-and 0/imm32/false -18277 74/jump-if-= break/disp8 -18278 # var tmp/eax: (handle block) -18279 68/push 0/imm32 -18280 68/push 0/imm32 -18281 89/<- %eax 4/r32/esp -18282 # -18283 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) -18284 (append-to-block Heap %edi *eax *(eax+4)) -18285 # reclaim tmp -18286 81 0/subop/add %esp 8/imm32 +17206 # TODO: raise an error on `var x: (array int a)` +17207 (decimal-digit? %eax) # => eax +17208 3d/compare-eax-and 0/imm32/false +17209 74/jump-if-= break/disp8 +17210 $parse-type:int: +17211 # strip out metadata +17212 (next-token-from-slice *ecx *(ecx+4) 0x2f %ecx) +17213 # +17214 (check-mu-hex-int %ecx *(ebp+0x14) *(ebp+0x18)) +17215 (parse-hex-int-from-slice %ecx) # => eax +17216 c7 0/subop/copy *(edx+4) 9/imm32/type-id-array-capacity # Type-tree-value +17217 89/<- *(edx+8) 0/r32/eax # Type-tree-value-size +17218 e9/jump $parse-type:end/disp32 +17219 } +17220 $parse-type:atom: +17221 # out->is-atom? = true +17222 c7 0/subop/copy *edx 1/imm32/true # Type-tree-is-atom +17223 { +17224 $parse-type:check-for-type-parameter: +17225 # var tmp/eax: byte = *s->slice +17226 8b/-> *ecx 0/r32/eax +17227 8a/copy-byte *eax 0/r32/AL +17228 25/and-eax-with 0xff/imm32 +17229 # if (tmp != '_') break +17230 3d/compare-eax-and 0x5f/imm32/_ +17231 75/jump-if-!= break/disp8 +17232 $parse-type:type-parameter: +17233 # out->value = type-parameter +17234 c7 0/subop/copy *(edx+4) 0xa/imm32/type-parameter # Type-tree-value +17235 # out->parameter-name = slice-to-string(ad, s) +17236 8d/copy-address *(edx+8) 0/r32/eax # Type-tree-parameter-name +17237 (slice-to-string *(ebp+8) %ecx %eax) +17238 e9/jump $parse-type:end/disp32 +17239 } +17240 $parse-type:non-type-parameter: +17241 # out->value = pos-or-insert-slice(Type-id, s) +17242 (pos-or-insert-slice Type-id %ecx) # => eax +17243 89/<- *(edx+4) 0/r32/eax # Type-tree-value +17244 e9/jump $parse-type:end/disp32 +17245 } +17246 $parse-type:non-atom: +17247 # otherwise s == "(" +17248 # out->left = parse-type(ad, in) +17249 8d/copy-address *(edx+4) 0/r32/eax # Type-tree-left +17250 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) +17251 # out->right = parse-type-tree(ad, in) +17252 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right +17253 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) +17254 $parse-type:end: +17255 # . reclaim locals +17256 81 0/subop/add %esp 8/imm32 +17257 # . restore registers +17258 5a/pop-to-edx +17259 59/pop-to-ecx +17260 58/pop-to-eax +17261 # . epilogue +17262 89/<- %esp 5/r32/ebp +17263 5d/pop-to-ebp +17264 c3/return +17265 +17266 $parse-type:abort: +17267 # error("unexpected token when parsing type: '" s "'\n") +17268 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '") +17269 (write-slice-buffered *(ebp+0x14) %ecx) +17270 (write-buffered *(ebp+0x14) "'\n") +17271 (flush *(ebp+0x14)) +17272 (stop *(ebp+0x18) 1) +17273 # never gets here +17274 +17275 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) +17276 # pseudocode: +17277 # var tmp: (handle type-tree) = parse-type(ad, in) +17278 # if tmp == 0 +17279 # return 0 +17280 # out = allocate(Type-tree) +17281 # out->left = tmp +17282 # out->right = parse-type-tree(ad, in) +17283 # +17284 # . prologue +17285 55/push-ebp +17286 89/<- %ebp 4/r32/esp +17287 # . save registers +17288 50/push-eax +17289 51/push-ecx +17290 52/push-edx +17291 # +17292 (zero-out *(ebp+0x10) *Handle-size) +17293 # var tmp/ecx: (handle type-tree) +17294 68/push 0/imm32 +17295 68/push 0/imm32 +17296 89/<- %ecx 4/r32/esp +17297 # tmp = parse-type(ad, in) +17298 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18)) +17299 # if (tmp == 0) return +17300 81 7/subop/compare *ecx 0/imm32 +17301 74/jump-if-= $parse-type-tree:end/disp8 +17302 # out = new tree +17303 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) +17304 # var out-addr/edx: (addr tree) = lookup(*out) +17305 8b/-> *(ebp+0x10) 2/r32/edx +17306 (lookup *edx *(edx+4)) # => eax +17307 89/<- %edx 0/r32/eax +17308 # out->left = tmp +17309 8b/-> *ecx 0/r32/eax +17310 89/<- *(edx+4) 0/r32/eax # Type-tree-left +17311 8b/-> *(ecx+4) 0/r32/eax +17312 89/<- *(edx+8) 0/r32/eax # Type-tree-left +17313 # out->right = parse-type-tree(ad, in) +17314 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right +17315 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) +17316 $parse-type-tree:end: +17317 # . reclaim locals +17318 81 0/subop/add %esp 8/imm32 +17319 # . restore registers +17320 5a/pop-to-edx +17321 59/pop-to-ecx +17322 58/pop-to-eax +17323 # . epilogue +17324 89/<- %esp 5/r32/ebp +17325 5d/pop-to-ebp +17326 c3/return +17327 +17328 next-mu-token: # in: (addr stream byte), out: (addr slice) +17329 # pseudocode: +17330 # start: +17331 # skip-chars-matching-whitespace(in) +17332 # if in->read >= in->write # end of in +17333 # out = {0, 0} +17334 # return +17335 # out->start = &in->data[in->read] +17336 # var curr-byte/eax: byte = in->data[in->read] +17337 # if curr->byte == ',' # comment token +17338 # ++in->read +17339 # goto start +17340 # if curr-byte == '#' # comment +17341 # goto done # treat as eof +17342 # if curr-byte == '"' # string literal +17343 # skip-string(in) +17344 # goto done # no metadata +17345 # if curr-byte == '(' +17346 # ++in->read +17347 # goto done +17348 # if curr-byte == ')' +17349 # ++in->read +17350 # goto done +17351 # # read a word +17352 # while true +17353 # if in->read >= in->write +17354 # break +17355 # curr-byte = in->data[in->read] +17356 # if curr-byte == ' ' +17357 # break +17358 # if curr-byte == '\r' +17359 # break +17360 # if curr-byte == '\n' +17361 # break +17362 # if curr-byte == '(' +17363 # break +17364 # if curr-byte == ')' +17365 # break +17366 # if curr-byte == ',' +17367 # break +17368 # ++in->read +17369 # done: +17370 # out->end = &in->data[in->read] +17371 # +17372 # . prologue +17373 55/push-ebp +17374 89/<- %ebp 4/r32/esp +17375 # . save registers +17376 50/push-eax +17377 51/push-ecx +17378 56/push-esi +17379 57/push-edi +17380 # esi = in +17381 8b/-> *(ebp+8) 6/r32/esi +17382 # edi = out +17383 8b/-> *(ebp+0xc) 7/r32/edi +17384 $next-mu-token:start: +17385 (skip-chars-matching-whitespace %esi) +17386 $next-mu-token:check0: +17387 # if (in->read >= in->write) return out = {0, 0} +17388 # . ecx = in->read +17389 8b/-> *(esi+4) 1/r32/ecx +17390 # . if (ecx >= in->write) return out = {0, 0} +17391 3b/compare<- *esi 1/r32/ecx +17392 c7 0/subop/copy *edi 0/imm32 +17393 c7 0/subop/copy *(edi+4) 0/imm32 +17394 0f 8d/jump-if->= $next-mu-token:end/disp32 +17395 # out->start = &in->data[in->read] +17396 8d/copy-address *(esi+ecx+0xc) 0/r32/eax +17397 89/<- *edi 0/r32/eax +17398 # var curr-byte/eax: byte = in->data[in->read] +17399 31/xor-with %eax 0/r32/eax +17400 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL +17401 { +17402 $next-mu-token:check-for-comma: +17403 # if (curr-byte != ',') break +17404 3d/compare-eax-and 0x2c/imm32/comma +17405 75/jump-if-!= break/disp8 +17406 # ++in->read +17407 ff 0/subop/increment *(esi+4) +17408 # restart +17409 e9/jump $next-mu-token:start/disp32 +17410 } +17411 { +17412 $next-mu-token:check-for-comment: +17413 # if (curr-byte != '#') break +17414 3d/compare-eax-and 0x23/imm32/pound +17415 75/jump-if-!= break/disp8 +17416 # return eof +17417 e9/jump $next-mu-token:done/disp32 +17418 } +17419 { +17420 $next-mu-token:check-for-string-literal: +17421 # if (curr-byte != '"') break +17422 3d/compare-eax-and 0x22/imm32/dquote +17423 75/jump-if-!= break/disp8 +17424 (skip-string %esi) +17425 # return +17426 e9/jump $next-mu-token:done/disp32 +17427 } +17428 { +17429 $next-mu-token:check-for-open-paren: +17430 # if (curr-byte != '(') break +17431 3d/compare-eax-and 0x28/imm32/open-paren +17432 75/jump-if-!= break/disp8 +17433 # ++in->read +17434 ff 0/subop/increment *(esi+4) +17435 # return +17436 e9/jump $next-mu-token:done/disp32 +17437 } +17438 { +17439 $next-mu-token:check-for-close-paren: +17440 # if (curr-byte != ')') break +17441 3d/compare-eax-and 0x29/imm32/close-paren +17442 75/jump-if-!= break/disp8 +17443 # ++in->read +17444 ff 0/subop/increment *(esi+4) +17445 # return +17446 e9/jump $next-mu-token:done/disp32 +17447 } +17448 { +17449 $next-mu-token:regular-word-without-metadata: +17450 # if (in->read >= in->write) break +17451 # . ecx = in->read +17452 8b/-> *(esi+4) 1/r32/ecx +17453 # . if (ecx >= in->write) break +17454 3b/compare<- *esi 1/r32/ecx +17455 7d/jump-if->= break/disp8 +17456 # var c/eax: byte = in->data[in->read] +17457 31/xor-with %eax 0/r32/eax +17458 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL +17459 # if (c == ' ') break +17460 3d/compare-eax-and 0x20/imm32/space +17461 74/jump-if-= break/disp8 +17462 # if (c == '\r') break +17463 3d/compare-eax-and 0xd/imm32/carriage-return +17464 74/jump-if-= break/disp8 +17465 # if (c == '\n') break +17466 3d/compare-eax-and 0xa/imm32/newline +17467 74/jump-if-= break/disp8 +17468 # if (c == '(') break +17469 3d/compare-eax-and 0x28/imm32/open-paren +17470 0f 84/jump-if-= break/disp32 +17471 # if (c == ')') break +17472 3d/compare-eax-and 0x29/imm32/close-paren +17473 0f 84/jump-if-= break/disp32 +17474 # if (c == ',') break +17475 3d/compare-eax-and 0x2c/imm32/comma +17476 0f 84/jump-if-= break/disp32 +17477 # ++in->read +17478 ff 0/subop/increment *(esi+4) +17479 # +17480 e9/jump loop/disp32 +17481 } +17482 $next-mu-token:done: +17483 # out->end = &in->data[in->read] +17484 8b/-> *(esi+4) 1/r32/ecx +17485 8d/copy-address *(esi+ecx+0xc) 0/r32/eax +17486 89/<- *(edi+4) 0/r32/eax +17487 $next-mu-token:end: +17488 # . restore registers +17489 5f/pop-to-edi +17490 5e/pop-to-esi +17491 59/pop-to-ecx +17492 58/pop-to-eax +17493 # . epilogue +17494 89/<- %esp 5/r32/ebp +17495 5d/pop-to-ebp +17496 c3/return +17497 +17498 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int +17499 # . prologue +17500 55/push-ebp +17501 89/<- %ebp 4/r32/esp +17502 # if (pos-slice(arr, s) != -1) return it +17503 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax +17504 3d/compare-eax-and -1/imm32 +17505 75/jump-if-!= $pos-or-insert-slice:end/disp8 +17506 $pos-or-insert-slice:insert: +17507 # var s2/eax: (handle array byte) +17508 68/push 0/imm32 +17509 68/push 0/imm32 +17510 89/<- %eax 4/r32/esp +17511 (slice-to-string Heap *(ebp+0xc) %eax) +17512 # throw away alloc-id +17513 (lookup *eax *(eax+4)) # => eax +17514 (write-int *(ebp+8) %eax) +17515 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax +17516 $pos-or-insert-slice:end: +17517 # . reclaim locals +17518 81 0/subop/add %esp 8/imm32 +17519 # . epilogue +17520 89/<- %esp 5/r32/ebp +17521 5d/pop-to-ebp +17522 c3/return +17523 +17524 # return the index in an array of strings matching 's', -1 if not found +17525 # index is denominated in elements, not bytes +17526 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int +17527 # . prologue +17528 55/push-ebp +17529 89/<- %ebp 4/r32/esp +17530 # . save registers +17531 51/push-ecx +17532 52/push-edx +17533 53/push-ebx +17534 56/push-esi +17535 #? (write-buffered Stderr "pos-slice: ") +17536 #? (write-slice-buffered Stderr *(ebp+0xc)) +17537 #? (write-buffered Stderr "\n") +17538 #? (flush Stderr) +17539 # esi = arr +17540 8b/-> *(ebp+8) 6/r32/esi +17541 # var index/ecx: int = 0 +17542 b9/copy-to-ecx 0/imm32 +17543 # var curr/edx: (addr (addr array byte)) = arr->data +17544 8d/copy-address *(esi+0xc) 2/r32/edx +17545 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] +17546 8b/-> *esi 3/r32/ebx +17547 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx +17548 { +17549 #? (write-buffered Stderr " ") +17550 #? (write-int32-hex-buffered Stderr %ecx) +17551 #? (write-buffered Stderr "\n") +17552 #? (flush Stderr) +17553 # if (curr >= max) return -1 +17554 39/compare %edx 3/r32/ebx +17555 b8/copy-to-eax -1/imm32 +17556 73/jump-if-addr>= $pos-slice:end/disp8 +17557 # if (slice-equal?(s, *curr)) break +17558 (slice-equal? *(ebp+0xc) *edx) # => eax +17559 3d/compare-eax-and 0/imm32/false +17560 75/jump-if-!= break/disp8 +17561 # ++index +17562 41/increment-ecx +17563 # curr += 4 +17564 81 0/subop/add %edx 4/imm32 +17565 # +17566 eb/jump loop/disp8 +17567 } +17568 # return index +17569 89/<- %eax 1/r32/ecx +17570 $pos-slice:end: +17571 #? (write-buffered Stderr "=> ") +17572 #? (write-int32-hex-buffered Stderr %eax) +17573 #? (write-buffered Stderr "\n") +17574 # . restore registers +17575 5e/pop-to-esi +17576 5b/pop-to-ebx +17577 5a/pop-to-edx +17578 59/pop-to-ecx +17579 # . epilogue +17580 89/<- %esp 5/r32/ebp +17581 5d/pop-to-ebp +17582 c3/return +17583 +17584 test-parse-var-with-type: +17585 # . prologue +17586 55/push-ebp +17587 89/<- %ebp 4/r32/esp +17588 # setup +17589 8b/-> *Primitive-type-ids 0/r32/eax +17590 89/<- *Type-id 0/r32/eax # stream-write +17591 # (eax..ecx) = "x:" +17592 b8/copy-to-eax "x:"/imm32 +17593 8b/-> *eax 1/r32/ecx +17594 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17595 05/add-to-eax 4/imm32 +17596 # var slice/ecx: slice = {eax, ecx} +17597 51/push-ecx +17598 50/push-eax +17599 89/<- %ecx 4/r32/esp +17600 # _test-input-stream contains "int" +17601 (clear-stream _test-input-stream) +17602 (write _test-input-stream "int") +17603 # var v/edx: (handle var) +17604 68/push 0/imm32 +17605 68/push 0/imm32 +17606 89/<- %edx 4/r32/esp +17607 # +17608 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) +17609 # var v-addr/edx: (addr var) = lookup(v) +17610 (lookup *edx *(edx+4)) # => eax +17611 89/<- %edx 0/r32/eax +17612 # check v-addr->name +17613 (lookup *edx *(edx+4)) # Var-name Var-name => eax +17614 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") +17615 # check v-addr->type +17616 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +17617 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Type-tree-is-atom +17618 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Type-tree-value +17619 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Type-tree-right +17620 # . epilogue +17621 89/<- %esp 5/r32/ebp +17622 5d/pop-to-ebp +17623 c3/return +17624 +17625 test-parse-var-with-type-and-register: +17626 # . prologue +17627 55/push-ebp +17628 89/<- %ebp 4/r32/esp +17629 # setup +17630 8b/-> *Primitive-type-ids 0/r32/eax +17631 89/<- *Type-id 0/r32/eax # stream-write +17632 # (eax..ecx) = "x/eax:" +17633 b8/copy-to-eax "x/eax:"/imm32 +17634 8b/-> *eax 1/r32/ecx +17635 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17636 05/add-to-eax 4/imm32 +17637 # var slice/ecx: slice = {eax, ecx} +17638 51/push-ecx +17639 50/push-eax +17640 89/<- %ecx 4/r32/esp +17641 # _test-input-stream contains "int" +17642 (clear-stream _test-input-stream) +17643 (write _test-input-stream "int") +17644 # var v/edx: (handle var) +17645 68/push 0/imm32 +17646 68/push 0/imm32 +17647 89/<- %edx 4/r32/esp +17648 # +17649 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) +17650 # var v-addr/edx: (addr var) = lookup(v) +17651 (lookup *edx *(edx+4)) # => eax +17652 89/<- %edx 0/r32/eax +17653 # check v-addr->name +17654 (lookup *edx *(edx+4)) # Var-name Var-name => eax +17655 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") +17656 # check v-addr->register +17657 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +17658 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") +17659 # check v-addr->type +17660 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +17661 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Type-tree-is-atom +17662 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Type-tree-left +17663 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Type-tree-right +17664 # . epilogue +17665 89/<- %esp 5/r32/ebp +17666 5d/pop-to-ebp +17667 c3/return +17668 +17669 test-parse-var-with-trailing-characters: +17670 # . prologue +17671 55/push-ebp +17672 89/<- %ebp 4/r32/esp +17673 # setup +17674 8b/-> *Primitive-type-ids 0/r32/eax +17675 89/<- *Type-id 0/r32/eax # stream-write +17676 # (eax..ecx) = "x:" +17677 b8/copy-to-eax "x:"/imm32 +17678 8b/-> *eax 1/r32/ecx +17679 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17680 05/add-to-eax 4/imm32 +17681 # var slice/ecx: slice = {eax, ecx} +17682 51/push-ecx +17683 50/push-eax +17684 89/<- %ecx 4/r32/esp +17685 # _test-input-stream contains "int," +17686 (clear-stream _test-input-stream) +17687 (write _test-input-stream "int,") +17688 # var v/edx: (handle var) +17689 68/push 0/imm32 +17690 68/push 0/imm32 +17691 89/<- %edx 4/r32/esp +17692 # +17693 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) +17694 # var v-addr/edx: (addr var) = lookup(v) +17695 (lookup *edx *(edx+4)) # => eax +17696 89/<- %edx 0/r32/eax +17697 # check v-addr->name +17698 (lookup *edx *(edx+4)) # Var-name Var-name => eax +17699 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") +17700 # check v-addr->register +17701 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register +17702 # check v-addr->type +17703 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +17704 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Type-tree-is-atom +17705 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-left +17706 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-right +17707 # . epilogue +17708 89/<- %esp 5/r32/ebp +17709 5d/pop-to-ebp +17710 c3/return +17711 +17712 test-parse-var-with-register-and-trailing-characters: +17713 # . prologue +17714 55/push-ebp +17715 89/<- %ebp 4/r32/esp +17716 # setup +17717 8b/-> *Primitive-type-ids 0/r32/eax +17718 89/<- *Type-id 0/r32/eax # stream-write +17719 # (eax..ecx) = "x/eax:" +17720 b8/copy-to-eax "x/eax:"/imm32 +17721 8b/-> *eax 1/r32/ecx +17722 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17723 05/add-to-eax 4/imm32 +17724 # var slice/ecx: slice = {eax, ecx} +17725 51/push-ecx +17726 50/push-eax +17727 89/<- %ecx 4/r32/esp +17728 # _test-input-stream contains "int," +17729 (clear-stream _test-input-stream) +17730 (write _test-input-stream "int,") +17731 # var v/edx: (handle var) +17732 68/push 0/imm32 +17733 68/push 0/imm32 +17734 89/<- %edx 4/r32/esp +17735 # +17736 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) +17737 # var v-addr/edx: (addr var) = lookup(v) +17738 (lookup *edx *(edx+4)) # => eax +17739 89/<- %edx 0/r32/eax +17740 # check v-addr->name +17741 (lookup *edx *(edx+4)) # Var-name Var-name => eax +17742 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") +17743 # check v-addr->register +17744 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +17745 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") +17746 # check v-addr->type +17747 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +17748 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Type-tree-is-atom +17749 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Type-tree-left +17750 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Type-tree-right +17751 # . epilogue +17752 89/<- %esp 5/r32/ebp +17753 5d/pop-to-ebp +17754 c3/return +17755 +17756 test-parse-var-with-compound-type: +17757 # . prologue +17758 55/push-ebp +17759 89/<- %ebp 4/r32/esp +17760 # setup +17761 8b/-> *Primitive-type-ids 0/r32/eax +17762 89/<- *Type-id 0/r32/eax # stream-write +17763 # (eax..ecx) = "x:" +17764 b8/copy-to-eax "x:"/imm32 +17765 8b/-> *eax 1/r32/ecx +17766 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17767 05/add-to-eax 4/imm32 +17768 # var slice/ecx: slice = {eax, ecx} +17769 51/push-ecx +17770 50/push-eax +17771 89/<- %ecx 4/r32/esp +17772 # _test-input-stream contains "(addr int)" +17773 (clear-stream _test-input-stream) +17774 (write _test-input-stream "(addr int)") +17775 # var v/edx: (handle var) +17776 68/push 0/imm32 +17777 68/push 0/imm32 +17778 89/<- %edx 4/r32/esp +17779 # +17780 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0) +17781 # var v-addr/edx: (addr var) = lookup(v) +17782 (lookup *edx *(edx+4)) # => eax +17783 89/<- %edx 0/r32/eax +17784 # check v-addr->name +17785 (lookup *edx *(edx+4)) # Var-name Var-name => eax +17786 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") +17787 # check v-addr->register +17788 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register +17789 # - check v-addr->type +17790 # var type/edx: (addr type-tree) = var->type +17791 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +17792 89/<- %edx 0/r32/eax +17793 # type is a non-atom +17794 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Type-tree-is-atom +17795 # type->left == atom(addr) +17796 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +17797 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Type-tree-is-atom +17798 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Type-tree-value +17799 # type->right->left == atom(int) +17800 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax +17801 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +17802 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Type-tree-is-atom +17803 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Type-tree-value +17804 # type->right->right == null +17805 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Type-tree-right +17806 # . epilogue +17807 89/<- %esp 5/r32/ebp +17808 5d/pop-to-ebp +17809 c3/return +17810 +17811 # identifier starts with a letter or '$' or '_' +17812 # no constraints at the moment on later letters +17813 # all we really want to do so far is exclude '{', '}' and '->' +17814 identifier?: # in: (addr slice) -> result/eax: boolean +17815 # . prologue +17816 55/push-ebp +17817 89/<- %ebp 4/r32/esp +17818 # if (slice-empty?(in)) return false +17819 (slice-empty? *(ebp+8)) # => eax +17820 3d/compare-eax-and 0/imm32/false +17821 75/jump-if-!= $identifier?:false/disp8 +17822 # var c/eax: byte = *in->start +17823 8b/-> *(ebp+8) 0/r32/eax +17824 8b/-> *eax 0/r32/eax +17825 8a/copy-byte *eax 0/r32/AL +17826 25/and-eax-with 0xff/imm32 +17827 # if (c == '$') return true +17828 3d/compare-eax-and 0x24/imm32/$ +17829 74/jump-if-= $identifier?:true/disp8 +17830 # if (c == '_') return true +17831 3d/compare-eax-and 0x5f/imm32/_ +17832 74/jump-if-= $identifier?:true/disp8 +17833 # drop case +17834 25/and-eax-with 0x5f/imm32 +17835 # if (c < 'A') return false +17836 3d/compare-eax-and 0x41/imm32/A +17837 7c/jump-if-< $identifier?:false/disp8 +17838 # if (c > 'Z') return false +17839 3d/compare-eax-and 0x5a/imm32/Z +17840 7f/jump-if-> $identifier?:false/disp8 +17841 # otherwise return true +17842 $identifier?:true: +17843 b8/copy-to-eax 1/imm32/true +17844 eb/jump $identifier?:end/disp8 +17845 $identifier?:false: +17846 b8/copy-to-eax 0/imm32/false +17847 $identifier?:end: +17848 # . epilogue +17849 89/<- %esp 5/r32/ebp +17850 5d/pop-to-ebp +17851 c3/return +17852 +17853 test-is-identifier-dollar: +17854 # . prologue +17855 55/push-ebp +17856 89/<- %ebp 4/r32/esp +17857 # (eax..ecx) = "$a" +17858 b8/copy-to-eax "$a"/imm32 +17859 8b/-> *eax 1/r32/ecx +17860 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17861 05/add-to-eax 4/imm32 +17862 # var slice/ecx: slice = {eax, ecx} +17863 51/push-ecx +17864 50/push-eax +17865 89/<- %ecx 4/r32/esp +17866 # +17867 (identifier? %ecx) +17868 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") +17869 # . epilogue +17870 89/<- %esp 5/r32/ebp +17871 5d/pop-to-ebp +17872 c3/return +17873 +17874 test-is-identifier-underscore: +17875 # . prologue +17876 55/push-ebp +17877 89/<- %ebp 4/r32/esp +17878 # (eax..ecx) = "_a" +17879 b8/copy-to-eax "_a"/imm32 +17880 8b/-> *eax 1/r32/ecx +17881 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17882 05/add-to-eax 4/imm32 +17883 # var slice/ecx: slice = {eax, ecx} +17884 51/push-ecx +17885 50/push-eax +17886 89/<- %ecx 4/r32/esp +17887 # +17888 (identifier? %ecx) +17889 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") +17890 # . epilogue +17891 89/<- %esp 5/r32/ebp +17892 5d/pop-to-ebp +17893 c3/return +17894 +17895 test-is-identifier-a: +17896 # . prologue +17897 55/push-ebp +17898 89/<- %ebp 4/r32/esp +17899 # (eax..ecx) = "a$" +17900 b8/copy-to-eax "a$"/imm32 +17901 8b/-> *eax 1/r32/ecx +17902 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17903 05/add-to-eax 4/imm32 +17904 # var slice/ecx: slice = {eax, ecx} +17905 51/push-ecx +17906 50/push-eax +17907 89/<- %ecx 4/r32/esp +17908 # +17909 (identifier? %ecx) +17910 (check-ints-equal %eax 1 "F - test-is-identifier-a") +17911 # . epilogue +17912 89/<- %esp 5/r32/ebp +17913 5d/pop-to-ebp +17914 c3/return +17915 +17916 test-is-identifier-z: +17917 # . prologue +17918 55/push-ebp +17919 89/<- %ebp 4/r32/esp +17920 # (eax..ecx) = "z$" +17921 b8/copy-to-eax "z$"/imm32 +17922 8b/-> *eax 1/r32/ecx +17923 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17924 05/add-to-eax 4/imm32 +17925 # var slice/ecx: slice = {eax, ecx} +17926 51/push-ecx +17927 50/push-eax +17928 89/<- %ecx 4/r32/esp +17929 # +17930 (identifier? %ecx) +17931 (check-ints-equal %eax 1 "F - test-is-identifier-z") +17932 # . epilogue +17933 89/<- %esp 5/r32/ebp +17934 5d/pop-to-ebp +17935 c3/return +17936 +17937 test-is-identifier-A: +17938 # . prologue +17939 55/push-ebp +17940 89/<- %ebp 4/r32/esp +17941 # (eax..ecx) = "A$" +17942 b8/copy-to-eax "A$"/imm32 +17943 8b/-> *eax 1/r32/ecx +17944 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17945 05/add-to-eax 4/imm32 +17946 # var slice/ecx: slice = {eax, ecx} +17947 51/push-ecx +17948 50/push-eax +17949 89/<- %ecx 4/r32/esp +17950 # +17951 (identifier? %ecx) +17952 (check-ints-equal %eax 1 "F - test-is-identifier-A") +17953 # . epilogue +17954 89/<- %esp 5/r32/ebp +17955 5d/pop-to-ebp +17956 c3/return +17957 +17958 test-is-identifier-Z: +17959 # . prologue +17960 55/push-ebp +17961 89/<- %ebp 4/r32/esp +17962 # (eax..ecx) = "Z$" +17963 b8/copy-to-eax "Z$"/imm32 +17964 8b/-> *eax 1/r32/ecx +17965 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17966 05/add-to-eax 4/imm32 +17967 # var slice/ecx: slice = {eax, ecx} +17968 51/push-ecx +17969 50/push-eax +17970 89/<- %ecx 4/r32/esp +17971 # +17972 (identifier? %ecx) +17973 (check-ints-equal %eax 1 "F - test-is-identifier-Z") +17974 # . epilogue +17975 89/<- %esp 5/r32/ebp +17976 5d/pop-to-ebp +17977 c3/return +17978 +17979 test-is-identifier-at: +17980 # character before 'A' is invalid +17981 # . prologue +17982 55/push-ebp +17983 89/<- %ebp 4/r32/esp +17984 # (eax..ecx) = "@a" +17985 b8/copy-to-eax "@a"/imm32 +17986 8b/-> *eax 1/r32/ecx +17987 8d/copy-address *(eax+ecx+4) 1/r32/ecx +17988 05/add-to-eax 4/imm32 +17989 # var slice/ecx: slice = {eax, ecx} +17990 51/push-ecx +17991 50/push-eax +17992 89/<- %ecx 4/r32/esp +17993 # +17994 (identifier? %ecx) +17995 (check-ints-equal %eax 0 "F - test-is-identifier-@") +17996 # . epilogue +17997 89/<- %esp 5/r32/ebp +17998 5d/pop-to-ebp +17999 c3/return +18000 +18001 test-is-identifier-square-bracket: +18002 # character after 'Z' is invalid +18003 # . prologue +18004 55/push-ebp +18005 89/<- %ebp 4/r32/esp +18006 # (eax..ecx) = "[a" +18007 b8/copy-to-eax "[a"/imm32 +18008 8b/-> *eax 1/r32/ecx +18009 8d/copy-address *(eax+ecx+4) 1/r32/ecx +18010 05/add-to-eax 4/imm32 +18011 # var slice/ecx: slice = {eax, ecx} +18012 51/push-ecx +18013 50/push-eax +18014 89/<- %ecx 4/r32/esp +18015 # +18016 (identifier? %ecx) +18017 (check-ints-equal %eax 0 "F - test-is-identifier-@") +18018 # . epilogue +18019 89/<- %esp 5/r32/ebp +18020 5d/pop-to-ebp +18021 c3/return +18022 +18023 test-is-identifier-backtick: +18024 # character before 'a' is invalid +18025 # . prologue +18026 55/push-ebp +18027 89/<- %ebp 4/r32/esp +18028 # (eax..ecx) = "`a" +18029 b8/copy-to-eax "`a"/imm32 +18030 8b/-> *eax 1/r32/ecx +18031 8d/copy-address *(eax+ecx+4) 1/r32/ecx +18032 05/add-to-eax 4/imm32 +18033 # var slice/ecx: slice = {eax, ecx} +18034 51/push-ecx +18035 50/push-eax +18036 89/<- %ecx 4/r32/esp +18037 # +18038 (identifier? %ecx) +18039 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") +18040 # . epilogue +18041 89/<- %esp 5/r32/ebp +18042 5d/pop-to-ebp +18043 c3/return +18044 +18045 test-is-identifier-curly-brace-open: +18046 # character after 'z' is invalid; also used for blocks +18047 # . prologue +18048 55/push-ebp +18049 89/<- %ebp 4/r32/esp +18050 # (eax..ecx) = "{a" +18051 b8/copy-to-eax "{a"/imm32 +18052 8b/-> *eax 1/r32/ecx +18053 8d/copy-address *(eax+ecx+4) 1/r32/ecx +18054 05/add-to-eax 4/imm32 +18055 # var slice/ecx: slice = {eax, ecx} +18056 51/push-ecx +18057 50/push-eax +18058 89/<- %ecx 4/r32/esp +18059 # +18060 (identifier? %ecx) +18061 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") +18062 # . epilogue +18063 89/<- %esp 5/r32/ebp +18064 5d/pop-to-ebp +18065 c3/return +18066 +18067 test-is-identifier-curly-brace-close: +18068 # . prologue +18069 55/push-ebp +18070 89/<- %ebp 4/r32/esp +18071 # (eax..ecx) = "}a" +18072 b8/copy-to-eax "}a"/imm32 +18073 8b/-> *eax 1/r32/ecx +18074 8d/copy-address *(eax+ecx+4) 1/r32/ecx +18075 05/add-to-eax 4/imm32 +18076 # var slice/ecx: slice = {eax, ecx} +18077 51/push-ecx +18078 50/push-eax +18079 89/<- %ecx 4/r32/esp +18080 # +18081 (identifier? %ecx) +18082 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") +18083 # . epilogue +18084 89/<- %esp 5/r32/ebp +18085 5d/pop-to-ebp +18086 c3/return +18087 +18088 test-is-identifier-hyphen: +18089 # disallow leading '-' since '->' has special meaning +18090 # . prologue +18091 55/push-ebp +18092 89/<- %ebp 4/r32/esp +18093 # (eax..ecx) = "-a" +18094 b8/copy-to-eax "-a"/imm32 +18095 8b/-> *eax 1/r32/ecx +18096 8d/copy-address *(eax+ecx+4) 1/r32/ecx +18097 05/add-to-eax 4/imm32 +18098 # var slice/ecx: slice = {eax, ecx} +18099 51/push-ecx +18100 50/push-eax +18101 89/<- %ecx 4/r32/esp +18102 # +18103 (identifier? %ecx) +18104 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") +18105 # . epilogue +18106 89/<- %esp 5/r32/ebp +18107 5d/pop-to-ebp +18108 c3/return +18109 +18110 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) +18111 # . prologue +18112 55/push-ebp +18113 89/<- %ebp 4/r32/esp +18114 # . save registers +18115 50/push-eax +18116 56/push-esi +18117 57/push-edi +18118 # esi = in +18119 8b/-> *(ebp+8) 6/r32/esi +18120 # edi = out +18121 8b/-> *(ebp+0xc) 7/r32/edi +18122 # initialize some global state +18123 c7 0/subop/copy *Curr-block-depth 1/imm32 +18124 # parse-mu-block(in, vars, out, out->body) +18125 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body +18126 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18)) +18127 $populate-mu-function-body:end: +18128 # . restore registers +18129 5f/pop-to-edi +18130 5e/pop-to-esi +18131 58/pop-to-eax +18132 # . epilogue +18133 89/<- %esp 5/r32/ebp +18134 5d/pop-to-ebp +18135 c3/return +18136 +18137 # parses a block, assuming that the leading '{' has already been read by the caller +18138 parse-mu-block: # in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle block), err: (addr buffered-file), ed: (addr exit-descriptor) +18139 # pseudocode: +18140 # var line: (stream byte 512) +18141 # var word-slice: slice +18142 # allocate(Heap, Stmt-size, out) +18143 # var out-addr: (addr block) = lookup(*out) +18144 # out-addr->tag = 0/block +18145 # out-addr->var = some unique name +18146 # push(vars, {out-addr->var, false}) +18147 # while true # line loop +18148 # clear-stream(line) +18149 # read-line-buffered(in, line) +18150 # if (line->write == 0) break # end of file +18151 # word-slice = next-mu-token(line) +18152 # if slice-empty?(word-slice) # end of line +18153 # continue +18154 # else if slice-starts-with?(word-slice, "#") +18155 # continue +18156 # else if slice-equal?(word-slice, "{") +18157 # assert(no-tokens-in(line)) +18158 # block = parse-mu-block(in, vars, fn) +18159 # append-to-block(out-addr, block) +18160 # else if slice-equal?(word-slice, "}") +18161 # break +18162 # else if slice-ends-with?(word-slice, ":") +18163 # # TODO: error-check the rest of 'line' +18164 # --word-slice->end to skip ':' +18165 # named-block = parse-mu-named-block(word-slice, in, vars, fn) +18166 # append-to-block(out-addr, named-block) +18167 # else if slice-equal?(word-slice, "var") +18168 # var-def = parse-mu-var-def(line, vars, fn) +18169 # append-to-block(out-addr, var-def) +18170 # else +18171 # stmt = parse-mu-stmt(line, vars, fn) +18172 # append-to-block(out-addr, stmt) +18173 # pop(vars) +18174 # +18175 # . prologue +18176 55/push-ebp +18177 89/<- %ebp 4/r32/esp +18178 # . save registers +18179 50/push-eax +18180 51/push-ecx +18181 52/push-edx +18182 53/push-ebx +18183 57/push-edi +18184 # var line/ecx: (stream byte 512) +18185 81 5/subop/subtract %esp 0x200/imm32 +18186 68/push 0x200/imm32/size +18187 68/push 0/imm32/read +18188 68/push 0/imm32/write +18189 89/<- %ecx 4/r32/esp +18190 # var word-slice/edx: slice +18191 68/push 0/imm32/end +18192 68/push 0/imm32/start +18193 89/<- %edx 4/r32/esp +18194 # allocate into out +18195 (allocate Heap *Stmt-size *(ebp+0x14)) +18196 # var out-addr/edi: (addr block) = lookup(*out) +18197 8b/-> *(ebp+0x14) 7/r32/edi +18198 (lookup *edi *(edi+4)) # => eax +18199 89/<- %edi 0/r32/eax +18200 # out-addr->tag is 0 (block) by default +18201 # set out-addr->var +18202 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var +18203 (new-block-name *(ebp+0x10) %eax) +18204 # push(vars, out-addr->var) +18205 (push *(ebp+0xc) *(edi+0xc)) # Block-var +18206 (push *(ebp+0xc) *(edi+0x10)) # Block-var +18207 (push *(ebp+0xc) 0) # false +18208 # increment *Curr-block-depth +18209 ff 0/subop/increment *Curr-block-depth +18210 { +18211 $parse-mu-block:line-loop: +18212 # line = read-line-buffered(in) +18213 (clear-stream %ecx) +18214 (read-line-buffered *(ebp+8) %ecx) +18215 #? (write-buffered Stderr "line: ") +18216 #? (write-stream-data Stderr %ecx) +18217 #? #? (write-buffered Stderr Newline) # line has its own newline +18218 #? (flush Stderr) +18219 #? (rewind-stream %ecx) +18220 # if (line->write == 0) break +18221 81 7/subop/compare *ecx 0/imm32 +18222 0f 84/jump-if-= break/disp32 +18223 #? (write-buffered Stderr "vars:\n") +18224 #? (dump-vars *(ebp+0xc)) +18225 # word-slice = next-mu-token(line) +18226 (next-mu-token %ecx %edx) +18227 #? (write-buffered Stderr "word: ") +18228 #? (write-slice-buffered Stderr %edx) +18229 #? (write-buffered Stderr Newline) +18230 #? (flush Stderr) +18231 # if slice-empty?(word-slice) continue +18232 (slice-empty? %edx) +18233 3d/compare-eax-and 0/imm32/false +18234 0f 85/jump-if-!= loop/disp32 +18235 # if (slice-starts-with?(word-slice, '#') continue +18236 # . eax = *word-slice->start +18237 8b/-> *edx 0/r32/eax +18238 8a/copy-byte *eax 0/r32/AL +18239 25/and-eax-with 0xff/imm32 +18240 # . if (eax == '#') continue +18241 3d/compare-eax-and 0x23/imm32/hash +18242 0f 84/jump-if-= loop/disp32 +18243 # if slice-equal?(word-slice, "{") +18244 { +18245 $parse-mu-block:check-for-block: +18246 (slice-equal? %edx "{") +18247 3d/compare-eax-and 0/imm32/false +18248 74/jump-if-= break/disp8 +18249 (check-no-tokens-left %ecx) +18250 # parse new block and append +18251 # . var tmp/eax: (handle block) +18252 68/push 0/imm32 +18253 68/push 0/imm32 +18254 89/<- %eax 4/r32/esp +18255 # . +18256 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) +18257 (append-to-block Heap %edi *eax *(eax+4)) +18258 # . reclaim tmp +18259 81 0/subop/add %esp 8/imm32 +18260 # . +18261 e9/jump $parse-mu-block:line-loop/disp32 +18262 } +18263 # if slice-equal?(word-slice, "}") break +18264 $parse-mu-block:check-for-end: +18265 (slice-equal? %edx "}") +18266 3d/compare-eax-and 0/imm32/false +18267 0f 85/jump-if-!= break/disp32 +18268 # if slice-ends-with?(word-slice, ":") parse named block and append +18269 { +18270 $parse-mu-block:check-for-named-block: +18271 # . eax = *(word-slice->end-1) +18272 8b/-> *(edx+4) 0/r32/eax +18273 48/decrement-eax +18274 8a/copy-byte *eax 0/r32/AL +18275 25/and-eax-with 0xff/imm32 +18276 # . if (eax != ':') break +18277 3d/compare-eax-and 0x3a/imm32/colon +18278 0f 85/jump-if-!= break/disp32 +18279 # TODO: error-check the rest of 'line' +18280 # +18281 # skip ':' +18282 ff 1/subop/decrement *(edx+4) # Slice-end +18283 # var tmp/eax: (handle block) +18284 68/push 0/imm32 +18285 68/push 0/imm32 +18286 89/<- %eax 4/r32/esp 18287 # -18288 e9/jump $parse-mu-block:line-loop/disp32 -18289 } -18290 $parse-mu-block:regular-stmt: -18291 # otherwise -18292 # var tmp/eax: (handle block) -18293 68/push 0/imm32 -18294 68/push 0/imm32 -18295 89/<- %eax 4/r32/esp -18296 # -18297 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) -18298 (append-to-block Heap %edi *eax *(eax+4)) -18299 # reclaim tmp -18300 81 0/subop/add %esp 8/imm32 -18301 # -18302 e9/jump loop/disp32 -18303 } # end line loop -18304 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10)) -18305 # decrement *Curr-block-depth -18306 ff 1/subop/decrement *Curr-block-depth -18307 # pop(vars) -18308 (pop *(ebp+0xc)) # => eax -18309 (pop *(ebp+0xc)) # => eax -18310 (pop *(ebp+0xc)) # => eax -18311 $parse-mu-block:end: -18312 # . reclaim locals -18313 81 0/subop/add %esp 0x214/imm32 -18314 # . restore registers -18315 5f/pop-to-edi -18316 5b/pop-to-ebx -18317 5a/pop-to-edx -18318 59/pop-to-ecx -18319 58/pop-to-eax -18320 # . epilogue -18321 89/<- %esp 5/r32/ebp -18322 5d/pop-to-ebp -18323 c3/return -18324 -18325 $parse-mu-block:abort: -18326 # error("'{' or '}' should be on its own line, but got '") -18327 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '") -18328 (rewind-stream %ecx) -18329 (write-stream-data *(ebp+0x18) %ecx) -18330 (write-buffered *(ebp+0x18) "'\n") -18331 (flush *(ebp+0x18)) -18332 (stop *(ebp+0x1c) 1) -18333 # never gets here -18334 -18335 new-block-name: # fn: (addr function), out: (addr handle var) -18336 # . prologue -18337 55/push-ebp -18338 89/<- %ebp 4/r32/esp -18339 # . save registers -18340 50/push-eax -18341 51/push-ecx -18342 52/push-edx -18343 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' -18344 8b/-> *(ebp+8) 0/r32/eax -18345 (lookup *eax *(eax+4)) # Function-name Function-name => eax -18346 8b/-> *eax 0/r32/eax # String-size -18347 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' -18348 89/<- %ecx 0/r32/eax -18349 # var name/edx: (stream byte n) -18350 29/subtract-from %esp 1/r32/ecx -18351 ff 6/subop/push %ecx -18352 68/push 0/imm32/read -18353 68/push 0/imm32/write -18354 89/<- %edx 4/r32/esp -18355 (clear-stream %edx) -18356 # eax = fn->name -18357 8b/-> *(ebp+8) 0/r32/eax -18358 (lookup *eax *(eax+4)) # Function-name Function-name => eax -18359 # construct result using Next-block-index (and increment it) -18360 (write %edx "$") -18361 (write %edx %eax) -18362 (write %edx ":") -18363 (write-int32-hex %edx *Next-block-index) -18364 ff 0/subop/increment *Next-block-index -18365 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) -18366 # . eax = name->write -18367 8b/-> *edx 0/r32/eax -18368 # . edx = name->data -18369 8d/copy-address *(edx+0xc) 2/r32/edx -18370 # . eax = name->write + name->data -18371 01/add-to %eax 2/r32/edx -18372 # . push {edx, eax} -18373 ff 6/subop/push %eax -18374 ff 6/subop/push %edx -18375 89/<- %eax 4/r32/esp -18376 # out = new literal(s) -18377 (new-literal Heap %eax *(ebp+0xc)) -18378 #? 8b/-> *(ebp+0xc) 0/r32/eax -18379 #? (write-buffered Stderr "type allocid in caller after new-literal: ") -18380 #? (write-int32-hex-buffered Stderr *(eax+8)) -18381 #? (write-buffered Stderr " for var ") -18382 #? (write-int32-hex-buffered Stderr %eax) -18383 #? (write-buffered Stderr Newline) -18384 #? (flush Stderr) -18385 $new-block-name:end: -18386 # . reclaim locals -18387 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} -18388 81 0/subop/add %ecx 8/imm32 # slice -18389 01/add-to %esp 1/r32/ecx -18390 # . restore registers -18391 5a/pop-to-edx -18392 59/pop-to-ecx -18393 58/pop-to-eax -18394 # . epilogue -18395 89/<- %esp 5/r32/ebp -18396 5d/pop-to-ebp -18397 c3/return -18398 -18399 check-no-tokens-left: # line: (addr stream byte) -18400 # . prologue -18401 55/push-ebp -18402 89/<- %ebp 4/r32/esp -18403 # . save registers -18404 50/push-eax -18405 51/push-ecx -18406 # var s/ecx: slice -18407 68/push 0/imm32/end -18408 68/push 0/imm32/start -18409 89/<- %ecx 4/r32/esp -18410 # -18411 (next-mu-token *(ebp+8) %ecx) -18412 # if slice-empty?(s) return -18413 (slice-empty? %ecx) -18414 3d/compare-eax-and 0/imm32/false -18415 75/jump-if-!= $check-no-tokens-left:end/disp8 -18416 # if (slice-starts-with?(s, '#') return -18417 # . eax = *s->start -18418 8b/-> *edx 0/r32/eax -18419 8a/copy-byte *eax 0/r32/AL -18420 25/and-eax-with 0xff/imm32 -18421 # . if (eax == '#') continue -18422 3d/compare-eax-and 0x23/imm32/hash -18423 74/jump-if-= $check-no-tokens-left:end/disp8 -18424 # abort -18425 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") -18426 (rewind-stream %ecx) -18427 (write-stream 2 %ecx) -18428 (write-buffered Stderr "'\n") -18429 (flush Stderr) -18430 # . syscall(exit, 1) -18431 bb/copy-to-ebx 1/imm32 -18432 e8/call syscall_exit/disp32 -18433 # never gets here -18434 $check-no-tokens-left:end: -18435 # . reclaim locals -18436 81 0/subop/add %esp 8/imm32 -18437 # . restore registers -18438 59/pop-to-ecx -18439 58/pop-to-eax -18440 # . epilogue -18441 89/<- %esp 5/r32/ebp -18442 5d/pop-to-ebp -18443 c3/return -18444 -18445 parse-mu-named-block: # name: (addr slice), in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -18446 # pseudocode: -18447 # var v: (handle var) -18448 # new-literal(name, v) -18449 # push(vars, {v, false}) -18450 # parse-mu-block(in, vars, fn, out) -18451 # pop(vars) -18452 # out->tag = block -18453 # out->var = v -18454 # -18455 # . prologue -18456 55/push-ebp -18457 89/<- %ebp 4/r32/esp -18458 # . save registers -18459 50/push-eax -18460 51/push-ecx -18461 57/push-edi -18462 # var v/ecx: (handle var) -18463 68/push 0/imm32 -18464 68/push 0/imm32 -18465 89/<- %ecx 4/r32/esp -18466 # -18467 (new-literal Heap *(ebp+8) %ecx) -18468 # push(vars, v) -18469 (push *(ebp+0x10) *ecx) -18470 (push *(ebp+0x10) *(ecx+4)) -18471 (push *(ebp+0x10) 0) # false -18472 # -18473 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20)) -18474 # pop v off vars -18475 (pop *(ebp+0x10)) # => eax -18476 (pop *(ebp+0x10)) # => eax -18477 (pop *(ebp+0x10)) # => eax -18478 # var out-addr/edi: (addr stmt) = lookup(*out) -18479 8b/-> *(ebp+0x18) 7/r32/edi -18480 (lookup *edi *(edi+4)) # => eax -18481 89/<- %edi 0/r32/eax -18482 # out-addr->tag = named-block -18483 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag -18484 # out-addr->var = v -18485 8b/-> *ecx 0/r32/eax -18486 89/<- *(edi+0xc) 0/r32/eax # Block-var -18487 8b/-> *(ecx+4) 0/r32/eax -18488 89/<- *(edi+0x10) 0/r32/eax # Block-var -18489 $parse-mu-named-block:end: -18490 # . reclaim locals -18491 81 0/subop/add %esp 8/imm32 -18492 # . restore registers -18493 5f/pop-to-edi -18494 59/pop-to-ecx -18495 58/pop-to-eax -18496 # . epilogue -18497 89/<- %esp 5/r32/ebp -18498 5d/pop-to-ebp -18499 c3/return -18500 -18501 parse-mu-var-def: # line: (addr stream byte), vars: (addr stack live-var), out: (addr handle stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -18502 # . prologue -18503 55/push-ebp -18504 89/<- %ebp 4/r32/esp -18505 # . save registers -18506 50/push-eax -18507 51/push-ecx -18508 52/push-edx -18509 56/push-esi -18510 57/push-edi -18511 # edi = out -18512 8b/-> *(ebp+0x10) 7/r32/edi -18513 # var word-slice/ecx: slice -18514 68/push 0/imm32/end -18515 68/push 0/imm32/start -18516 89/<- %ecx 4/r32/esp -18517 # var v/edx: (handle var) -18518 68/push 0/imm32 -18519 68/push 0/imm32 -18520 89/<- %edx 4/r32/esp -18521 # v = parse-var-with-type(next-mu-token(line)) -18522 (next-mu-token *(ebp+8) %ecx) -18523 { -18524 # just for tests, support null fn -18525 8b/-> *(ebp+0x14) 0/r32/eax -18526 3d/compare-eax-and 0/imm32 -18527 74/jump-if-= break/disp8 -18528 (lookup *eax *(eax+4)) # Var-name Var-name => eax -18529 } -18530 (parse-var-with-type %ecx *(ebp+8) %edx %eax *(ebp+0x18) *(ebp+0x1c)) -18531 # var v-addr/esi: (addr var) -18532 (lookup *edx *(edx+4)) # => eax -18533 89/<- %esi 0/r32/eax -18534 # v->block-depth = *Curr-block-depth -18535 8b/-> *Curr-block-depth 0/r32/eax -18536 89/<- *(esi+0x10) 0/r32/eax # Var-block-depth -18537 # either v has no register and there's no more to this line -18538 81 7/subop/compare *(esi+0x18) 0/imm32 -18539 { -18540 75/jump-if-!= break/disp8 -18541 # if v-addr->type == byte, abort -18542 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -18543 (simple-mu-type? %eax 8) # byte => eax -18544 3d/compare-eax-and 0/imm32/false -18545 0f 85/jump-if-!= $parse-mu-var-def:error-byte-on-stack/disp32 -18546 # ensure that there's nothing else on this line -18547 (next-mu-token *(ebp+8) %ecx) -18548 (slice-empty? %ecx) # => eax -18549 3d/compare-eax-and 0/imm32/false -18550 0f 84/jump-if-= $parse-mu-var-def:error2/disp32 -18551 # -18552 (new-var-def Heap *edx *(edx+4) %edi) -18553 e9/jump $parse-mu-var-def:update-vars/disp32 -18554 } -18555 # or v has a register and there's more to this line -18556 { -18557 0f 84/jump-if-= break/disp32 -18558 # if v-addr->type == byte, check for unsupported registers -18559 { -18560 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -18561 (simple-mu-type? %eax 8) # byte => eax -18562 3d/compare-eax-and 0/imm32/false -18563 74/jump-if-= break/disp8 -18564 (lookup *(esi+0x18) *(esi+0x1c)) # => eax -18565 (string-equal? %eax "esi") # => eax -18566 3d/compare-eax-and 0/imm32/false -18567 0f 85/jump-if-!= $parse-mu-var-def:error-byte-registers/disp32 -18568 (lookup *(esi+0x18) *(esi+0x1c)) # => eax -18569 (string-equal? %eax "edi") # => eax -18570 3d/compare-eax-and 0/imm32/false -18571 0f 85/jump-if-!= $parse-mu-var-def:error-byte-registers/disp32 -18572 } -18573 # TODO: vars of type 'byte' should only be initialized by clearing to 0 -18574 # ensure that the next word is '<-' -18575 (next-mu-token *(ebp+8) %ecx) -18576 (slice-equal? %ecx "<-") # => eax -18577 3d/compare-eax-and 0/imm32/false -18578 0f 84/jump-if-= $parse-mu-var-def:error1/disp32 -18579 # -18580 (new-reg-var-def Heap *edx *(edx+4) %edi) -18581 (lookup *edi *(edi+4)) # => eax -18582 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -18583 } -18584 $parse-mu-var-def:update-vars: -18585 # push 'v' at end of function -18586 (push *(ebp+0xc) *edx) -18587 (push *(ebp+0xc) *(edx+4)) -18588 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing -18589 $parse-mu-var-def:end: -18590 # . reclaim locals -18591 81 0/subop/add %esp 0x10/imm32 -18592 # . restore registers -18593 5f/pop-to-edi -18594 5e/pop-to-esi -18595 5a/pop-to-edx -18596 59/pop-to-ecx -18597 58/pop-to-eax -18598 # . epilogue -18599 89/<- %esp 5/r32/ebp -18600 5d/pop-to-ebp -18601 c3/return -18602 -18603 $parse-mu-var-def:error1: -18604 (rewind-stream *(ebp+8)) -18605 # error("register variable requires a valid instruction to initialize but got '" line "'\n") -18606 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '") -18607 (flush *(ebp+0x18)) -18608 (write-stream-data *(ebp+0x18) *(ebp+8)) -18609 (write-buffered *(ebp+0x18) "'\n") -18610 (flush *(ebp+0x18)) -18611 (stop *(ebp+0x1c) 1) -18612 # never gets here -18613 -18614 $parse-mu-var-def:error2: -18615 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n") -18616 (write-buffered *(ebp+0x18) "fn ") -18617 8b/-> *(ebp+0x14) 0/r32/eax -18618 (lookup *eax *(eax+4)) # Function-name Function-name => eax -18619 (write-buffered *(ebp+0x18) %eax) -18620 (write-buffered *(ebp+0x18) ": var ") -18621 # var v-addr/eax: (addr var) = lookup(v) -18622 (lookup *edx *(edx+4)) # => eax -18623 (lookup *eax *(eax+4)) # Var-name Var-name => eax -18624 (write-buffered *(ebp+0x18) %eax) -18625 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n") -18626 (flush *(ebp+0x18)) -18627 (stop *(ebp+0x1c) 1) -18628 # never gets here -18629 -18630 $parse-mu-var-def:error-byte-on-stack: -18631 # error("fn " fn ": var '" var "' of type 'byte' cannot be on the stack\n") -18632 (write-buffered *(ebp+0x18) "fn ") -18633 8b/-> *(ebp+0x14) 0/r32/eax -18634 (lookup *eax *(eax+4)) # Function-name Function-name => eax -18635 (write-buffered *(ebp+0x18) %eax) -18636 (write-buffered *(ebp+0x18) ": var '") -18637 # var v-addr/eax: (addr var) = lookup(v) -18638 (lookup *edx *(edx+4)) # => eax -18639 (lookup *eax *(eax+4)) # Var-name Var-name => eax -18640 (write-buffered *(ebp+0x18) %eax) -18641 (write-buffered *(ebp+0x18) "' of type 'byte' cannot be on the stack\n") -18642 (flush *(ebp+0x18)) -18643 (stop *(ebp+0x1c) 1) -18644 # never gets here -18645 -18646 $parse-mu-var-def:error-byte-registers: -18647 # error("fn " fn ": var '" var "' of type 'byte' cannot be in esi or edi\n") -18648 (write-buffered *(ebp+0x18) "fn ") -18649 8b/-> *(ebp+0x14) 0/r32/eax -18650 (lookup *eax *(eax+4)) # Function-name Function-name => eax -18651 (write-buffered *(ebp+0x18) %eax) -18652 (write-buffered *(ebp+0x18) ": var '") -18653 # var v-addr/eax: (addr var) = lookup(v) -18654 (lookup *edx *(edx+4)) # => eax -18655 (lookup *eax *(eax+4)) # Var-name Var-name => eax -18656 (write-buffered *(ebp+0x18) %eax) -18657 (write-buffered *(ebp+0x18) "' of type 'byte' cannot be in esi or edi\n") -18658 (flush *(ebp+0x18)) -18659 (stop *(ebp+0x1c) 1) -18660 # never gets here -18661 -18662 test-parse-mu-var-def: -18663 # 'var n: int' -18664 # . prologue -18665 55/push-ebp -18666 89/<- %ebp 4/r32/esp -18667 # setup -18668 8b/-> *Primitive-type-ids 0/r32/eax -18669 89/<- *Type-id 0/r32/eax # stream-write -18670 (clear-stream _test-input-stream) -18671 (write _test-input-stream "n: int\n") # caller has consumed the 'var' -18672 c7 0/subop/copy *Curr-block-depth 1/imm32 -18673 # var out/esi: (handle stmt) -18674 68/push 0/imm32 -18675 68/push 0/imm32 -18676 89/<- %esi 4/r32/esp -18677 # var vars/ecx: (stack (addr var) 16) -18678 81 5/subop/subtract %esp 0xc0/imm32 -18679 68/push 0xc0/imm32/size -18680 68/push 0/imm32/top -18681 89/<- %ecx 4/r32/esp -18682 (clear-stack %ecx) -18683 # convert -18684 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) -18685 # var out-addr/esi: (addr stmt) -18686 (lookup *esi *(esi+4)) # => eax -18687 89/<- %esi 0/r32/eax -18688 # -18689 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def -18690 # var v/ecx: (addr var) = lookup(out->var) -18691 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax -18692 89/<- %ecx 0/r32/eax -18693 # v->name -18694 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -18695 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") -18696 # v->register -18697 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register -18698 # v->block-depth -18699 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth -18700 # v->type == int -18701 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -18702 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Type-tree-is-atom -18703 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Type-tree-value -18704 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Type-tree-right -18705 # . epilogue -18706 89/<- %esp 5/r32/ebp -18707 5d/pop-to-ebp -18708 c3/return -18709 -18710 test-parse-mu-reg-var-def: -18711 # 'var n/eax: int <- copy 0' -18712 # . prologue -18713 55/push-ebp -18714 89/<- %ebp 4/r32/esp -18715 # setup -18716 8b/-> *Primitive-type-ids 0/r32/eax -18717 89/<- *Type-id 0/r32/eax # stream-write -18718 (clear-stream _test-input-stream) -18719 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' -18720 c7 0/subop/copy *Curr-block-depth 1/imm32 -18721 # var out/esi: (handle stmt) -18722 68/push 0/imm32 -18723 68/push 0/imm32 -18724 89/<- %esi 4/r32/esp -18725 # var vars/ecx: (stack (addr var) 16) -18726 81 5/subop/subtract %esp 0xc0/imm32 -18727 68/push 0xc0/imm32/size -18728 68/push 0/imm32/top -18729 89/<- %ecx 4/r32/esp -18730 (clear-stack %ecx) -18731 # convert -18732 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) -18733 # var out-addr/esi: (addr stmt) -18734 (lookup *esi *(esi+4)) # => eax -18735 89/<- %esi 0/r32/eax -18736 # -18737 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def -18738 # var v/ecx: (addr var) = lookup(out->outputs->value) -18739 # . eax: (addr stmt-var) = lookup(out->outputs) -18740 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax -18741 # . -18742 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next -18743 # . eax: (addr var) = lookup(eax->value) -18744 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -18745 # . ecx = eax -18746 89/<- %ecx 0/r32/eax -18747 # v->name -18748 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -18749 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name -18750 # v->register -18751 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -18752 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") -18753 # v->block-depth -18754 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth -18755 # v->type == int -18756 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -18757 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Type-tree-is-atom -18758 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Type-tree-value -18759 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Type-tree-right -18760 # . epilogue -18761 89/<- %esp 5/r32/ebp -18762 5d/pop-to-ebp -18763 c3/return -18764 -18765 parse-mu-stmt: # line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -18766 # pseudocode: -18767 # var name: slice -18768 # allocate(Heap, Stmt-size, out) -18769 # var out-addr: (addr stmt) = lookup(*out) -18770 # out-addr->tag = stmt -18771 # if stmt-has-outputs?(line) -18772 # while true -18773 # name = next-mu-token(line) -18774 # if (name == '<-') break -18775 # assert(identifier?(name)) -18776 # var v: (handle var) = lookup-var(name, vars) -18777 # out-addr->outputs = append(v, out-addr->outputs) -18778 # add-operation-and-inputs-to-stmt(out-addr, line, vars) -18779 # -18780 # . prologue -18781 55/push-ebp -18782 89/<- %ebp 4/r32/esp -18783 # . save registers -18784 50/push-eax -18785 51/push-ecx -18786 52/push-edx -18787 53/push-ebx -18788 57/push-edi -18789 # var name/ecx: slice -18790 68/push 0/imm32/end -18791 68/push 0/imm32/start -18792 89/<- %ecx 4/r32/esp -18793 # var is-deref?/edx: boolean = false -18794 ba/copy-to-edx 0/imm32/false -18795 # var v: (handle var) -18796 68/push 0/imm32 -18797 68/push 0/imm32 -18798 89/<- %ebx 4/r32/esp -18799 # -18800 (allocate Heap *Stmt-size *(ebp+0x14)) -18801 # var out-addr/edi: (addr stmt) = lookup(*out) -18802 8b/-> *(ebp+0x14) 7/r32/edi -18803 (lookup *edi *(edi+4)) # => eax -18804 89/<- %edi 0/r32/eax -18805 # out-addr->tag = 1/stmt -18806 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag -18807 { -18808 (stmt-has-outputs? *(ebp+8)) -18809 3d/compare-eax-and 0/imm32/false -18810 0f 84/jump-if-= break/disp32 -18811 { -18812 $parse-mu-stmt:read-outputs: -18813 # name = next-mu-token(line) -18814 (next-mu-token *(ebp+8) %ecx) -18815 # if slice-empty?(word-slice) break -18816 (slice-empty? %ecx) # => eax -18817 3d/compare-eax-and 0/imm32/false -18818 0f 85/jump-if-!= break/disp32 -18819 # if (name == "<-") break -18820 (slice-equal? %ecx "<-") # => eax -18821 3d/compare-eax-and 0/imm32/false -18822 0f 85/jump-if-!= break/disp32 -18823 # if slice-starts-with?(name, "*") abort -18824 8b/-> *ecx 0/r32/eax # Slice-start -18825 8a/copy-byte *eax 0/r32/AL -18826 25/and-eax-with 0xff/imm32 -18827 3d/compare-eax-and 0x2a/imm32/asterisk -18828 0f 84/jump-if-= $parse-mu-stmt:error-output-dereferenced/disp32 -18829 # assert(identifier?(name)) -18830 (identifier? %ecx) # => eax -18831 3d/compare-eax-and 0/imm32/false -18832 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 -18833 # -18834 (lookup-var %ecx *(ebp+0xc) %ebx *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) -18835 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs -18836 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) 0 %eax) # Stmt1-outputs -18837 # -18838 e9/jump loop/disp32 -18839 } -18840 } -18841 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) -18842 $parse-mu-stmt:end: -18843 # . reclaim locals -18844 81 0/subop/add %esp 0x10/imm32 -18845 # . restore registers -18846 5f/pop-to-edi -18847 5b/pop-to-ebx -18848 5a/pop-to-edx -18849 59/pop-to-ecx -18850 58/pop-to-eax -18851 # . epilogue -18852 89/<- %esp 5/r32/ebp -18853 5d/pop-to-ebp -18854 c3/return -18855 -18856 $parse-mu-stmt:abort: -18857 # error("invalid identifier '" name "'\n") -18858 (write-buffered *(ebp+0x18) "fn ") -18859 8b/-> *(ebp+0x10) 0/r32/eax -18860 (lookup *eax *(eax+4)) # Function-name Function-name => eax -18861 (write-buffered *(ebp+0x18) %eax) -18862 (write-buffered *(ebp+0x18) ": invalid identifier '") -18863 (write-slice-buffered *(ebp+0x18) %ecx) -18864 (write-buffered *(ebp+0x18) "'\n") -18865 (flush *(ebp+0x18)) -18866 (stop *(ebp+0x1c) 1) -18867 # never gets here -18868 -18869 $parse-mu-stmt:error-output-dereferenced: -18870 # error("invalid identifier '" name "'\n") -18871 (write-buffered *(ebp+0x18) "fn ") -18872 8b/-> *(ebp+0x10) 0/r32/eax -18873 (lookup *eax *(eax+4)) # Function-name Function-name => eax -18874 (write-buffered *(ebp+0x18) %eax) -18875 (write-buffered *(ebp+0x18) ": output '") -18876 (write-slice-buffered *(ebp+0x18) %ecx) -18877 (write-buffered *(ebp+0x18) "' should write to a register, and therefore cannot be dereferenced\n") -18878 (flush *(ebp+0x18)) -18879 (stop *(ebp+0x1c) 1) -18880 # never gets here -18881 -18882 add-operation-and-inputs-to-stmt: # stmt: (addr stmt), line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -18883 # pseudocode: -18884 # stmt->name = slice-to-string(next-mu-token(line)) -18885 # while true -18886 # name = next-mu-token(line) -18887 # v = lookup-var-or-literal(name) -18888 # stmt->inouts = append(v, stmt->inouts) -18889 # -18890 # . prologue -18891 55/push-ebp -18892 89/<- %ebp 4/r32/esp -18893 # . save registers -18894 50/push-eax -18895 51/push-ecx -18896 52/push-edx -18897 53/push-ebx -18898 56/push-esi -18899 57/push-edi -18900 # edi = stmt -18901 8b/-> *(ebp+8) 7/r32/edi -18902 # var name/ecx: slice -18903 68/push 0/imm32/end -18904 68/push 0/imm32/start -18905 89/<- %ecx 4/r32/esp -18906 # var is-deref?/edx: boolean = false -18907 ba/copy-to-edx 0/imm32/false -18908 # var v/esi: (handle var) -18909 68/push 0/imm32 -18910 68/push 0/imm32 -18911 89/<- %esi 4/r32/esp -18912 $add-operation-and-inputs-to-stmt:read-operation: -18913 (next-mu-token *(ebp+0xc) %ecx) -18914 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation -18915 (slice-to-string Heap %ecx %eax) -18916 # var is-get?/ebx: boolean = (name == "get") -18917 (slice-equal? %ecx "get") # => eax -18918 89/<- %ebx 0/r32/eax -18919 { -18920 $add-operation-and-inputs-to-stmt:read-inouts: -18921 # name = next-mu-token(line) -18922 (next-mu-token *(ebp+0xc) %ecx) -18923 # if slice-empty?(word-slice) break -18924 (slice-empty? %ecx) # => eax -18925 3d/compare-eax-and 0/imm32/false -18926 0f 85/jump-if-!= break/disp32 -18927 # if (name == "<-") abort -18928 (slice-equal? %ecx "<-") -18929 3d/compare-eax-and 0/imm32/false -18930 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 -18931 # if (get? && second operand) lookup or create offset -18932 { -18933 81 7/subop/compare %ebx 0/imm32/false -18934 74/jump-if-= break/disp8 -18935 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -18936 3d/compare-eax-and 0/imm32 -18937 74/jump-if-= break/disp8 -18938 (lookup-or-create-constant %eax %ecx %esi) -18939 #? (lookup *esi *(esi+4)) -18940 #? (write-buffered Stderr "creating new output var ") -18941 #? (write-int32-hex-buffered Stderr %eax) -18942 #? (write-buffered Stderr " for field called ") -18943 #? (write-slice-buffered Stderr %ecx) -18944 #? (write-buffered Stderr "; var name ") -18945 #? (lookup *eax *(eax+4)) # Var-name -18946 #? (write-buffered Stderr %eax) -18947 #? (write-buffered Stderr Newline) -18948 #? (flush Stderr) -18949 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 -18950 } -18951 # is-deref? = false -18952 ba/copy-to-edx 0/imm32/false -18953 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? -18954 8b/-> *ecx 0/r32/eax # Slice-start -18955 8a/copy-byte *eax 0/r32/AL -18956 25/and-eax-with 0xff/imm32 -18957 3d/compare-eax-and 0x2a/imm32/asterisk -18958 { -18959 75/jump-if-!= break/disp8 -18960 $add-operation-and-inputs-to-stmt:inout-is-deref: -18961 ff 0/subop/increment *ecx -18962 ba/copy-to-edx 1/imm32/true -18963 } -18964 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -18965 # if (deref?) some additional checks -18966 81 7/subop/compare %edx 0/imm32/false -18967 { -18968 74/jump-if-= break/disp8 -18969 # if var is not in register, abort -18970 (lookup *esi *(esi+4)) # => eax -18971 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -18972 0f 84/jump-if-= $add-operation-and-inputs-to-stmt:error-deref-on-stack/disp32 -18973 # if var is not an address, abort -18974 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -18975 (mu-addr-type? %eax) # => eax -18976 3d/compare-eax-and 0/imm32/false -18977 0f 84/jump-if-= $add-operation-and-inputs-to-stmt:error-deref-non-addr/disp32 -18978 } -18979 $add-operation-and-inputs-to-stmt:save-var: -18980 8d/copy-address *(edi+0xc) 0/r32/eax -18981 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts -18982 # -18983 e9/jump loop/disp32 -18984 } -18985 $add-operation-and-inputs-to-stmt:end: -18986 # . reclaim locals -18987 81 0/subop/add %esp 0x10/imm32 -18988 # . restore registers -18989 5f/pop-to-edi -18990 5e/pop-to-esi -18991 5b/pop-to-ebx -18992 5a/pop-to-edx -18993 59/pop-to-ecx -18994 58/pop-to-eax -18995 # . epilogue -18996 89/<- %esp 5/r32/ebp -18997 5d/pop-to-ebp -18998 c3/return -18999 -19000 $add-operation-and-inputs-to-stmt:abort: -19001 # error("fn ___: invalid identifier in '" line "'\n") -19002 (write-buffered *(ebp+0x18) "fn ") -19003 8b/-> *(ebp+0x14) 0/r32/eax -19004 (lookup *eax *(eax+4)) # Function-name Function-name => eax -19005 (write-buffered *(ebp+0x18) %eax) -19006 (rewind-stream *(ebp+0xc)) -19007 (write-buffered *(ebp+0x18) ": invalid identifier in '") -19008 (write-stream-data *(ebp+0x18) *(ebp+0xc)) -19009 (write-buffered *(ebp+0x18) "'\n") -19010 (flush *(ebp+0x18)) -19011 (stop *(ebp+0x1c) 1) -19012 # never gets here -19013 -19014 $add-operation-and-inputs-to-stmt:error-deref-on-stack: -19015 # error("fn ___: cannot dereference var ___ on stack\n") -19016 (write-buffered *(ebp+0x18) "fn ") -19017 8b/-> *(ebp+0x14) 0/r32/eax -19018 (lookup *eax *(eax+4)) # Function-name Function-name => eax -19019 (write-buffered *(ebp+0x18) %eax) -19020 (rewind-stream *(ebp+0xc)) -19021 (write-buffered *(ebp+0x18) ": cannot dereference var '") -19022 (lookup *esi *(esi+4)) # => eax -19023 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19024 (write-buffered *(ebp+0x18) %eax) -19025 (write-buffered *(ebp+0x18) "' on stack\n") -19026 (flush *(ebp+0x18)) -19027 (stop *(ebp+0x1c) 1) -19028 # never gets here -19029 -19030 $add-operation-and-inputs-to-stmt:error-deref-non-addr: -19031 # error("fn ___: cannot dereference non-addr var ___\n") -19032 (write-buffered *(ebp+0x18) "fn ") -19033 8b/-> *(ebp+0x14) 0/r32/eax -19034 (lookup *eax *(eax+4)) # Function-name Function-name => eax -19035 (write-buffered *(ebp+0x18) %eax) -19036 (rewind-stream *(ebp+0xc)) -19037 (write-buffered *(ebp+0x18) ": cannot dereference non-addr var '") -19038 (lookup *esi *(esi+4)) # => eax -19039 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19040 (write-buffered *(ebp+0x18) %eax) -19041 (write-buffered *(ebp+0x18) "'\n") -19042 (flush *(ebp+0x18)) -19043 (stop *(ebp+0x1c) 1) -19044 # never gets here -19045 -19046 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean -19047 # . prologue -19048 55/push-ebp -19049 89/<- %ebp 4/r32/esp -19050 # . save registers -19051 51/push-ecx -19052 # var word-slice/ecx: slice -19053 68/push 0/imm32/end -19054 68/push 0/imm32/start -19055 89/<- %ecx 4/r32/esp -19056 # result = false -19057 b8/copy-to-eax 0/imm32/false -19058 (rewind-stream *(ebp+8)) -19059 { -19060 (next-mu-token *(ebp+8) %ecx) -19061 # if slice-empty?(word-slice) break -19062 (slice-empty? %ecx) -19063 3d/compare-eax-and 0/imm32/false -19064 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) -19065 0f 85/jump-if-!= break/disp32 -19066 # if slice-starts-with?(word-slice, '#') break -19067 # . eax = *word-slice->start -19068 8b/-> *ecx 0/r32/eax -19069 8a/copy-byte *eax 0/r32/AL -19070 25/and-eax-with 0xff/imm32 -19071 # . if (eax == '#') break -19072 3d/compare-eax-and 0x23/imm32/hash -19073 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) -19074 0f 84/jump-if-= break/disp32 -19075 # if slice-equal?(word-slice, '<-') return true -19076 (slice-equal? %ecx "<-") -19077 3d/compare-eax-and 0/imm32/false -19078 74/jump-if-= loop/disp8 -19079 b8/copy-to-eax 1/imm32/true -19080 } -19081 $stmt-has-outputs:end: -19082 (rewind-stream *(ebp+8)) -19083 # . reclaim locals -19084 81 0/subop/add %esp 8/imm32 -19085 # . restore registers -19086 59/pop-to-ecx -19087 # . epilogue -19088 89/<- %esp 5/r32/ebp -19089 5d/pop-to-ebp -19090 c3/return -19091 -19092 # if 'name' starts with a digit, create a new literal var for it -19093 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found -19094 lookup-var-or-literal: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -19095 # . prologue -19096 55/push-ebp -19097 89/<- %ebp 4/r32/esp -19098 # . save registers -19099 50/push-eax -19100 51/push-ecx -19101 56/push-esi -19102 # esi = name -19103 8b/-> *(ebp+8) 6/r32/esi -19104 # if slice-empty?(name) abort -19105 (slice-empty? %esi) # => eax -19106 3d/compare-eax-and 0/imm32/false -19107 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 -19108 # var c/ecx: byte = *name->start -19109 8b/-> *esi 1/r32/ecx -19110 8a/copy-byte *ecx 1/r32/CL -19111 81 4/subop/and %ecx 0xff/imm32 -19112 # if (decimal-digit?(c) || c == '-') return new var(name) -19113 { -19114 81 7/subop/compare %ecx 0x2d/imm32/dash -19115 74/jump-if-= $lookup-var-or-literal:literal/disp8 -19116 (decimal-digit? %ecx) # => eax -19117 3d/compare-eax-and 0/imm32/false -19118 74/jump-if-= break/disp8 -19119 $lookup-var-or-literal:literal: -19120 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -19121 eb/jump $lookup-var-or-literal:end/disp8 -19122 } -19123 # else if (c == '"') return new var(name) -19124 { -19125 81 7/subop/compare %ecx 0x22/imm32/dquote -19126 75/jump-if-!= break/disp8 -19127 $lookup-var-or-literal:literal-string: -19128 (new-literal-string Heap %esi *(ebp+0x10)) -19129 eb/jump $lookup-var-or-literal:end/disp8 -19130 } -19131 # otherwise return lookup-var(name, vars) -19132 { -19133 $lookup-var-or-literal:var: -19134 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -19135 } -19136 $lookup-var-or-literal:end: -19137 # . restore registers -19138 5e/pop-to-esi -19139 59/pop-to-ecx -19140 58/pop-to-eax -19141 # . epilogue -19142 89/<- %esp 5/r32/ebp -19143 5d/pop-to-ebp -19144 c3/return -19145 -19146 $lookup-var-or-literal:abort: -19147 (write-buffered *(ebp+0x18) "fn ") -19148 8b/-> *(ebp+0x14) 0/r32/eax -19149 (lookup *eax *(eax+4)) # Function-name Function-name => eax -19150 (write-buffered *(ebp+0x18) %eax) -19151 (write-buffered *(ebp+0x18) ": empty variable!") -19152 (flush *(ebp+0x18)) -19153 (stop *(ebp+0x1c) 1) -19154 # never gets here -19155 -19156 # return first 'name' from the top (back) of 'vars' and abort if not found -19157 lookup-var: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -19158 # . prologue -19159 55/push-ebp -19160 89/<- %ebp 4/r32/esp -19161 # . save registers -19162 50/push-eax -19163 # -19164 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -19165 # if (*out == 0) abort -19166 8b/-> *(ebp+0x10) 0/r32/eax -19167 81 7/subop/compare *eax 0/imm32 -19168 74/jump-if-= $lookup-var:abort/disp8 -19169 $lookup-var:end: -19170 # . restore registers -19171 58/pop-to-eax -19172 # . epilogue -19173 89/<- %esp 5/r32/ebp -19174 5d/pop-to-ebp -19175 c3/return -19176 -19177 $lookup-var:abort: -19178 (write-buffered *(ebp+0x18) "fn ") -19179 8b/-> *(ebp+0x14) 0/r32/eax -19180 (lookup *eax *(eax+4)) # Function-name Function-name => eax -19181 (write-buffered *(ebp+0x18) %eax) -19182 (write-buffered *(ebp+0x18) ": unknown variable '") -19183 (write-slice-buffered *(ebp+0x18) *(ebp+8)) -19184 (write-buffered *(ebp+0x18) "'\n") -19185 (flush *(ebp+0x18)) -19186 (stop *(ebp+0x1c) 1) -19187 # never gets here -19188 -19189 # return first 'name' from the top (back) of 'vars', and 0/null if not found -19190 # ensure that 'name' if in a register is the topmost variable in that register -19191 lookup-var-helper: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -19192 # pseudocode: -19193 # var curr: (addr handle var) = &vars->data[vars->top - 12] -19194 # var min = vars->data -19195 # while curr >= min -19196 # var v: (handle var) = *curr -19197 # if v->name == name -19198 # return -19199 # curr -= 12 -19200 # -19201 # . prologue -19202 55/push-ebp -19203 89/<- %ebp 4/r32/esp -19204 # . save registers -19205 50/push-eax -19206 51/push-ecx -19207 52/push-edx -19208 53/push-ebx -19209 56/push-esi -19210 57/push-edi -19211 # clear out -19212 (zero-out *(ebp+0x10) *Handle-size) -19213 # esi = vars -19214 8b/-> *(ebp+0xc) 6/r32/esi -19215 # ebx = vars->top -19216 8b/-> *esi 3/r32/ebx -19217 # if (vars->top > vars->size) abort -19218 3b/compare<- *(esi+4) 0/r32/eax -19219 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 -19220 # var min/edx: (addr handle var) = vars->data -19221 8d/copy-address *(esi+8) 2/r32/edx -19222 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] -19223 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 -19224 # var var-in-reg/edi: 16 addrs -19225 68/push 0/imm32 -19226 68/push 0/imm32 -19227 68/push 0/imm32 -19228 68/push 0/imm32 -19229 68/push 0/imm32 -19230 68/push 0/imm32 -19231 68/push 0/imm32 -19232 68/push 0/imm32 -19233 68/push 0/imm32 -19234 68/push 0/imm32 -19235 68/push 0/imm32 -19236 68/push 0/imm32 -19237 68/push 0/imm32 -19238 68/push 0/imm32 -19239 68/push 0/imm32 -19240 68/push 0/imm32 -19241 89/<- %edi 4/r32/esp -19242 { -19243 $lookup-var-helper:loop: -19244 # if (curr < min) return -19245 39/compare %ebx 2/r32/edx -19246 0f 82/jump-if-addr< break/disp32 -19247 # var v/ecx: (addr var) = lookup(*curr) -19248 (lookup *ebx *(ebx+4)) # => eax -19249 89/<- %ecx 0/r32/eax -19250 # var vn/eax: (addr array byte) = lookup(v->name) -19251 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -19252 # if (vn == name) return curr -19253 (slice-equal? *(ebp+8) %eax) # => eax -19254 3d/compare-eax-and 0/imm32/false -19255 { -19256 74/jump-if-= break/disp8 -19257 $lookup-var-helper:found: -19258 # var vr/eax: (addr array byte) = lookup(v->register) -19259 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -19260 3d/compare-eax-and 0/imm32 -19261 { -19262 74/jump-if-= break/disp8 -19263 $lookup-var-helper:found-register: -19264 # var reg/eax: int = get(Registers, vr) -19265 (get Mu-registers-unique %eax 0xc "Mu-registers-unique") # => eax -19266 8b/-> *eax 0/r32/eax -19267 # if (var-in-reg[reg]) error -19268 8b/-> *(edi+eax<<2) 0/r32/eax -19269 3d/compare-eax-and 0/imm32 -19270 0f 85/jump-if-!= $lookup-var-helper:error2/disp32 -19271 } -19272 $lookup-var-helper:return: -19273 # esi = out -19274 8b/-> *(ebp+0x10) 6/r32/esi -19275 # *out = *curr -19276 8b/-> *ebx 0/r32/eax -19277 89/<- *esi 0/r32/eax -19278 8b/-> *(ebx+4) 0/r32/eax -19279 89/<- *(esi+4) 0/r32/eax -19280 # return -19281 eb/jump $lookup-var-helper:end/disp8 -19282 } -19283 # 'name' not yet found; update var-in-reg if v in register -19284 # . var vr/eax: (addr array byte) = lookup(v->register) -19285 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -19286 # . if (vr == 0) continue -19287 3d/compare-eax-and 0/imm32 -19288 74/jump-if-= $lookup-var-helper:continue/disp8 -19289 # . var reg/eax: int = get(Registers, vr) -19290 (get Mu-registers-unique %eax 0xc "Mu-registers-unique") # => eax -19291 8b/-> *eax 0/r32/eax -19292 # . var-in-reg[reg] = v -19293 89/<- *(edi+eax<<2) 1/r32/ecx -19294 $lookup-var-helper:continue: -19295 # curr -= 12 -19296 81 5/subop/subtract %ebx 0xc/imm32 -19297 e9/jump loop/disp32 -19298 } -19299 $lookup-var-helper:end: -19300 # . reclaim locals -19301 81 0/subop/add %esp 0x40/imm32 -19302 # . restore registers -19303 5f/pop-to-edi -19304 5e/pop-to-esi -19305 5b/pop-to-ebx -19306 5a/pop-to-edx -19307 59/pop-to-ecx -19308 58/pop-to-eax -19309 # . epilogue -19310 89/<- %esp 5/r32/ebp -19311 5d/pop-to-ebp -19312 c3/return -19313 -19314 $lookup-var-helper:error1: -19315 (write-buffered *(ebp+0x18) "fn ") -19316 8b/-> *(ebp+0x14) 0/r32/eax -19317 (lookup *eax *(eax+4)) # Function-name Function-name => eax -19318 (write-buffered *(ebp+0x18) %eax) -19319 (write-buffered *(ebp+0x18) ": malformed stack when looking up '") -19320 (write-slice-buffered *(ebp+0x18) *(ebp+8)) -19321 (write-buffered *(ebp+0x18) "'\n") -19322 (flush *(ebp+0x18)) -19323 (stop *(ebp+0x1c) 1) -19324 # never gets here -19325 -19326 $lookup-var-helper:error2: -19327 # eax contains the conflicting var at this point -19328 (write-buffered *(ebp+0x18) "fn ") -19329 50/push-eax -19330 8b/-> *(ebp+0x14) 0/r32/eax -19331 (lookup *eax *(eax+4)) # Function-name Function-name => eax -19332 (write-buffered *(ebp+0x18) %eax) -19333 58/pop-eax -19334 (write-buffered *(ebp+0x18) ": register ") -19335 50/push-eax -19336 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -19337 (write-buffered *(ebp+0x18) %eax) -19338 58/pop-to-eax -19339 (write-buffered *(ebp+0x18) " reads var '") -19340 (write-slice-buffered *(ebp+0x18) *(ebp+8)) -19341 (write-buffered *(ebp+0x18) "' after writing var '") -19342 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19343 (write-buffered *(ebp+0x18) %eax) +18288 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) +18289 (append-to-block Heap %edi *eax *(eax+4)) +18290 # reclaim tmp +18291 81 0/subop/add %esp 8/imm32 +18292 # +18293 e9/jump $parse-mu-block:line-loop/disp32 +18294 } +18295 # if slice-equal?(word-slice, "var") +18296 { +18297 $parse-mu-block:check-for-var: +18298 (slice-equal? %edx "var") +18299 3d/compare-eax-and 0/imm32/false +18300 74/jump-if-= break/disp8 +18301 # var tmp/eax: (handle block) +18302 68/push 0/imm32 +18303 68/push 0/imm32 +18304 89/<- %eax 4/r32/esp +18305 # +18306 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) +18307 (append-to-block Heap %edi *eax *(eax+4)) +18308 # reclaim tmp +18309 81 0/subop/add %esp 8/imm32 +18310 # +18311 e9/jump $parse-mu-block:line-loop/disp32 +18312 } +18313 $parse-mu-block:regular-stmt: +18314 # otherwise +18315 # var tmp/eax: (handle block) +18316 68/push 0/imm32 +18317 68/push 0/imm32 +18318 89/<- %eax 4/r32/esp +18319 # +18320 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) +18321 (append-to-block Heap %edi *eax *(eax+4)) +18322 # reclaim tmp +18323 81 0/subop/add %esp 8/imm32 +18324 # +18325 e9/jump loop/disp32 +18326 } # end line loop +18327 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10)) +18328 # decrement *Curr-block-depth +18329 ff 1/subop/decrement *Curr-block-depth +18330 # pop(vars) +18331 (pop *(ebp+0xc)) # => eax +18332 (pop *(ebp+0xc)) # => eax +18333 (pop *(ebp+0xc)) # => eax +18334 $parse-mu-block:end: +18335 # . reclaim locals +18336 81 0/subop/add %esp 0x214/imm32 +18337 # . restore registers +18338 5f/pop-to-edi +18339 5b/pop-to-ebx +18340 5a/pop-to-edx +18341 59/pop-to-ecx +18342 58/pop-to-eax +18343 # . epilogue +18344 89/<- %esp 5/r32/ebp +18345 5d/pop-to-ebp +18346 c3/return +18347 +18348 $parse-mu-block:abort: +18349 # error("'{' or '}' should be on its own line, but got '") +18350 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '") +18351 (rewind-stream %ecx) +18352 (write-stream-data *(ebp+0x18) %ecx) +18353 (write-buffered *(ebp+0x18) "'\n") +18354 (flush *(ebp+0x18)) +18355 (stop *(ebp+0x1c) 1) +18356 # never gets here +18357 +18358 new-block-name: # fn: (addr function), out: (addr handle var) +18359 # . prologue +18360 55/push-ebp +18361 89/<- %ebp 4/r32/esp +18362 # . save registers +18363 50/push-eax +18364 51/push-ecx +18365 52/push-edx +18366 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' +18367 8b/-> *(ebp+8) 0/r32/eax +18368 (lookup *eax *(eax+4)) # Function-name Function-name => eax +18369 8b/-> *eax 0/r32/eax # String-size +18370 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' +18371 89/<- %ecx 0/r32/eax +18372 # var name/edx: (stream byte n) +18373 29/subtract-from %esp 1/r32/ecx +18374 ff 6/subop/push %ecx +18375 68/push 0/imm32/read +18376 68/push 0/imm32/write +18377 89/<- %edx 4/r32/esp +18378 (clear-stream %edx) +18379 # eax = fn->name +18380 8b/-> *(ebp+8) 0/r32/eax +18381 (lookup *eax *(eax+4)) # Function-name Function-name => eax +18382 # construct result using Next-block-index (and increment it) +18383 (write %edx "$") +18384 (write %edx %eax) +18385 (write %edx ":") +18386 (write-int32-hex %edx *Next-block-index) +18387 ff 0/subop/increment *Next-block-index +18388 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) +18389 # . eax = name->write +18390 8b/-> *edx 0/r32/eax +18391 # . edx = name->data +18392 8d/copy-address *(edx+0xc) 2/r32/edx +18393 # . eax = name->write + name->data +18394 01/add-to %eax 2/r32/edx +18395 # . push {edx, eax} +18396 ff 6/subop/push %eax +18397 ff 6/subop/push %edx +18398 89/<- %eax 4/r32/esp +18399 # out = new literal(s) +18400 (new-literal Heap %eax *(ebp+0xc)) +18401 #? 8b/-> *(ebp+0xc) 0/r32/eax +18402 #? (write-buffered Stderr "type allocid in caller after new-literal: ") +18403 #? (write-int32-hex-buffered Stderr *(eax+8)) +18404 #? (write-buffered Stderr " for var ") +18405 #? (write-int32-hex-buffered Stderr %eax) +18406 #? (write-buffered Stderr Newline) +18407 #? (flush Stderr) +18408 $new-block-name:end: +18409 # . reclaim locals +18410 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} +18411 81 0/subop/add %ecx 8/imm32 # slice +18412 01/add-to %esp 1/r32/ecx +18413 # . restore registers +18414 5a/pop-to-edx +18415 59/pop-to-ecx +18416 58/pop-to-eax +18417 # . epilogue +18418 89/<- %esp 5/r32/ebp +18419 5d/pop-to-ebp +18420 c3/return +18421 +18422 check-no-tokens-left: # line: (addr stream byte) +18423 # . prologue +18424 55/push-ebp +18425 89/<- %ebp 4/r32/esp +18426 # . save registers +18427 50/push-eax +18428 51/push-ecx +18429 # var s/ecx: slice +18430 68/push 0/imm32/end +18431 68/push 0/imm32/start +18432 89/<- %ecx 4/r32/esp +18433 # +18434 (next-mu-token *(ebp+8) %ecx) +18435 # if slice-empty?(s) return +18436 (slice-empty? %ecx) +18437 3d/compare-eax-and 0/imm32/false +18438 75/jump-if-!= $check-no-tokens-left:end/disp8 +18439 # if (slice-starts-with?(s, '#') return +18440 # . eax = *s->start +18441 8b/-> *edx 0/r32/eax +18442 8a/copy-byte *eax 0/r32/AL +18443 25/and-eax-with 0xff/imm32 +18444 # . if (eax == '#') continue +18445 3d/compare-eax-and 0x23/imm32/hash +18446 74/jump-if-= $check-no-tokens-left:end/disp8 +18447 # abort +18448 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") +18449 (rewind-stream %ecx) +18450 (write-stream 2 %ecx) +18451 (write-buffered Stderr "'\n") +18452 (flush Stderr) +18453 # . syscall(exit, 1) +18454 bb/copy-to-ebx 1/imm32 +18455 e8/call syscall_exit/disp32 +18456 # never gets here +18457 $check-no-tokens-left:end: +18458 # . reclaim locals +18459 81 0/subop/add %esp 8/imm32 +18460 # . restore registers +18461 59/pop-to-ecx +18462 58/pop-to-eax +18463 # . epilogue +18464 89/<- %esp 5/r32/ebp +18465 5d/pop-to-ebp +18466 c3/return +18467 +18468 parse-mu-named-block: # name: (addr slice), in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +18469 # pseudocode: +18470 # var v: (handle var) +18471 # new-literal(name, v) +18472 # push(vars, {v, false}) +18473 # parse-mu-block(in, vars, fn, out) +18474 # pop(vars) +18475 # out->tag = block +18476 # out->var = v +18477 # +18478 # . prologue +18479 55/push-ebp +18480 89/<- %ebp 4/r32/esp +18481 # . save registers +18482 50/push-eax +18483 51/push-ecx +18484 57/push-edi +18485 # var v/ecx: (handle var) +18486 68/push 0/imm32 +18487 68/push 0/imm32 +18488 89/<- %ecx 4/r32/esp +18489 # +18490 (new-literal Heap *(ebp+8) %ecx) +18491 # push(vars, v) +18492 (push *(ebp+0x10) *ecx) +18493 (push *(ebp+0x10) *(ecx+4)) +18494 (push *(ebp+0x10) 0) # false +18495 # +18496 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20)) +18497 # pop v off vars +18498 (pop *(ebp+0x10)) # => eax +18499 (pop *(ebp+0x10)) # => eax +18500 (pop *(ebp+0x10)) # => eax +18501 # var out-addr/edi: (addr stmt) = lookup(*out) +18502 8b/-> *(ebp+0x18) 7/r32/edi +18503 (lookup *edi *(edi+4)) # => eax +18504 89/<- %edi 0/r32/eax +18505 # out-addr->tag = named-block +18506 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag +18507 # out-addr->var = v +18508 8b/-> *ecx 0/r32/eax +18509 89/<- *(edi+0xc) 0/r32/eax # Block-var +18510 8b/-> *(ecx+4) 0/r32/eax +18511 89/<- *(edi+0x10) 0/r32/eax # Block-var +18512 $parse-mu-named-block:end: +18513 # . reclaim locals +18514 81 0/subop/add %esp 8/imm32 +18515 # . restore registers +18516 5f/pop-to-edi +18517 59/pop-to-ecx +18518 58/pop-to-eax +18519 # . epilogue +18520 89/<- %esp 5/r32/ebp +18521 5d/pop-to-ebp +18522 c3/return +18523 +18524 parse-mu-var-def: # line: (addr stream byte), vars: (addr stack live-var), out: (addr handle stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +18525 # . prologue +18526 55/push-ebp +18527 89/<- %ebp 4/r32/esp +18528 # . save registers +18529 50/push-eax +18530 51/push-ecx +18531 52/push-edx +18532 56/push-esi +18533 57/push-edi +18534 # edi = out +18535 8b/-> *(ebp+0x10) 7/r32/edi +18536 # var word-slice/ecx: slice +18537 68/push 0/imm32/end +18538 68/push 0/imm32/start +18539 89/<- %ecx 4/r32/esp +18540 # var v/edx: (handle var) +18541 68/push 0/imm32 +18542 68/push 0/imm32 +18543 89/<- %edx 4/r32/esp +18544 # v = parse-var-with-type(next-mu-token(line)) +18545 (next-mu-token *(ebp+8) %ecx) +18546 { +18547 # just for tests, support null fn +18548 8b/-> *(ebp+0x14) 0/r32/eax +18549 3d/compare-eax-and 0/imm32 +18550 74/jump-if-= break/disp8 +18551 (lookup *eax *(eax+4)) # Var-name Var-name => eax +18552 } +18553 (parse-var-with-type %ecx *(ebp+8) %edx %eax *(ebp+0x18) *(ebp+0x1c)) +18554 # var v-addr/esi: (addr var) +18555 (lookup *edx *(edx+4)) # => eax +18556 89/<- %esi 0/r32/eax +18557 # v->block-depth = *Curr-block-depth +18558 8b/-> *Curr-block-depth 0/r32/eax +18559 89/<- *(esi+0x10) 0/r32/eax # Var-block-depth +18560 # either v has no register and there's no more to this line +18561 81 7/subop/compare *(esi+0x18) 0/imm32 +18562 { +18563 75/jump-if-!= break/disp8 +18564 # if v-addr->type == byte, abort +18565 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +18566 (simple-mu-type? %eax 8) # byte => eax +18567 3d/compare-eax-and 0/imm32/false +18568 0f 85/jump-if-!= $parse-mu-var-def:error-byte-on-stack/disp32 +18569 # ensure that there's nothing else on this line +18570 (next-mu-token *(ebp+8) %ecx) +18571 (slice-empty? %ecx) # => eax +18572 3d/compare-eax-and 0/imm32/false +18573 0f 84/jump-if-= $parse-mu-var-def:error2/disp32 +18574 # +18575 (new-var-def Heap *edx *(edx+4) %edi) +18576 e9/jump $parse-mu-var-def:update-vars/disp32 +18577 } +18578 # or v has a register and there's more to this line +18579 { +18580 0f 84/jump-if-= break/disp32 +18581 # if v-addr->type == byte, check for unsupported registers +18582 { +18583 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +18584 (simple-mu-type? %eax 8) # byte => eax +18585 3d/compare-eax-and 0/imm32/false +18586 74/jump-if-= break/disp8 +18587 (lookup *(esi+0x18) *(esi+0x1c)) # => eax +18588 (string-equal? %eax "esi") # => eax +18589 3d/compare-eax-and 0/imm32/false +18590 0f 85/jump-if-!= $parse-mu-var-def:error-byte-registers/disp32 +18591 (lookup *(esi+0x18) *(esi+0x1c)) # => eax +18592 (string-equal? %eax "edi") # => eax +18593 3d/compare-eax-and 0/imm32/false +18594 0f 85/jump-if-!= $parse-mu-var-def:error-byte-registers/disp32 +18595 } +18596 # TODO: vars of type 'byte' should only be initialized by clearing to 0 +18597 # ensure that the next word is '<-' +18598 (next-mu-token *(ebp+8) %ecx) +18599 (slice-equal? %ecx "<-") # => eax +18600 3d/compare-eax-and 0/imm32/false +18601 0f 84/jump-if-= $parse-mu-var-def:error1/disp32 +18602 # +18603 (new-reg-var-def Heap *edx *(edx+4) %edi) +18604 (lookup *edi *(edi+4)) # => eax +18605 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +18606 } +18607 $parse-mu-var-def:update-vars: +18608 # push 'v' at end of function +18609 (push *(ebp+0xc) *edx) +18610 (push *(ebp+0xc) *(edx+4)) +18611 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing +18612 $parse-mu-var-def:end: +18613 # . reclaim locals +18614 81 0/subop/add %esp 0x10/imm32 +18615 # . restore registers +18616 5f/pop-to-edi +18617 5e/pop-to-esi +18618 5a/pop-to-edx +18619 59/pop-to-ecx +18620 58/pop-to-eax +18621 # . epilogue +18622 89/<- %esp 5/r32/ebp +18623 5d/pop-to-ebp +18624 c3/return +18625 +18626 $parse-mu-var-def:error1: +18627 (rewind-stream *(ebp+8)) +18628 # error("register variable requires a valid instruction to initialize but got '" line "'\n") +18629 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '") +18630 (flush *(ebp+0x18)) +18631 (write-stream-data *(ebp+0x18) *(ebp+8)) +18632 (write-buffered *(ebp+0x18) "'\n") +18633 (flush *(ebp+0x18)) +18634 (stop *(ebp+0x1c) 1) +18635 # never gets here +18636 +18637 $parse-mu-var-def:error2: +18638 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n") +18639 (write-buffered *(ebp+0x18) "fn ") +18640 8b/-> *(ebp+0x14) 0/r32/eax +18641 (lookup *eax *(eax+4)) # Function-name Function-name => eax +18642 (write-buffered *(ebp+0x18) %eax) +18643 (write-buffered *(ebp+0x18) ": var ") +18644 # var v-addr/eax: (addr var) = lookup(v) +18645 (lookup *edx *(edx+4)) # => eax +18646 (lookup *eax *(eax+4)) # Var-name Var-name => eax +18647 (write-buffered *(ebp+0x18) %eax) +18648 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n") +18649 (flush *(ebp+0x18)) +18650 (stop *(ebp+0x1c) 1) +18651 # never gets here +18652 +18653 $parse-mu-var-def:error-byte-on-stack: +18654 # error("fn " fn ": var '" var "' of type 'byte' cannot be on the stack\n") +18655 (write-buffered *(ebp+0x18) "fn ") +18656 8b/-> *(ebp+0x14) 0/r32/eax +18657 (lookup *eax *(eax+4)) # Function-name Function-name => eax +18658 (write-buffered *(ebp+0x18) %eax) +18659 (write-buffered *(ebp+0x18) ": var '") +18660 # var v-addr/eax: (addr var) = lookup(v) +18661 (lookup *edx *(edx+4)) # => eax +18662 (lookup *eax *(eax+4)) # Var-name Var-name => eax +18663 (write-buffered *(ebp+0x18) %eax) +18664 (write-buffered *(ebp+0x18) "' of type 'byte' cannot be on the stack\n") +18665 (flush *(ebp+0x18)) +18666 (stop *(ebp+0x1c) 1) +18667 # never gets here +18668 +18669 $parse-mu-var-def:error-byte-registers: +18670 # error("fn " fn ": var '" var "' of type 'byte' cannot be in esi or edi\n") +18671 (write-buffered *(ebp+0x18) "fn ") +18672 8b/-> *(ebp+0x14) 0/r32/eax +18673 (lookup *eax *(eax+4)) # Function-name Function-name => eax +18674 (write-buffered *(ebp+0x18) %eax) +18675 (write-buffered *(ebp+0x18) ": var '") +18676 # var v-addr/eax: (addr var) = lookup(v) +18677 (lookup *edx *(edx+4)) # => eax +18678 (lookup *eax *(eax+4)) # Var-name Var-name => eax +18679 (write-buffered *(ebp+0x18) %eax) +18680 (write-buffered *(ebp+0x18) "' of type 'byte' cannot be in esi or edi\n") +18681 (flush *(ebp+0x18)) +18682 (stop *(ebp+0x1c) 1) +18683 # never gets here +18684 +18685 test-parse-mu-var-def: +18686 # 'var n: int' +18687 # . prologue +18688 55/push-ebp +18689 89/<- %ebp 4/r32/esp +18690 # setup +18691 8b/-> *Primitive-type-ids 0/r32/eax +18692 89/<- *Type-id 0/r32/eax # stream-write +18693 (clear-stream _test-input-stream) +18694 (write _test-input-stream "n: int\n") # caller has consumed the 'var' +18695 c7 0/subop/copy *Curr-block-depth 1/imm32 +18696 # var out/esi: (handle stmt) +18697 68/push 0/imm32 +18698 68/push 0/imm32 +18699 89/<- %esi 4/r32/esp +18700 # var vars/ecx: (stack (addr var) 16) +18701 81 5/subop/subtract %esp 0xc0/imm32 +18702 68/push 0xc0/imm32/size +18703 68/push 0/imm32/top +18704 89/<- %ecx 4/r32/esp +18705 (clear-stack %ecx) +18706 # convert +18707 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) +18708 # var out-addr/esi: (addr stmt) +18709 (lookup *esi *(esi+4)) # => eax +18710 89/<- %esi 0/r32/eax +18711 # +18712 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def +18713 # var v/ecx: (addr var) = lookup(out->var) +18714 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax +18715 89/<- %ecx 0/r32/eax +18716 # v->name +18717 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +18718 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") +18719 # v->register +18720 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register +18721 # v->block-depth +18722 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth +18723 # v->type == int +18724 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +18725 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Type-tree-is-atom +18726 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Type-tree-value +18727 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Type-tree-right +18728 # . epilogue +18729 89/<- %esp 5/r32/ebp +18730 5d/pop-to-ebp +18731 c3/return +18732 +18733 test-parse-mu-reg-var-def: +18734 # 'var n/eax: int <- copy 0' +18735 # . prologue +18736 55/push-ebp +18737 89/<- %ebp 4/r32/esp +18738 # setup +18739 8b/-> *Primitive-type-ids 0/r32/eax +18740 89/<- *Type-id 0/r32/eax # stream-write +18741 (clear-stream _test-input-stream) +18742 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' +18743 c7 0/subop/copy *Curr-block-depth 1/imm32 +18744 # var out/esi: (handle stmt) +18745 68/push 0/imm32 +18746 68/push 0/imm32 +18747 89/<- %esi 4/r32/esp +18748 # var vars/ecx: (stack (addr var) 16) +18749 81 5/subop/subtract %esp 0xc0/imm32 +18750 68/push 0xc0/imm32/size +18751 68/push 0/imm32/top +18752 89/<- %ecx 4/r32/esp +18753 (clear-stack %ecx) +18754 # convert +18755 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) +18756 # var out-addr/esi: (addr stmt) +18757 (lookup *esi *(esi+4)) # => eax +18758 89/<- %esi 0/r32/eax +18759 # +18760 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def +18761 # var v/ecx: (addr var) = lookup(out->outputs->value) +18762 # . eax: (addr stmt-var) = lookup(out->outputs) +18763 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax +18764 # . +18765 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next +18766 # . eax: (addr var) = lookup(eax->value) +18767 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +18768 # . ecx = eax +18769 89/<- %ecx 0/r32/eax +18770 # v->name +18771 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +18772 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name +18773 # v->register +18774 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +18775 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") +18776 # v->block-depth +18777 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth +18778 # v->type == int +18779 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +18780 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Type-tree-is-atom +18781 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Type-tree-value +18782 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Type-tree-right +18783 # . epilogue +18784 89/<- %esp 5/r32/ebp +18785 5d/pop-to-ebp +18786 c3/return +18787 +18788 parse-mu-stmt: # line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +18789 # pseudocode: +18790 # var name: slice +18791 # allocate(Heap, Stmt-size, out) +18792 # var out-addr: (addr stmt) = lookup(*out) +18793 # out-addr->tag = stmt +18794 # if stmt-has-outputs?(line) +18795 # while true +18796 # name = next-mu-token(line) +18797 # if (name == '<-') break +18798 # assert(identifier?(name)) +18799 # var v: (handle var) = lookup-var(name, vars) +18800 # out-addr->outputs = append(v, out-addr->outputs) +18801 # add-operation-and-inputs-to-stmt(out-addr, line, vars) +18802 # +18803 # . prologue +18804 55/push-ebp +18805 89/<- %ebp 4/r32/esp +18806 # . save registers +18807 50/push-eax +18808 51/push-ecx +18809 52/push-edx +18810 53/push-ebx +18811 57/push-edi +18812 # var name/ecx: slice +18813 68/push 0/imm32/end +18814 68/push 0/imm32/start +18815 89/<- %ecx 4/r32/esp +18816 # var is-deref?/edx: boolean = false +18817 ba/copy-to-edx 0/imm32/false +18818 # var v: (handle var) +18819 68/push 0/imm32 +18820 68/push 0/imm32 +18821 89/<- %ebx 4/r32/esp +18822 # +18823 (allocate Heap *Stmt-size *(ebp+0x14)) +18824 # var out-addr/edi: (addr stmt) = lookup(*out) +18825 8b/-> *(ebp+0x14) 7/r32/edi +18826 (lookup *edi *(edi+4)) # => eax +18827 89/<- %edi 0/r32/eax +18828 # out-addr->tag = 1/stmt +18829 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag +18830 { +18831 (stmt-has-outputs? *(ebp+8)) +18832 3d/compare-eax-and 0/imm32/false +18833 0f 84/jump-if-= break/disp32 +18834 { +18835 $parse-mu-stmt:read-outputs: +18836 # name = next-mu-token(line) +18837 (next-mu-token *(ebp+8) %ecx) +18838 # if slice-empty?(word-slice) break +18839 (slice-empty? %ecx) # => eax +18840 3d/compare-eax-and 0/imm32/false +18841 0f 85/jump-if-!= break/disp32 +18842 # if (name == "<-") break +18843 (slice-equal? %ecx "<-") # => eax +18844 3d/compare-eax-and 0/imm32/false +18845 0f 85/jump-if-!= break/disp32 +18846 # if slice-starts-with?(name, "*") abort +18847 8b/-> *ecx 0/r32/eax # Slice-start +18848 8a/copy-byte *eax 0/r32/AL +18849 25/and-eax-with 0xff/imm32 +18850 3d/compare-eax-and 0x2a/imm32/asterisk +18851 0f 84/jump-if-= $parse-mu-stmt:error-output-dereferenced/disp32 +18852 # assert(identifier?(name)) +18853 (identifier? %ecx) # => eax +18854 3d/compare-eax-and 0/imm32/false +18855 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 +18856 # +18857 (lookup-var %ecx *(ebp+0xc) %ebx *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) +18858 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs +18859 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) 0 %eax) # Stmt1-outputs +18860 # +18861 e9/jump loop/disp32 +18862 } +18863 } +18864 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) +18865 $parse-mu-stmt:end: +18866 # . reclaim locals +18867 81 0/subop/add %esp 0x10/imm32 +18868 # . restore registers +18869 5f/pop-to-edi +18870 5b/pop-to-ebx +18871 5a/pop-to-edx +18872 59/pop-to-ecx +18873 58/pop-to-eax +18874 # . epilogue +18875 89/<- %esp 5/r32/ebp +18876 5d/pop-to-ebp +18877 c3/return +18878 +18879 $parse-mu-stmt:abort: +18880 # error("invalid identifier '" name "'\n") +18881 (write-buffered *(ebp+0x18) "fn ") +18882 8b/-> *(ebp+0x10) 0/r32/eax +18883 (lookup *eax *(eax+4)) # Function-name Function-name => eax +18884 (write-buffered *(ebp+0x18) %eax) +18885 (write-buffered *(ebp+0x18) ": invalid identifier '") +18886 (write-slice-buffered *(ebp+0x18) %ecx) +18887 (write-buffered *(ebp+0x18) "'\n") +18888 (flush *(ebp+0x18)) +18889 (stop *(ebp+0x1c) 1) +18890 # never gets here +18891 +18892 $parse-mu-stmt:error-output-dereferenced: +18893 # error("invalid identifier '" name "'\n") +18894 (write-buffered *(ebp+0x18) "fn ") +18895 8b/-> *(ebp+0x10) 0/r32/eax +18896 (lookup *eax *(eax+4)) # Function-name Function-name => eax +18897 (write-buffered *(ebp+0x18) %eax) +18898 (write-buffered *(ebp+0x18) ": output '") +18899 (write-slice-buffered *(ebp+0x18) %ecx) +18900 (write-buffered *(ebp+0x18) "' should write to a register, and therefore cannot be dereferenced\n") +18901 (flush *(ebp+0x18)) +18902 (stop *(ebp+0x1c) 1) +18903 # never gets here +18904 +18905 add-operation-and-inputs-to-stmt: # stmt: (addr stmt), line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +18906 # pseudocode: +18907 # stmt->name = slice-to-string(next-mu-token(line)) +18908 # while true +18909 # name = next-mu-token(line) +18910 # v = lookup-var-or-literal(name) +18911 # stmt->inouts = append(v, stmt->inouts) +18912 # +18913 # . prologue +18914 55/push-ebp +18915 89/<- %ebp 4/r32/esp +18916 # . save registers +18917 50/push-eax +18918 51/push-ecx +18919 52/push-edx +18920 53/push-ebx +18921 56/push-esi +18922 57/push-edi +18923 # edi = stmt +18924 8b/-> *(ebp+8) 7/r32/edi +18925 # var name/ecx: slice +18926 68/push 0/imm32/end +18927 68/push 0/imm32/start +18928 89/<- %ecx 4/r32/esp +18929 # var is-deref?/edx: boolean = false +18930 ba/copy-to-edx 0/imm32/false +18931 # var v/esi: (handle var) +18932 68/push 0/imm32 +18933 68/push 0/imm32 +18934 89/<- %esi 4/r32/esp +18935 $add-operation-and-inputs-to-stmt:read-operation: +18936 (next-mu-token *(ebp+0xc) %ecx) +18937 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation +18938 (slice-to-string Heap %ecx %eax) +18939 # var is-get?/ebx: boolean = (name == "get") +18940 (slice-equal? %ecx "get") # => eax +18941 89/<- %ebx 0/r32/eax +18942 { +18943 $add-operation-and-inputs-to-stmt:read-inouts: +18944 # name = next-mu-token(line) +18945 (next-mu-token *(ebp+0xc) %ecx) +18946 # if slice-empty?(word-slice) break +18947 (slice-empty? %ecx) # => eax +18948 3d/compare-eax-and 0/imm32/false +18949 0f 85/jump-if-!= break/disp32 +18950 # if (name == "<-") abort +18951 (slice-equal? %ecx "<-") +18952 3d/compare-eax-and 0/imm32/false +18953 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 +18954 # if (get? && second operand) lookup or create offset +18955 { +18956 81 7/subop/compare %ebx 0/imm32/false +18957 74/jump-if-= break/disp8 +18958 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +18959 3d/compare-eax-and 0/imm32 +18960 74/jump-if-= break/disp8 +18961 (lookup-or-create-constant %eax %ecx %esi) +18962 #? (lookup *esi *(esi+4)) +18963 #? (write-buffered Stderr "creating new output var ") +18964 #? (write-int32-hex-buffered Stderr %eax) +18965 #? (write-buffered Stderr " for field called ") +18966 #? (write-slice-buffered Stderr %ecx) +18967 #? (write-buffered Stderr "; var name ") +18968 #? (lookup *eax *(eax+4)) # Var-name +18969 #? (write-buffered Stderr %eax) +18970 #? (write-buffered Stderr Newline) +18971 #? (flush Stderr) +18972 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 +18973 } +18974 # is-deref? = false +18975 ba/copy-to-edx 0/imm32/false +18976 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? +18977 8b/-> *ecx 0/r32/eax # Slice-start +18978 8a/copy-byte *eax 0/r32/AL +18979 25/and-eax-with 0xff/imm32 +18980 3d/compare-eax-and 0x2a/imm32/asterisk +18981 { +18982 75/jump-if-!= break/disp8 +18983 $add-operation-and-inputs-to-stmt:inout-is-deref: +18984 ff 0/subop/increment *ecx +18985 ba/copy-to-edx 1/imm32/true +18986 } +18987 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +18988 # if (deref?) some additional checks +18989 81 7/subop/compare %edx 0/imm32/false +18990 { +18991 74/jump-if-= break/disp8 +18992 # if var is not in register, abort +18993 (lookup *esi *(esi+4)) # => eax +18994 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +18995 0f 84/jump-if-= $add-operation-and-inputs-to-stmt:error-deref-on-stack/disp32 +18996 # if var is not an address, abort +18997 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +18998 (mu-addr-type? %eax) # => eax +18999 3d/compare-eax-and 0/imm32/false +19000 0f 84/jump-if-= $add-operation-and-inputs-to-stmt:error-deref-non-addr/disp32 +19001 } +19002 $add-operation-and-inputs-to-stmt:save-var: +19003 8d/copy-address *(edi+0xc) 0/r32/eax +19004 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts +19005 # +19006 e9/jump loop/disp32 +19007 } +19008 $add-operation-and-inputs-to-stmt:end: +19009 # . reclaim locals +19010 81 0/subop/add %esp 0x10/imm32 +19011 # . restore registers +19012 5f/pop-to-edi +19013 5e/pop-to-esi +19014 5b/pop-to-ebx +19015 5a/pop-to-edx +19016 59/pop-to-ecx +19017 58/pop-to-eax +19018 # . epilogue +19019 89/<- %esp 5/r32/ebp +19020 5d/pop-to-ebp +19021 c3/return +19022 +19023 $add-operation-and-inputs-to-stmt:abort: +19024 # error("fn ___: invalid identifier in '" line "'\n") +19025 (write-buffered *(ebp+0x18) "fn ") +19026 8b/-> *(ebp+0x14) 0/r32/eax +19027 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19028 (write-buffered *(ebp+0x18) %eax) +19029 (rewind-stream *(ebp+0xc)) +19030 (write-buffered *(ebp+0x18) ": invalid identifier in '") +19031 (write-stream-data *(ebp+0x18) *(ebp+0xc)) +19032 (write-buffered *(ebp+0x18) "'\n") +19033 (flush *(ebp+0x18)) +19034 (stop *(ebp+0x1c) 1) +19035 # never gets here +19036 +19037 $add-operation-and-inputs-to-stmt:error-deref-on-stack: +19038 # error("fn ___: cannot dereference var ___ on stack\n") +19039 (write-buffered *(ebp+0x18) "fn ") +19040 8b/-> *(ebp+0x14) 0/r32/eax +19041 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19042 (write-buffered *(ebp+0x18) %eax) +19043 (rewind-stream *(ebp+0xc)) +19044 (write-buffered *(ebp+0x18) ": cannot dereference var '") +19045 (lookup *esi *(esi+4)) # => eax +19046 (lookup *eax *(eax+4)) # Var-name Var-name => eax +19047 (write-buffered *(ebp+0x18) %eax) +19048 (write-buffered *(ebp+0x18) "' on stack\n") +19049 (flush *(ebp+0x18)) +19050 (stop *(ebp+0x1c) 1) +19051 # never gets here +19052 +19053 $add-operation-and-inputs-to-stmt:error-deref-non-addr: +19054 # error("fn ___: cannot dereference non-addr var ___\n") +19055 (write-buffered *(ebp+0x18) "fn ") +19056 8b/-> *(ebp+0x14) 0/r32/eax +19057 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19058 (write-buffered *(ebp+0x18) %eax) +19059 (rewind-stream *(ebp+0xc)) +19060 (write-buffered *(ebp+0x18) ": cannot dereference non-addr var '") +19061 (lookup *esi *(esi+4)) # => eax +19062 (lookup *eax *(eax+4)) # Var-name Var-name => eax +19063 (write-buffered *(ebp+0x18) %eax) +19064 (write-buffered *(ebp+0x18) "'\n") +19065 (flush *(ebp+0x18)) +19066 (stop *(ebp+0x1c) 1) +19067 # never gets here +19068 +19069 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean +19070 # . prologue +19071 55/push-ebp +19072 89/<- %ebp 4/r32/esp +19073 # . save registers +19074 51/push-ecx +19075 # var word-slice/ecx: slice +19076 68/push 0/imm32/end +19077 68/push 0/imm32/start +19078 89/<- %ecx 4/r32/esp +19079 # result = false +19080 b8/copy-to-eax 0/imm32/false +19081 (rewind-stream *(ebp+8)) +19082 { +19083 (next-mu-token *(ebp+8) %ecx) +19084 # if slice-empty?(word-slice) break +19085 (slice-empty? %ecx) +19086 3d/compare-eax-and 0/imm32/false +19087 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) +19088 0f 85/jump-if-!= break/disp32 +19089 # if slice-starts-with?(word-slice, '#') break +19090 # . eax = *word-slice->start +19091 8b/-> *ecx 0/r32/eax +19092 8a/copy-byte *eax 0/r32/AL +19093 25/and-eax-with 0xff/imm32 +19094 # . if (eax == '#') break +19095 3d/compare-eax-and 0x23/imm32/hash +19096 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) +19097 0f 84/jump-if-= break/disp32 +19098 # if slice-equal?(word-slice, '<-') return true +19099 (slice-equal? %ecx "<-") +19100 3d/compare-eax-and 0/imm32/false +19101 74/jump-if-= loop/disp8 +19102 b8/copy-to-eax 1/imm32/true +19103 } +19104 $stmt-has-outputs:end: +19105 (rewind-stream *(ebp+8)) +19106 # . reclaim locals +19107 81 0/subop/add %esp 8/imm32 +19108 # . restore registers +19109 59/pop-to-ecx +19110 # . epilogue +19111 89/<- %esp 5/r32/ebp +19112 5d/pop-to-ebp +19113 c3/return +19114 +19115 # if 'name' starts with a digit, create a new literal var for it +19116 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found +19117 lookup-var-or-literal: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +19118 # . prologue +19119 55/push-ebp +19120 89/<- %ebp 4/r32/esp +19121 # . save registers +19122 50/push-eax +19123 51/push-ecx +19124 56/push-esi +19125 # esi = name +19126 8b/-> *(ebp+8) 6/r32/esi +19127 # if slice-empty?(name) abort +19128 (slice-empty? %esi) # => eax +19129 3d/compare-eax-and 0/imm32/false +19130 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 +19131 # var c/ecx: byte = *name->start +19132 8b/-> *esi 1/r32/ecx +19133 8a/copy-byte *ecx 1/r32/CL +19134 81 4/subop/and %ecx 0xff/imm32 +19135 # if (decimal-digit?(c) || c == '-') return new var(name) +19136 { +19137 81 7/subop/compare %ecx 0x2d/imm32/dash +19138 74/jump-if-= $lookup-var-or-literal:literal/disp8 +19139 (decimal-digit? %ecx) # => eax +19140 3d/compare-eax-and 0/imm32/false +19141 74/jump-if-= break/disp8 +19142 $lookup-var-or-literal:literal: +19143 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +19144 eb/jump $lookup-var-or-literal:end/disp8 +19145 } +19146 # else if (c == '"') return new var(name) +19147 { +19148 81 7/subop/compare %ecx 0x22/imm32/dquote +19149 75/jump-if-!= break/disp8 +19150 $lookup-var-or-literal:literal-string: +19151 (new-literal-string Heap %esi *(ebp+0x10)) +19152 eb/jump $lookup-var-or-literal:end/disp8 +19153 } +19154 # otherwise return lookup-var(name, vars) +19155 { +19156 $lookup-var-or-literal:var: +19157 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +19158 } +19159 $lookup-var-or-literal:end: +19160 # . restore registers +19161 5e/pop-to-esi +19162 59/pop-to-ecx +19163 58/pop-to-eax +19164 # . epilogue +19165 89/<- %esp 5/r32/ebp +19166 5d/pop-to-ebp +19167 c3/return +19168 +19169 $lookup-var-or-literal:abort: +19170 (write-buffered *(ebp+0x18) "fn ") +19171 8b/-> *(ebp+0x14) 0/r32/eax +19172 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19173 (write-buffered *(ebp+0x18) %eax) +19174 (write-buffered *(ebp+0x18) ": empty variable!") +19175 (flush *(ebp+0x18)) +19176 (stop *(ebp+0x1c) 1) +19177 # never gets here +19178 +19179 # return first 'name' from the top (back) of 'vars' and abort if not found +19180 lookup-var: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +19181 # . prologue +19182 55/push-ebp +19183 89/<- %ebp 4/r32/esp +19184 # . save registers +19185 50/push-eax +19186 # +19187 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +19188 # if (*out == 0) abort +19189 8b/-> *(ebp+0x10) 0/r32/eax +19190 81 7/subop/compare *eax 0/imm32 +19191 74/jump-if-= $lookup-var:abort/disp8 +19192 $lookup-var:end: +19193 # . restore registers +19194 58/pop-to-eax +19195 # . epilogue +19196 89/<- %esp 5/r32/ebp +19197 5d/pop-to-ebp +19198 c3/return +19199 +19200 $lookup-var:abort: +19201 (write-buffered *(ebp+0x18) "fn ") +19202 8b/-> *(ebp+0x14) 0/r32/eax +19203 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19204 (write-buffered *(ebp+0x18) %eax) +19205 (write-buffered *(ebp+0x18) ": unknown variable '") +19206 (write-slice-buffered *(ebp+0x18) *(ebp+8)) +19207 (write-buffered *(ebp+0x18) "'\n") +19208 (flush *(ebp+0x18)) +19209 (stop *(ebp+0x1c) 1) +19210 # never gets here +19211 +19212 # return first 'name' from the top (back) of 'vars', and 0/null if not found +19213 # ensure that 'name' if in a register is the topmost variable in that register +19214 lookup-var-helper: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +19215 # pseudocode: +19216 # var curr: (addr handle var) = &vars->data[vars->top - 12] +19217 # var min = vars->data +19218 # while curr >= min +19219 # var v: (handle var) = *curr +19220 # if v->name == name +19221 # return +19222 # curr -= 12 +19223 # +19224 # . prologue +19225 55/push-ebp +19226 89/<- %ebp 4/r32/esp +19227 # . save registers +19228 50/push-eax +19229 51/push-ecx +19230 52/push-edx +19231 53/push-ebx +19232 56/push-esi +19233 57/push-edi +19234 # clear out +19235 (zero-out *(ebp+0x10) *Handle-size) +19236 # esi = vars +19237 8b/-> *(ebp+0xc) 6/r32/esi +19238 # ebx = vars->top +19239 8b/-> *esi 3/r32/ebx +19240 # if (vars->top > vars->size) abort +19241 3b/compare<- *(esi+4) 0/r32/eax +19242 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 +19243 # var min/edx: (addr handle var) = vars->data +19244 8d/copy-address *(esi+8) 2/r32/edx +19245 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] +19246 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 +19247 # var var-in-reg/edi: 16 addrs +19248 68/push 0/imm32 +19249 68/push 0/imm32 +19250 68/push 0/imm32 +19251 68/push 0/imm32 +19252 68/push 0/imm32 +19253 68/push 0/imm32 +19254 68/push 0/imm32 +19255 68/push 0/imm32 +19256 68/push 0/imm32 +19257 68/push 0/imm32 +19258 68/push 0/imm32 +19259 68/push 0/imm32 +19260 68/push 0/imm32 +19261 68/push 0/imm32 +19262 68/push 0/imm32 +19263 68/push 0/imm32 +19264 89/<- %edi 4/r32/esp +19265 { +19266 $lookup-var-helper:loop: +19267 # if (curr < min) return +19268 39/compare %ebx 2/r32/edx +19269 0f 82/jump-if-addr< break/disp32 +19270 # var v/ecx: (addr var) = lookup(*curr) +19271 (lookup *ebx *(ebx+4)) # => eax +19272 89/<- %ecx 0/r32/eax +19273 # var vn/eax: (addr array byte) = lookup(v->name) +19274 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +19275 # if (vn == name) return curr +19276 (slice-equal? *(ebp+8) %eax) # => eax +19277 3d/compare-eax-and 0/imm32/false +19278 { +19279 74/jump-if-= break/disp8 +19280 $lookup-var-helper:found: +19281 # var vr/eax: (addr array byte) = lookup(v->register) +19282 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +19283 3d/compare-eax-and 0/imm32 +19284 { +19285 74/jump-if-= break/disp8 +19286 $lookup-var-helper:found-register: +19287 # var reg/eax: int = get(Registers, vr) +19288 (get Mu-registers-unique %eax 0xc "Mu-registers-unique") # => eax +19289 8b/-> *eax 0/r32/eax +19290 # if (var-in-reg[reg]) error +19291 8b/-> *(edi+eax<<2) 0/r32/eax +19292 3d/compare-eax-and 0/imm32 +19293 0f 85/jump-if-!= $lookup-var-helper:error2/disp32 +19294 } +19295 $lookup-var-helper:return: +19296 # esi = out +19297 8b/-> *(ebp+0x10) 6/r32/esi +19298 # *out = *curr +19299 8b/-> *ebx 0/r32/eax +19300 89/<- *esi 0/r32/eax +19301 8b/-> *(ebx+4) 0/r32/eax +19302 89/<- *(esi+4) 0/r32/eax +19303 # return +19304 eb/jump $lookup-var-helper:end/disp8 +19305 } +19306 # 'name' not yet found; update var-in-reg if v in register +19307 # . var vr/eax: (addr array byte) = lookup(v->register) +19308 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +19309 # . if (vr == 0) continue +19310 3d/compare-eax-and 0/imm32 +19311 74/jump-if-= $lookup-var-helper:continue/disp8 +19312 # . var reg/eax: int = get(Registers, vr) +19313 (get Mu-registers-unique %eax 0xc "Mu-registers-unique") # => eax +19314 8b/-> *eax 0/r32/eax +19315 # . var-in-reg[reg] = v +19316 89/<- *(edi+eax<<2) 1/r32/ecx +19317 $lookup-var-helper:continue: +19318 # curr -= 12 +19319 81 5/subop/subtract %ebx 0xc/imm32 +19320 e9/jump loop/disp32 +19321 } +19322 $lookup-var-helper:end: +19323 # . reclaim locals +19324 81 0/subop/add %esp 0x40/imm32 +19325 # . restore registers +19326 5f/pop-to-edi +19327 5e/pop-to-esi +19328 5b/pop-to-ebx +19329 5a/pop-to-edx +19330 59/pop-to-ecx +19331 58/pop-to-eax +19332 # . epilogue +19333 89/<- %esp 5/r32/ebp +19334 5d/pop-to-ebp +19335 c3/return +19336 +19337 $lookup-var-helper:error1: +19338 (write-buffered *(ebp+0x18) "fn ") +19339 8b/-> *(ebp+0x14) 0/r32/eax +19340 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19341 (write-buffered *(ebp+0x18) %eax) +19342 (write-buffered *(ebp+0x18) ": malformed stack when looking up '") +19343 (write-slice-buffered *(ebp+0x18) *(ebp+8)) 19344 (write-buffered *(ebp+0x18) "'\n") 19345 (flush *(ebp+0x18)) 19346 (stop *(ebp+0x1c) 1) 19347 # never gets here 19348 -19349 dump-vars: # vars: (addr stack live-var) -19350 # pseudocode: -19351 # var curr: (addr handle var) = &vars->data[vars->top - 12] -19352 # var min = vars->data -19353 # while curr >= min -19354 # var v: (handle var) = *curr -19355 # print v -19356 # curr -= 12 -19357 # -19358 # . prologue -19359 55/push-ebp -19360 89/<- %ebp 4/r32/esp -19361 # . save registers -19362 52/push-edx -19363 53/push-ebx -19364 56/push-esi -19365 # esi = vars -19366 8b/-> *(ebp+8) 6/r32/esi -19367 # ebx = vars->top -19368 8b/-> *esi 3/r32/ebx -19369 # var min/edx: (addr handle var) = vars->data -19370 8d/copy-address *(esi+8) 2/r32/edx -19371 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] -19372 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 -19373 { -19374 $dump-vars:loop: -19375 # if (curr < min) return -19376 39/compare %ebx 2/r32/edx -19377 0f 82/jump-if-addr< break/disp32 -19378 # -19379 (write-buffered Stderr " var@") -19380 (dump-var 2 %ebx) -19381 # curr -= 12 -19382 81 5/subop/subtract %ebx 0xc/imm32 -19383 e9/jump loop/disp32 -19384 } -19385 $dump-vars:end: -19386 # . restore registers -19387 5e/pop-to-esi -19388 5b/pop-to-ebx -19389 5a/pop-to-edx -19390 # . epilogue -19391 89/<- %esp 5/r32/ebp -19392 5d/pop-to-ebp -19393 c3/return -19394 -19395 == data -19396 # Like Registers, but no esp or ebp -19397 Mu-registers: # (addr stream {(handle array byte), int}) -19398 # a table is a stream -19399 0xa8/imm32/write -19400 0/imm32/read -19401 0xa8/imm32/length -19402 # data -19403 # general-purpose registers -19404 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them -19405 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 -19406 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 -19407 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 -19408 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 -19409 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 -19410 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 -19411 # floating-point registers -19412 0x11/imm32/alloc-id $Mu-register-xmm0/imm32 0/imm32 -19413 0x11/imm32/alloc-id $Mu-register-xmm1/imm32 1/imm32 -19414 0x11/imm32/alloc-id $Mu-register-xmm2/imm32 2/imm32 -19415 0x11/imm32/alloc-id $Mu-register-xmm3/imm32 3/imm32 -19416 0x11/imm32/alloc-id $Mu-register-xmm4/imm32 4/imm32 -19417 0x11/imm32/alloc-id $Mu-register-xmm5/imm32 5/imm32 -19418 0x11/imm32/alloc-id $Mu-register-xmm6/imm32 6/imm32 -19419 0x11/imm32/alloc-id $Mu-register-xmm7/imm32 7/imm32 -19420 -19421 # Like Mu-registers, but with unique codes for integer and floating-point -19422 # registers. -19423 # Don't use this for code-generation, only for checking. -19424 Mu-registers-unique: # (addr stream {(handle array byte), int}) -19425 # a table is a stream -19426 0xa8/imm32/write -19427 0/imm32/read -19428 0xa8/imm32/length -19429 # data -19430 # general-purpose registers -19431 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 -19432 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 -19433 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 -19434 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 -19435 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 -19436 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 -19437 # floating-point registers -19438 0x11/imm32/alloc-id $Mu-register-xmm0/imm32 8/imm32 -19439 0x11/imm32/alloc-id $Mu-register-xmm1/imm32 9/imm32 -19440 0x11/imm32/alloc-id $Mu-register-xmm2/imm32 0xa/imm32 -19441 0x11/imm32/alloc-id $Mu-register-xmm3/imm32 0xb/imm32 -19442 0x11/imm32/alloc-id $Mu-register-xmm4/imm32 0xc/imm32 -19443 0x11/imm32/alloc-id $Mu-register-xmm5/imm32 0xd/imm32 -19444 0x11/imm32/alloc-id $Mu-register-xmm6/imm32 0xe/imm32 -19445 0x11/imm32/alloc-id $Mu-register-xmm7/imm32 0xf/imm32 -19446 -19447 $Mu-register-eax: -19448 0x11/imm32/alloc-id -19449 3/imm32/size -19450 0x65/e 0x61/a 0x78/x -19451 -19452 $Mu-register-ecx: -19453 0x11/imm32/alloc-id -19454 3/imm32/size -19455 0x65/e 0x63/c 0x78/x -19456 -19457 $Mu-register-edx: -19458 0x11/imm32/alloc-id -19459 3/imm32/size -19460 0x65/e 0x64/d 0x78/x -19461 -19462 $Mu-register-ebx: -19463 0x11/imm32/alloc-id -19464 3/imm32/size -19465 0x65/e 0x62/b 0x78/x -19466 -19467 $Mu-register-esi: -19468 0x11/imm32/alloc-id -19469 3/imm32/size -19470 0x65/e 0x73/s 0x69/i -19471 -19472 $Mu-register-edi: -19473 0x11/imm32/alloc-id -19474 3/imm32/size -19475 0x65/e 0x64/d 0x69/i -19476 -19477 $Mu-register-xmm0: -19478 0x11/imm32/alloc-id:fake:payload -19479 # "xmm0" -19480 0x4/imm32/size -19481 0x78/x 0x6d/m 0x6d/m 0x30/0 -19482 -19483 $Mu-register-xmm1: -19484 0x11/imm32/alloc-id:fake:payload -19485 # "xmm1" -19486 0x4/imm32/size -19487 0x78/x 0x6d/m 0x6d/m 0x31/1 -19488 -19489 $Mu-register-xmm2: -19490 0x11/imm32/alloc-id:fake:payload -19491 # "xmm2" -19492 0x4/imm32/size -19493 0x78/x 0x6d/m 0x6d/m 0x32/2 +19349 $lookup-var-helper:error2: +19350 # eax contains the conflicting var at this point +19351 (write-buffered *(ebp+0x18) "fn ") +19352 50/push-eax +19353 8b/-> *(ebp+0x14) 0/r32/eax +19354 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19355 (write-buffered *(ebp+0x18) %eax) +19356 58/pop-eax +19357 (write-buffered *(ebp+0x18) ": register ") +19358 50/push-eax +19359 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +19360 (write-buffered *(ebp+0x18) %eax) +19361 58/pop-to-eax +19362 (write-buffered *(ebp+0x18) " reads var '") +19363 (write-slice-buffered *(ebp+0x18) *(ebp+8)) +19364 (write-buffered *(ebp+0x18) "' after writing var '") +19365 (lookup *eax *(eax+4)) # Var-name Var-name => eax +19366 (write-buffered *(ebp+0x18) %eax) +19367 (write-buffered *(ebp+0x18) "'\n") +19368 (flush *(ebp+0x18)) +19369 (stop *(ebp+0x1c) 1) +19370 # never gets here +19371 +19372 dump-vars: # vars: (addr stack live-var) +19373 # pseudocode: +19374 # var curr: (addr handle var) = &vars->data[vars->top - 12] +19375 # var min = vars->data +19376 # while curr >= min +19377 # var v: (handle var) = *curr +19378 # print v +19379 # curr -= 12 +19380 # +19381 # . prologue +19382 55/push-ebp +19383 89/<- %ebp 4/r32/esp +19384 # . save registers +19385 52/push-edx +19386 53/push-ebx +19387 56/push-esi +19388 # esi = vars +19389 8b/-> *(ebp+8) 6/r32/esi +19390 # ebx = vars->top +19391 8b/-> *esi 3/r32/ebx +19392 # var min/edx: (addr handle var) = vars->data +19393 8d/copy-address *(esi+8) 2/r32/edx +19394 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] +19395 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 +19396 { +19397 $dump-vars:loop: +19398 # if (curr < min) return +19399 39/compare %ebx 2/r32/edx +19400 0f 82/jump-if-addr< break/disp32 +19401 # +19402 (write-buffered Stderr " var@") +19403 (dump-var 2 %ebx) +19404 # curr -= 12 +19405 81 5/subop/subtract %ebx 0xc/imm32 +19406 e9/jump loop/disp32 +19407 } +19408 $dump-vars:end: +19409 # . restore registers +19410 5e/pop-to-esi +19411 5b/pop-to-ebx +19412 5a/pop-to-edx +19413 # . epilogue +19414 89/<- %esp 5/r32/ebp +19415 5d/pop-to-ebp +19416 c3/return +19417 +19418 == data +19419 # Like Registers, but no esp or ebp +19420 Mu-registers: # (addr stream {(handle array byte), int}) +19421 # a table is a stream +19422 0xa8/imm32/write +19423 0/imm32/read +19424 0xa8/imm32/length +19425 # data +19426 # general-purpose registers +19427 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them +19428 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 +19429 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 +19430 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 +19431 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 +19432 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 +19433 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 +19434 # floating-point registers +19435 0x11/imm32/alloc-id $Mu-register-xmm0/imm32 0/imm32 +19436 0x11/imm32/alloc-id $Mu-register-xmm1/imm32 1/imm32 +19437 0x11/imm32/alloc-id $Mu-register-xmm2/imm32 2/imm32 +19438 0x11/imm32/alloc-id $Mu-register-xmm3/imm32 3/imm32 +19439 0x11/imm32/alloc-id $Mu-register-xmm4/imm32 4/imm32 +19440 0x11/imm32/alloc-id $Mu-register-xmm5/imm32 5/imm32 +19441 0x11/imm32/alloc-id $Mu-register-xmm6/imm32 6/imm32 +19442 0x11/imm32/alloc-id $Mu-register-xmm7/imm32 7/imm32 +19443 +19444 # Like Mu-registers, but with unique codes for integer and floating-point +19445 # registers. +19446 # Don't use this for code-generation, only for checking. +19447 Mu-registers-unique: # (addr stream {(handle array byte), int}) +19448 # a table is a stream +19449 0xa8/imm32/write +19450 0/imm32/read +19451 0xa8/imm32/length +19452 # data +19453 # general-purpose registers +19454 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 +19455 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 +19456 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 +19457 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 +19458 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 +19459 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 +19460 # floating-point registers +19461 0x11/imm32/alloc-id $Mu-register-xmm0/imm32 8/imm32 +19462 0x11/imm32/alloc-id $Mu-register-xmm1/imm32 9/imm32 +19463 0x11/imm32/alloc-id $Mu-register-xmm2/imm32 0xa/imm32 +19464 0x11/imm32/alloc-id $Mu-register-xmm3/imm32 0xb/imm32 +19465 0x11/imm32/alloc-id $Mu-register-xmm4/imm32 0xc/imm32 +19466 0x11/imm32/alloc-id $Mu-register-xmm5/imm32 0xd/imm32 +19467 0x11/imm32/alloc-id $Mu-register-xmm6/imm32 0xe/imm32 +19468 0x11/imm32/alloc-id $Mu-register-xmm7/imm32 0xf/imm32 +19469 +19470 $Mu-register-eax: +19471 0x11/imm32/alloc-id +19472 3/imm32/size +19473 0x65/e 0x61/a 0x78/x +19474 +19475 $Mu-register-ecx: +19476 0x11/imm32/alloc-id +19477 3/imm32/size +19478 0x65/e 0x63/c 0x78/x +19479 +19480 $Mu-register-edx: +19481 0x11/imm32/alloc-id +19482 3/imm32/size +19483 0x65/e 0x64/d 0x78/x +19484 +19485 $Mu-register-ebx: +19486 0x11/imm32/alloc-id +19487 3/imm32/size +19488 0x65/e 0x62/b 0x78/x +19489 +19490 $Mu-register-esi: +19491 0x11/imm32/alloc-id +19492 3/imm32/size +19493 0x65/e 0x73/s 0x69/i 19494 -19495 $Mu-register-xmm3: -19496 0x11/imm32/alloc-id:fake:payload -19497 # "xmm3" -19498 0x4/imm32/size -19499 0x78/x 0x6d/m 0x6d/m 0x33/3 -19500 -19501 $Mu-register-xmm4: -19502 0x11/imm32/alloc-id:fake:payload -19503 # "xmm4" -19504 0x4/imm32/size -19505 0x78/x 0x6d/m 0x6d/m 0x34/4 -19506 -19507 $Mu-register-xmm5: -19508 0x11/imm32/alloc-id:fake:payload -19509 # "xmm5" -19510 0x4/imm32/size -19511 0x78/x 0x6d/m 0x6d/m 0x35/5 -19512 -19513 $Mu-register-xmm6: -19514 0x11/imm32/alloc-id:fake:payload -19515 # "xmm6" -19516 0x4/imm32/size -19517 0x78/x 0x6d/m 0x6d/m 0x36/6 -19518 -19519 $Mu-register-xmm7: -19520 0x11/imm32/alloc-id:fake:payload -19521 # "xmm7" -19522 0x4/imm32/size -19523 0x78/x 0x6d/m 0x6d/m 0x37/7 -19524 -19525 == code -19526 -19527 # push 'out' to 'vars' if not already there; it's assumed to be a fn output -19528 maybe-define-var: # out: (handle var), vars: (addr stack live-var) -19529 # . prologue -19530 55/push-ebp -19531 89/<- %ebp 4/r32/esp -19532 # . save registers -19533 50/push-eax -19534 # var out-addr/eax: (addr var) -19535 (lookup *(ebp+8) *(ebp+0xc)) # => eax -19536 # -19537 (binding-exists? %eax *(ebp+0x10)) # => eax -19538 3d/compare-eax-and 0/imm32/false -19539 75/jump-if-!= $maybe-define-var:end/disp8 -19540 # otherwise update vars -19541 (push *(ebp+0x10) *(ebp+8)) -19542 (push *(ebp+0x10) *(ebp+0xc)) -19543 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it -19544 $maybe-define-var:end: -19545 # . restore registers -19546 58/pop-to-eax -19547 # . epilogue -19548 89/<- %esp 5/r32/ebp -19549 5d/pop-to-ebp -19550 c3/return -19551 -19552 # simpler version of lookup-var-helper -19553 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean -19554 # pseudocode: -19555 # var curr: (addr handle var) = &vars->data[vars->top - 12] -19556 # var min = vars->data -19557 # while curr >= min -19558 # var v: (handle var) = *curr -19559 # if v->name == target->name -19560 # return true -19561 # curr -= 12 -19562 # return false -19563 # -19564 # . prologue -19565 55/push-ebp -19566 89/<- %ebp 4/r32/esp -19567 # . save registers -19568 51/push-ecx -19569 52/push-edx -19570 56/push-esi -19571 # var target-name/ecx: (addr array byte) = lookup(target->name) -19572 8b/-> *(ebp+8) 0/r32/eax -19573 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19574 89/<- %ecx 0/r32/eax -19575 # esi = vars -19576 8b/-> *(ebp+0xc) 6/r32/esi -19577 # eax = vars->top -19578 8b/-> *esi 0/r32/eax -19579 # var min/edx: (addr handle var) = vars->data -19580 8d/copy-address *(esi+8) 2/r32/edx -19581 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -19582 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12 -19583 { -19584 $binding-exists?:loop: -19585 # if (curr < min) return -19586 39/compare %esi 2/r32/edx -19587 0f 82/jump-if-addr< break/disp32 -19588 # var v/eax: (addr var) = lookup(*curr) -19589 (lookup *esi *(esi+4)) # => eax -19590 # var vn/eax: (addr array byte) = lookup(v->name) -19591 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19592 # if (vn == target-name) return true -19593 (string-equal? %ecx %eax) # => eax -19594 3d/compare-eax-and 0/imm32/false -19595 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true -19596 # curr -= 12 -19597 81 5/subop/subtract %esi 0xc/imm32 -19598 e9/jump loop/disp32 -19599 } -19600 b8/copy-to-eax 0/imm32/false -19601 $binding-exists?:end: -19602 # . restore registers -19603 5e/pop-to-esi -19604 5a/pop-to-edx -19605 59/pop-to-ecx -19606 # . epilogue -19607 89/<- %esp 5/r32/ebp -19608 5d/pop-to-ebp -19609 c3/return -19610 -19611 test-parse-mu-stmt: -19612 # . prologue -19613 55/push-ebp -19614 89/<- %ebp 4/r32/esp -19615 # setup -19616 8b/-> *Primitive-type-ids 0/r32/eax -19617 89/<- *Type-id 0/r32/eax # stream-write -19618 (clear-stream _test-input-stream) -19619 (write _test-input-stream "increment n\n") -19620 # var vars/ecx: (stack (addr var) 16) -19621 81 5/subop/subtract %esp 0xc0/imm32 -19622 68/push 0xc0/imm32/size -19623 68/push 0/imm32/top -19624 89/<- %ecx 4/r32/esp -19625 (clear-stack %ecx) -19626 # var v/edx: (handle var) -19627 68/push 0/imm32 -19628 68/push 0/imm32 -19629 89/<- %edx 4/r32/esp -19630 # var s/eax: (handle array byte) -19631 68/push 0/imm32 -19632 68/push 0/imm32 -19633 89/<- %eax 4/r32/esp -19634 # v = new var("n") -19635 (copy-array Heap "n" %eax) -19636 (new-var Heap *eax *(eax+4) %edx) -19637 # -19638 (push %ecx *edx) -19639 (push %ecx *(edx+4)) -19640 (push %ecx 0) -19641 # var out/eax: (handle stmt) -19642 68/push 0/imm32 -19643 68/push 0/imm32 -19644 89/<- %eax 4/r32/esp -19645 # convert -19646 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) -19647 # var out-addr/edx: (addr stmt) = lookup(*out) -19648 (lookup *eax *(eax+4)) # => eax -19649 89/<- %edx 0/r32/eax -19650 # out->tag -19651 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 -19652 # out->operation -19653 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax -19654 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation -19655 # out->inouts->value->name -19656 # . eax = out->inouts -19657 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -19658 # . eax = out->inouts->value -19659 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -19660 # . eax = out->inouts->value->name -19661 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19662 # . -19663 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") -19664 # . epilogue -19665 89/<- %esp 5/r32/ebp -19666 5d/pop-to-ebp -19667 c3/return -19668 -19669 test-parse-mu-stmt-with-comma: -19670 # . prologue -19671 55/push-ebp -19672 89/<- %ebp 4/r32/esp -19673 # setup -19674 8b/-> *Primitive-type-ids 0/r32/eax -19675 89/<- *Type-id 0/r32/eax # stream-write -19676 (clear-stream _test-input-stream) -19677 (write _test-input-stream "copy-to n, 3\n") -19678 # var vars/ecx: (stack (addr var) 16) -19679 81 5/subop/subtract %esp 0xc0/imm32 -19680 68/push 0xc0/imm32/size -19681 68/push 0/imm32/top -19682 89/<- %ecx 4/r32/esp -19683 (clear-stack %ecx) -19684 # var v/edx: (handle var) -19685 68/push 0/imm32 -19686 68/push 0/imm32 -19687 89/<- %edx 4/r32/esp -19688 # var s/eax: (handle array byte) -19689 68/push 0/imm32 -19690 68/push 0/imm32 -19691 89/<- %eax 4/r32/esp -19692 # v = new var("n") -19693 (copy-array Heap "n" %eax) -19694 (new-var Heap *eax *(eax+4) %edx) -19695 # -19696 (push %ecx *edx) -19697 (push %ecx *(edx+4)) -19698 (push %ecx 0) -19699 # var out/eax: (handle stmt) -19700 68/push 0/imm32 -19701 68/push 0/imm32 -19702 89/<- %eax 4/r32/esp -19703 # convert -19704 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) -19705 # var out-addr/edx: (addr stmt) = lookup(*out) -19706 (lookup *eax *(eax+4)) # => eax -19707 89/<- %edx 0/r32/eax -19708 # out->tag -19709 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 -19710 # out->operation -19711 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax -19712 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation -19713 # out->inouts->value->name -19714 # . eax = out->inouts -19715 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -19716 # . eax = out->inouts->value -19717 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -19718 # . eax = out->inouts->value->name -19719 (lookup *eax *(eax+4)) # Var-name Var-name => eax -19720 # . -19721 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") -19722 # . epilogue -19723 89/<- %esp 5/r32/ebp -19724 5d/pop-to-ebp -19725 c3/return -19726 -19727 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) -19728 # . prologue -19729 55/push-ebp -19730 89/<- %ebp 4/r32/esp -19731 # . save registers -19732 50/push-eax -19733 51/push-ecx -19734 # ecx = out -19735 8b/-> *(ebp+0x14) 1/r32/ecx -19736 # -19737 (allocate *(ebp+8) *Var-size %ecx) -19738 # var out-addr/eax: (addr var) -19739 (lookup *ecx *(ecx+4)) # => eax -19740 # out-addr->name = name -19741 8b/-> *(ebp+0xc) 1/r32/ecx -19742 89/<- *eax 1/r32/ecx # Var-name -19743 8b/-> *(ebp+0x10) 1/r32/ecx -19744 89/<- *(eax+4) 1/r32/ecx # Var-name -19745 #? (write-buffered Stderr "var ") -19746 #? (lookup *(ebp+0xc) *(ebp+0x10)) -19747 #? (write-buffered Stderr %eax) -19748 #? (write-buffered Stderr " at ") -19749 #? 8b/-> *(ebp+0x14) 1/r32/ecx -19750 #? (lookup *ecx *(ecx+4)) # => eax -19751 #? (write-int32-hex-buffered Stderr %eax) -19752 #? (write-buffered Stderr Newline) -19753 #? (flush Stderr) -19754 $new-var:end: -19755 # . restore registers -19756 59/pop-to-ecx -19757 58/pop-to-eax -19758 # . epilogue -19759 89/<- %esp 5/r32/ebp -19760 5d/pop-to-ebp -19761 c3/return -19762 -19763 # WARNING: modifies name -19764 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -19765 # . prologue -19766 55/push-ebp -19767 89/<- %ebp 4/r32/esp -19768 # . save registers -19769 50/push-eax -19770 51/push-ecx -19771 # first strip out metadata -19772 8b/-> *(ebp+0xc) 1/r32/ecx -19773 (next-token-from-slice *ecx *(ecx+4) 0x2f *(ebp+0xc)) -19774 # if (!is-hex-int?(name)) abort -19775 (hex-int? *(ebp+0xc)) # => eax -19776 3d/compare-eax-and 0/imm32/false -19777 0f 84/jump-if-= $new-literal-integer:abort/disp32 -19778 # a little more error-checking -19779 (check-mu-hex-int *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -19780 # out = new var(s) -19781 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) -19782 # var out-addr/ecx: (addr var) = lookup(*out) -19783 8b/-> *(ebp+0x10) 0/r32/eax -19784 (lookup *eax *(eax+4)) # => eax -19785 89/<- %ecx 0/r32/eax -19786 # out-addr->block-depth = *Curr-block-depth -19787 8b/-> *Curr-block-depth 0/r32/eax -19788 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -19789 # out-addr->type = new tree() -19790 8d/copy-address *(ecx+8) 0/r32/eax # Var-type -19791 (allocate *(ebp+8) *Type-tree-size %eax) -19792 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -19793 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom -19794 # nothing else to do; default type is 'literal' -19795 $new-literal-integer:end: -19796 # . reclaim locals -19797 81 0/subop/add %esp 8/imm32 -19798 # . restore registers -19799 59/pop-to-ecx -19800 58/pop-to-eax -19801 # . epilogue -19802 89/<- %esp 5/r32/ebp -19803 5d/pop-to-ebp -19804 c3/return -19805 -19806 $new-literal-integer:abort: -19807 (write-buffered *(ebp+0x18) "fn ") -19808 8b/-> *(ebp+0x14) 0/r32/eax -19809 (lookup *eax *(eax+4)) # Function-name Function-name => eax -19810 (write-buffered *(ebp+0x18) %eax) -19811 (write-buffered *(ebp+0x18) ": variable '") -19812 (write-slice-buffered *(ebp+0x18) *(ebp+0xc)) -19813 (write-buffered *(ebp+0x18) "' cannot begin with a digit (or do you have a typo in a number?)\n") -19814 (flush *(ebp+0x18)) -19815 (stop *(ebp+0x1c) 1) -19816 # never gets here -19817 -19818 # precondition: name is a valid hex integer; require a '0x' prefix -19819 check-mu-hex-int: # name: (addr slice), err: (addr buffered-file), ed: (addr exit-descriptor) -19820 # . prologue -19821 55/push-ebp -19822 89/<- %ebp 4/r32/esp -19823 # . save registers -19824 50/push-eax -19825 51/push-ecx -19826 52/push-edx -19827 # ecx = name -19828 8b/-> *(ebp+8) 1/r32/ecx -19829 # var start/edx: (addr byte) = name->start -19830 8b/-> *ecx 2/r32/edx -19831 # if (*start == '-') ++start -19832 b8/copy-to-eax 0/imm32 -19833 8a/copy-byte *edx 0/r32/AL -19834 3d/compare-eax-and 0x2d/imm32/dash -19835 { -19836 75/jump-if-!= break/disp8 -19837 42/increment-edx -19838 } -19839 # var end/ecx: (addr byte) = name->end -19840 8b/-> *(ecx+4) 1/r32/ecx -19841 # var len/eax: int = name->end - name->start -19842 89/<- %eax 1/r32/ecx -19843 29/subtract-from %eax 2/r32/edx -19844 # if (len <= 1) return -19845 3d/compare-eax-with 1/imm32 -19846 0f 8e/jump-if-<= $check-mu-hex-int:end/disp32 -19847 $check-mu-hex-int:length->-1: -19848 # if slice-starts-with?({start, end}, "0x") return -19849 # . var tmp = {start, end} -19850 51/push-ecx -19851 52/push-edx -19852 89/<- %eax 4/r32/esp -19853 # . -19854 (slice-starts-with? %eax "0x") # => eax -19855 # . reclaim tmp -19856 81 0/subop/add %esp 8/imm32 -19857 # . -19858 3d/compare-eax-with 0/imm32/false -19859 75/jump-if-!= $check-mu-hex-int:end/disp8 -19860 $check-mu-hex-int:abort: -19861 # otherwise abort -19862 (write-buffered *(ebp+0xc) "literal integers are always hex in Mu; start '") -19863 (write-slice-buffered *(ebp+0xc) *(ebp+8)) -19864 (write-buffered *(ebp+0xc) "' with a '0x' to be unambiguous, converting it to hexadecimal as necessary.\n") -19865 (flush *(ebp+0xc)) -19866 (stop *(ebp+0x10) 1) -19867 $check-mu-hex-int:end: -19868 # . restore registers -19869 5a/pop-to-edx -19870 59/pop-to-ecx -19871 58/pop-to-eax -19872 # . epilogue -19873 89/<- %esp 5/r32/ebp -19874 5d/pop-to-ebp -19875 c3/return -19876 -19877 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) -19878 # . prologue -19879 55/push-ebp -19880 89/<- %ebp 4/r32/esp -19881 # . save registers -19882 50/push-eax -19883 51/push-ecx -19884 # var s/ecx: (handle array byte) -19885 68/push 0/imm32 -19886 68/push 0/imm32 -19887 89/<- %ecx 4/r32/esp -19888 # s = slice-to-string(name) -19889 (slice-to-string Heap *(ebp+0xc) %ecx) -19890 # allocate to out -19891 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) -19892 # var out-addr/ecx: (addr var) = lookup(*out) -19893 8b/-> *(ebp+0x10) 1/r32/ecx -19894 (lookup *ecx *(ecx+4)) # => eax -19895 89/<- %ecx 0/r32/eax -19896 # out-addr->block-depth = *Curr-block-depth -19897 8b/-> *Curr-block-depth 0/r32/eax -19898 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -19899 # out-addr->type/eax = new type -19900 8d/copy-address *(ecx+8) 0/r32/eax # Var-type -19901 (allocate *(ebp+8) *Type-tree-size %eax) -19902 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -19903 # nothing else to do; default type is 'literal' -19904 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom -19905 $new-literal:end: -19906 # . reclaim locals -19907 81 0/subop/add %esp 8/imm32 -19908 # . restore registers -19909 59/pop-to-ecx -19910 58/pop-to-eax -19911 # . epilogue -19912 89/<- %esp 5/r32/ebp -19913 5d/pop-to-ebp -19914 c3/return -19915 -19916 new-literal-string: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) -19917 # . prologue -19918 55/push-ebp -19919 89/<- %ebp 4/r32/esp -19920 # . save registers -19921 50/push-eax -19922 51/push-ecx -19923 # var s/ecx: (handle array byte) -19924 68/push 0/imm32 -19925 68/push 0/imm32 -19926 89/<- %ecx 4/r32/esp -19927 # s = slice-to-string(name) -19928 (slice-to-string Heap *(ebp+0xc) %ecx) -19929 # allocate to out -19930 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) -19931 # var out-addr/ecx: (addr var) = lookup(*out) -19932 8b/-> *(ebp+0x10) 1/r32/ecx -19933 (lookup *ecx *(ecx+4)) # => eax -19934 89/<- %ecx 0/r32/eax -19935 # out-addr->block-depth = *Curr-block-depth -19936 8b/-> *Curr-block-depth 0/r32/eax -19937 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -19938 # out-addr->type/eax = new type -19939 8d/copy-address *(ecx+8) 0/r32/eax # Var-type -19940 (allocate *(ebp+8) *Type-tree-size %eax) -19941 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -19942 # out-addr->type->value = literal-string -19943 c7 0/subop/copy *(eax+4) 0x10/imm32/type-id-string-literal # Type-tree-value -19944 # out-addr->type->is-atom? = true -19945 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom -19946 $new-literal-string:end: -19947 # . reclaim locals -19948 81 0/subop/add %esp 8/imm32 -19949 # . restore registers -19950 59/pop-to-ecx -19951 58/pop-to-eax -19952 # . epilogue -19953 89/<- %esp 5/r32/ebp -19954 5d/pop-to-ebp -19955 c3/return -19956 -19957 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) -19958 # . prologue -19959 55/push-ebp -19960 89/<- %ebp 4/r32/esp -19961 # . save registers -19962 51/push-ecx -19963 # var tmp/ecx: (handle array byte) -19964 68/push 0/imm32 -19965 68/push 0/imm32 -19966 89/<- %ecx 4/r32/esp -19967 # tmp = slice-to-string(name) -19968 (slice-to-string Heap *(ebp+0xc) %ecx) -19969 # out = new-var(tmp) -19970 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) -19971 $new-var-from-slice:end: -19972 # . reclaim locals -19973 81 0/subop/add %esp 8/imm32 -19974 # . restore registers -19975 59/pop-to-ecx -19976 # . epilogue -19977 89/<- %esp 5/r32/ebp -19978 5d/pop-to-ebp -19979 c3/return -19980 -19981 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) -19982 # . prologue -19983 55/push-ebp -19984 89/<- %ebp 4/r32/esp -19985 # . save registers -19986 50/push-eax -19987 51/push-ecx -19988 # -19989 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) -19990 # var out-addr/eax: (addr stmt) = lookup(*out) -19991 8b/-> *(ebp+0x14) 0/r32/eax -19992 (lookup *eax *(eax+4)) # => eax -19993 # out-addr->tag = stmt -19994 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag -19995 # result->var = var -19996 8b/-> *(ebp+0xc) 1/r32/ecx -19997 89/<- *(eax+4) 1/r32/ecx # Vardef-var -19998 8b/-> *(ebp+0x10) 1/r32/ecx -19999 89/<- *(eax+8) 1/r32/ecx # Vardef-var -20000 $new-var-def:end: -20001 # . restore registers -20002 59/pop-to-ecx -20003 58/pop-to-eax -20004 # . epilogue -20005 89/<- %esp 5/r32/ebp -20006 5d/pop-to-ebp -20007 c3/return -20008 -20009 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) -20010 # . prologue -20011 55/push-ebp -20012 89/<- %ebp 4/r32/esp -20013 # . save registers -20014 50/push-eax -20015 # eax = out -20016 8b/-> *(ebp+0x14) 0/r32/eax -20017 # -20018 (allocate *(ebp+8) *Stmt-size %eax) -20019 # var out-addr/eax: (addr stmt) = lookup(*out) -20020 (lookup *eax *(eax+4)) # => eax -20021 # set tag -20022 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag -20023 # set output -20024 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs -20025 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) -20026 $new-reg-var-def:end: -20027 # . restore registers -20028 58/pop-to-eax -20029 # . epilogue -20030 89/<- %esp 5/r32/ebp -20031 5d/pop-to-ebp -20032 c3/return -20033 -20034 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) -20035 # . prologue -20036 55/push-ebp -20037 89/<- %ebp 4/r32/esp -20038 # . save registers -20039 50/push-eax -20040 51/push-ecx -20041 57/push-edi -20042 # edi = out -20043 8b/-> *(ebp+0x1c) 7/r32/edi -20044 # *out = new list -20045 (allocate *(ebp+8) *List-size %edi) -20046 # var out-addr/edi: (addr list _type) = lookup(*out) -20047 (lookup *edi *(edi+4)) # => eax -20048 89/<- %edi 0/r32/eax -20049 # out-addr->value = value -20050 8b/-> *(ebp+0xc) 0/r32/eax -20051 89/<- *edi 0/r32/eax # List-value -20052 8b/-> *(ebp+0x10) 0/r32/eax -20053 89/<- *(edi+4) 0/r32/eax # List-value -20054 # if (list == null) return -20055 81 7/subop/compare *(ebp+0x14) 0/imm32 -20056 74/jump-if-= $append-list:end/disp8 -20057 # otherwise append -20058 $append-list:non-empty-list: -20059 # var curr/eax: (addr list _type) = lookup(list) -20060 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax -20061 # while (curr->next != null) curr = curr->next -20062 { -20063 81 7/subop/compare *(eax+8) 0/imm32 # List-next -20064 74/jump-if-= break/disp8 -20065 # curr = lookup(curr->next) -20066 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax -20067 # -20068 eb/jump loop/disp8 -20069 } -20070 # edi = out -20071 8b/-> *(ebp+0x1c) 7/r32/edi -20072 # curr->next = out -20073 8b/-> *edi 1/r32/ecx -20074 89/<- *(eax+8) 1/r32/ecx # List-next -20075 8b/-> *(edi+4) 1/r32/ecx -20076 89/<- *(eax+0xc) 1/r32/ecx # List-next -20077 # out = list -20078 8b/-> *(ebp+0x14) 1/r32/ecx -20079 89/<- *edi 1/r32/ecx -20080 8b/-> *(ebp+0x18) 1/r32/ecx -20081 89/<- *(edi+4) 1/r32/ecx -20082 $append-list:end: -20083 # . restore registers -20084 5f/pop-to-edi -20085 59/pop-to-ecx -20086 58/pop-to-eax -20087 # . epilogue -20088 89/<- %esp 5/r32/ebp -20089 5d/pop-to-ebp -20090 c3/return -20091 -20092 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) -20093 # . prologue -20094 55/push-ebp -20095 89/<- %ebp 4/r32/esp -20096 # . save registers -20097 50/push-eax -20098 51/push-ecx -20099 57/push-edi -20100 # edi = out -20101 8b/-> *(ebp+0x20) 7/r32/edi -20102 # out = new stmt-var -20103 (allocate *(ebp+8) *Stmt-var-size %edi) -20104 # var out-addr/ecx: (addr stmt-var) = lookup(*out) -20105 (lookup *edi *(edi+4)) # => eax -20106 89/<- %ecx 0/r32/eax -20107 # out-addr->value = v -20108 8b/-> *(ebp+0xc) 0/r32/eax -20109 89/<- *ecx 0/r32/eax # Stmt-var-value -20110 8b/-> *(ebp+0x10) 0/r32/eax -20111 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value -20112 # out-addr->is-deref? = is-deref? -20113 8b/-> *(ebp+0x1c) 0/r32/eax -20114 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref -20115 # if (vars == null) return result -20116 81 7/subop/compare *(ebp+0x14) 0/imm32/null -20117 74/jump-if-= $append-stmt-var:end/disp8 -20118 # otherwise append -20119 # var curr/eax: (addr stmt-var) = lookup(vars) -20120 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax -20121 # while (curr->next != null) curr = curr->next -20122 { -20123 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next -20124 74/jump-if-= break/disp8 -20125 # curr = lookup(curr->next) -20126 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax -20127 # -20128 eb/jump loop/disp8 -20129 } -20130 # curr->next = out -20131 8b/-> *edi 1/r32/ecx -20132 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next -20133 8b/-> *(edi+4) 1/r32/ecx -20134 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next -20135 # out = vars -20136 8b/-> *(ebp+0x14) 1/r32/ecx -20137 89/<- *edi 1/r32/ecx -20138 8b/-> *(ebp+0x18) 1/r32/ecx -20139 89/<- *(edi+4) 1/r32/ecx -20140 $append-stmt-var:end: -20141 # . restore registers -20142 5f/pop-to-edi -20143 59/pop-to-ecx -20144 58/pop-to-eax -20145 # . epilogue -20146 89/<- %esp 5/r32/ebp -20147 5d/pop-to-ebp -20148 c3/return -20149 -20150 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) -20151 # . prologue -20152 55/push-ebp -20153 89/<- %ebp 4/r32/esp -20154 # . save registers -20155 50/push-eax -20156 56/push-esi -20157 # esi = block -20158 8b/-> *(ebp+0xc) 6/r32/esi -20159 # block->stmts = append(x, block->stmts) -20160 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts -20161 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts -20162 $append-to-block:end: -20163 # . restore registers -20164 5e/pop-to-esi -20165 58/pop-to-eax -20166 # . epilogue -20167 89/<- %esp 5/r32/ebp -20168 5d/pop-to-ebp -20169 c3/return -20170 -20171 ## Parsing types -20172 # We need to create metadata on user-defined types, and we need to use this -20173 # metadata as we parse instructions. -20174 # However, we also want to allow types to be used before their definitions. -20175 # This means we can't ever assume any type data structures exist. -20176 -20177 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) -20178 # . prologue -20179 55/push-ebp -20180 89/<- %ebp 4/r32/esp -20181 # . save registers -20182 50/push-eax -20183 56/push-esi -20184 # var container-type/esi: type-id -20185 (container-type *(ebp+8)) # => eax -20186 89/<- %esi 0/r32/eax -20187 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) -20188 68/push 0/imm32 -20189 68/push 0/imm32 -20190 89/<- %eax 4/r32/esp -20191 (find-or-create-typeinfo %esi %eax) -20192 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) -20193 (lookup *eax *(eax+4)) # => eax -20194 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) -20195 #? (write-buffered Stderr "constant: ") -20196 #? (write-slice-buffered Stderr *(ebp+0xc)) -20197 #? (write-buffered Stderr Newline) -20198 #? (flush Stderr) -20199 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) -20200 #? 8b/-> *(ebp+0x10) 0/r32/eax -20201 #? (write-buffered Stderr "@") -20202 #? (lookup *eax *(eax+4)) -20203 #? (write-int32-hex-buffered Stderr %eax) -20204 #? (lookup *eax *(eax+4)) -20205 #? (write-buffered Stderr %eax) -20206 #? (write-buffered Stderr Newline) -20207 #? (flush Stderr) -20208 #? (write-buffered Stderr "offset: ") -20209 #? 8b/-> *(eax+0x14) 0/r32/eax -20210 #? (write-int32-hex-buffered Stderr %eax) -20211 #? (write-buffered Stderr Newline) -20212 #? (flush Stderr) -20213 $lookup-or-create-constant:end: -20214 # . reclaim locals -20215 81 0/subop/add %esp 8/imm32 -20216 # . restore registers -20217 5e/pop-to-esi -20218 58/pop-to-eax -20219 # . epilogue -20220 89/<- %esp 5/r32/ebp -20221 5d/pop-to-ebp -20222 c3/return -20223 -20224 # if addr var: -20225 # container->var->type->right->left->value -20226 # otherwise -20227 # container->var->type->value -20228 container-type: # container: (addr stmt-var) -> result/eax: type-id -20229 # . prologue -20230 55/push-ebp -20231 89/<- %ebp 4/r32/esp -20232 # -20233 8b/-> *(ebp+8) 0/r32/eax -20234 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -20235 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -20236 { -20237 81 7/subop/compare *(eax+8) 0/imm32 # Type-tree-right -20238 74/jump-if-= break/disp8 -20239 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -20240 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -20241 } -20242 8b/-> *(eax+4) 0/r32/eax # Type-tree-value -20243 $container-type:end: -20244 # . epilogue -20245 89/<- %esp 5/r32/ebp -20246 5d/pop-to-ebp -20247 c3/return -20248 -20249 container?: # t: type-id -> result/eax: boolean -20250 # . prologue -20251 55/push-ebp -20252 89/<- %ebp 4/r32/esp -20253 # -20254 8b/-> *(ebp+8) 0/r32/eax -20255 c1/shift 4/subop/left %eax 2/imm8 -20256 3b/compare 0/r32/eax *Primitive-type-ids -20257 0f 9d/set-if->= %al -20258 25/and-eax-with 0xff/imm32 -20259 $container?:end: -20260 # . epilogue -20261 89/<- %esp 5/r32/ebp -20262 5d/pop-to-ebp -20263 c3/return -20264 -20265 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) -20266 # . prologue -20267 55/push-ebp -20268 89/<- %ebp 4/r32/esp -20269 # . save registers -20270 50/push-eax -20271 51/push-ecx -20272 52/push-edx -20273 57/push-edi -20274 # edi = out -20275 8b/-> *(ebp+0xc) 7/r32/edi -20276 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) -20277 68/push 0/imm32 -20278 68/push 0/imm32 -20279 89/<- %ecx 4/r32/esp -20280 # find-typeinfo(t, out) -20281 (find-typeinfo *(ebp+8) %edi) -20282 { -20283 # if (*out != 0) break -20284 81 7/subop/compare *edi 0/imm32 -20285 0f 85/jump-if-!= break/disp32 -20286 $find-or-create-typeinfo:create: -20287 # *out = allocate -20288 (allocate Heap *Typeinfo-size %edi) -20289 # var tmp/eax: (addr typeinfo) = lookup(*out) -20290 (lookup *edi *(edi+4)) # => eax -20291 #? (write-buffered Stderr "created typeinfo at ") -20292 #? (write-int32-hex-buffered Stderr %eax) -20293 #? (write-buffered Stderr " for type-id ") -20294 #? (write-int32-hex-buffered Stderr *(ebp+8)) -20295 #? (write-buffered Stderr Newline) -20296 #? (flush Stderr) -20297 # tmp->id = t -20298 8b/-> *(ebp+8) 2/r32/edx -20299 89/<- *eax 2/r32/edx # Typeinfo-id -20300 # tmp->fields = new table -20301 # . fields = new table -20302 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) -20303 # . tmp->fields = fields -20304 8b/-> *ecx 2/r32/edx -20305 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields -20306 8b/-> *(ecx+4) 2/r32/edx -20307 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields -20308 # tmp->next = Program->types -20309 8b/-> *_Program-types 1/r32/ecx -20310 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next -20311 8b/-> *_Program-types->payload 1/r32/ecx -20312 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next -20313 # Program->types = out -20314 8b/-> *edi 1/r32/ecx -20315 89/<- *_Program-types 1/r32/ecx -20316 8b/-> *(edi+4) 1/r32/ecx -20317 89/<- *_Program-types->payload 1/r32/ecx -20318 } -20319 $find-or-create-typeinfo:end: -20320 # . reclaim locals -20321 81 0/subop/add %esp 8/imm32 -20322 # . restore registers -20323 5f/pop-to-edi -20324 5a/pop-to-edx -20325 59/pop-to-ecx -20326 58/pop-to-eax -20327 # . epilogue -20328 89/<- %esp 5/r32/ebp -20329 5d/pop-to-ebp -20330 c3/return -20331 -20332 find-typeinfo: # t: type-id, out: (addr handle typeinfo) -20333 # . prologue -20334 55/push-ebp -20335 89/<- %ebp 4/r32/esp -20336 # . save registers -20337 50/push-eax -20338 51/push-ecx -20339 52/push-edx -20340 57/push-edi -20341 # ecx = t -20342 8b/-> *(ebp+8) 1/r32/ecx -20343 # edi = out -20344 8b/-> *(ebp+0xc) 7/r32/edi -20345 # *out = Program->types -20346 8b/-> *_Program-types 0/r32/eax -20347 89/<- *edi 0/r32/eax -20348 8b/-> *_Program-types->payload 0/r32/eax -20349 89/<- *(edi+4) 0/r32/eax -20350 { -20351 $find-typeinfo:loop: -20352 # if (*out == 0) break -20353 81 7/subop/compare *edi 0/imm32 -20354 74/jump-if-= break/disp8 -20355 $find-typeinfo:check: -20356 # var tmp/eax: (addr typeinfo) = lookup(*out) -20357 (lookup *edi *(edi+4)) # => eax -20358 # if (tmp->id == t) break -20359 39/compare *eax 1/r32/ecx # Typeinfo-id -20360 74/jump-if-= break/disp8 -20361 $find-typeinfo:continue: -20362 # *out = tmp->next -20363 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next -20364 89/<- *edi 2/r32/edx -20365 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next -20366 89/<- *(edi+4) 2/r32/edx -20367 # -20368 eb/jump loop/disp8 -20369 } -20370 $find-typeinfo:end: -20371 # . restore registers -20372 5f/pop-to-edi -20373 5a/pop-to-edx -20374 59/pop-to-ecx -20375 58/pop-to-eax -20376 # . epilogue -20377 89/<- %esp 5/r32/ebp -20378 5d/pop-to-ebp -20379 c3/return -20380 -20381 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) -20382 # . prologue -20383 55/push-ebp -20384 89/<- %ebp 4/r32/esp -20385 # . save registers -20386 50/push-eax -20387 52/push-edx -20388 57/push-edi -20389 # var dest/edi: (handle typeinfo-entry) -20390 68/push 0/imm32 -20391 68/push 0/imm32 -20392 89/<- %edi 4/r32/esp -20393 # find-or-create-typeinfo-fields(T, f, dest) -20394 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) -20395 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) -20396 (lookup *edi *(edi+4)) # => eax -20397 89/<- %edi 0/r32/eax -20398 # if dest-addr->output-var doesn't exist, create it -20399 { -20400 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var -20401 0f 85/jump-if-!= break/disp32 -20402 # dest-addr->output-var = new var(dummy name, type, -1 offset) -20403 # . var name/eax: (handle array byte) = "field" -20404 68/push 0/imm32 -20405 68/push 0/imm32 -20406 89/<- %eax 4/r32/esp -20407 (slice-to-string Heap *(ebp+0xc) %eax) -20408 # . new var -20409 8d/copy-address *(edi+0xc) 2/r32/edx -20410 (new-var Heap *eax *(eax+4) %edx) -20411 # . reclaim name -20412 81 0/subop/add %esp 8/imm32 -20413 # var result/edx: (addr var) = lookup(dest-addr->output-var) -20414 (lookup *(edi+0xc) *(edi+0x10)) # => eax -20415 89/<- %edx 0/r32/eax -20416 # result->type = new constant type -20417 8d/copy-address *(edx+8) 0/r32/eax # Var-type -20418 (allocate Heap *Type-tree-size %eax) -20419 (lookup *(edx+8) *(edx+0xc)) # => eax -20420 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom -20421 c7 0/subop/copy *(eax+4) 6/imm32/constant # Type-tree-value -20422 c7 0/subop/copy *(eax+8) 0/imm32 # Type-tree-left -20423 c7 0/subop/copy *(eax+0xc) 0/imm32 # Type-tree-right -20424 c7 0/subop/copy *(eax+0x10) 0/imm32 # Type-tree-right -20425 # result->offset isn't filled out yet -20426 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset -20427 } -20428 # out = dest-addr->output-var -20429 8b/-> *(ebp+0x10) 2/r32/edx -20430 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var -20431 89/<- *edx 0/r32/eax -20432 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var -20433 89/<- *(edx+4) 0/r32/eax -20434 $find-or-create-typeinfo-output-var:end: -20435 # . reclaim locals -20436 81 0/subop/add %esp 8/imm32 -20437 # . restore registers -20438 5f/pop-to-edi -20439 5a/pop-to-edx -20440 58/pop-to-eax -20441 # . epilogue -20442 89/<- %esp 5/r32/ebp -20443 5d/pop-to-ebp -20444 c3/return -20445 -20446 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) -20447 # . prologue -20448 55/push-ebp -20449 89/<- %ebp 4/r32/esp -20450 # . save registers -20451 50/push-eax -20452 56/push-esi -20453 57/push-edi -20454 # eax = lookup(T->fields) -20455 8b/-> *(ebp+8) 0/r32/eax -20456 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax -20457 # edi = out -20458 8b/-> *(ebp+0x10) 7/r32/edi -20459 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) -20460 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax -20461 89/<- %esi 0/r32/eax -20462 # if src doesn't exist, allocate it -20463 { -20464 81 7/subop/compare *esi 0/imm32 -20465 75/jump-if-!= break/disp8 -20466 (allocate Heap *Typeinfo-entry-size %esi) -20467 #? (write-buffered Stderr "handle at ") -20468 #? (write-int32-hex-buffered Stderr %esi) -20469 #? (write-buffered Stderr ": ") -20470 #? (write-int32-hex-buffered Stderr *esi) -20471 #? (write-buffered Stderr " ") -20472 #? (write-int32-hex-buffered Stderr *(esi+4)) -20473 #? (write-buffered Stderr Newline) -20474 #? (flush Stderr) -20475 #? (lookup *esi *(esi+4)) -20476 #? (write-buffered Stderr "created typeinfo fields at ") -20477 #? (write-int32-hex-buffered Stderr %esi) -20478 #? (write-buffered Stderr " for ") -20479 #? (write-int32-hex-buffered Stderr *(ebp+8)) -20480 #? (write-buffered Stderr Newline) -20481 #? (flush Stderr) -20482 } -20483 # *out = src -20484 # . *edi = *src -20485 8b/-> *esi 0/r32/eax -20486 89/<- *edi 0/r32/eax -20487 8b/-> *(esi+4) 0/r32/eax -20488 89/<- *(edi+4) 0/r32/eax -20489 $find-or-create-typeinfo-fields:end: -20490 # . restore registers -20491 5f/pop-to-edi -20492 5e/pop-to-esi -20493 58/pop-to-eax -20494 # . epilogue -20495 89/<- %esp 5/r32/ebp -20496 5d/pop-to-ebp -20497 c3/return -20498 -20499 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -20500 # pseudocode: -20501 # var line: (stream byte 512) -20502 # curr-index = 0 -20503 # while true -20504 # clear-stream(line) -20505 # read-line-buffered(in, line) -20506 # if line->write == 0 -20507 # abort -20508 # word-slice = next-mu-token(line) -20509 # if slice-empty?(word-slice) # end of line -20510 # continue -20511 # if slice-equal?(word-slice, "}") -20512 # break -20513 # var v: (handle var) = parse-var-with-type(word-slice, line) -20514 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) -20515 # TODO: ensure that r->first is null -20516 # r->index = curr-index -20517 # curr-index++ -20518 # r->input-var = v -20519 # if r->output-var == 0 -20520 # r->output-var = new literal -20521 # TODO: ensure nothing else in line -20522 # t->total-size-in-bytes = -2 (not yet initialized) -20523 # -20524 # . prologue -20525 55/push-ebp -20526 89/<- %ebp 4/r32/esp -20527 # var curr-index: int at *(ebp-4) -20528 68/push 0/imm32 -20529 # . save registers -20530 50/push-eax -20531 51/push-ecx -20532 52/push-edx -20533 53/push-ebx -20534 56/push-esi -20535 57/push-edi -20536 # edi = t -20537 8b/-> *(ebp+0xc) 7/r32/edi -20538 # var line/ecx: (stream byte 512) -20539 81 5/subop/subtract %esp 0x200/imm32 -20540 68/push 0x200/imm32/size -20541 68/push 0/imm32/read -20542 68/push 0/imm32/write -20543 89/<- %ecx 4/r32/esp -20544 # var word-slice/edx: slice -20545 68/push 0/imm32/end -20546 68/push 0/imm32/start -20547 89/<- %edx 4/r32/esp -20548 # var v/esi: (handle var) -20549 68/push 0/imm32 -20550 68/push 0/imm32 -20551 89/<- %esi 4/r32/esp -20552 # var r/ebx: (handle typeinfo-entry) -20553 68/push 0/imm32 -20554 68/push 0/imm32 -20555 89/<- %ebx 4/r32/esp -20556 { -20557 $populate-mu-type:line-loop: -20558 (clear-stream %ecx) -20559 (read-line-buffered *(ebp+8) %ecx) -20560 # if (line->write == 0) abort -20561 81 7/subop/compare *ecx 0/imm32 -20562 0f 84/jump-if-= $populate-mu-type:error1/disp32 -20563 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ -20569 (next-mu-token %ecx %edx) -20570 # if slice-empty?(word-slice) continue -20571 (slice-empty? %edx) # => eax -20572 3d/compare-eax-and 0/imm32 -20573 0f 85/jump-if-!= loop/disp32 -20574 # if slice-equal?(word-slice, "}") break -20575 (slice-equal? %edx "}") -20576 3d/compare-eax-and 0/imm32 -20577 0f 85/jump-if-!= break/disp32 -20578 $populate-mu-type:parse-element: -20579 # v = parse-var-with-type(word-slice, first-line) -20580 # must do this first to strip the trailing ':' from word-slice before -20581 # using it in find-or-create-typeinfo-fields below -20582 # TODO: clean up that mutation in parse-var-with-type -20583 (type-name *edi) # Typeinfo-id => eax -20584 (parse-var-with-type %edx %ecx %esi %eax *(ebp+0x10) *(ebp+0x14)) -20585 # if v is an addr, abort -20586 (lookup *esi *(esi+4)) # => eax -20587 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -20588 (mu-addr-type? %eax) # => eax -20589 3d/compare-eax-and 0/imm32/false -20590 0f 85/jump-if-!= $populate-mu-type:error2/disp32 -20591 # if v is an array, abort (we could support it, but initialization gets complex) -20592 (lookup *esi *(esi+4)) # => eax -20593 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -20594 (mu-array-type? %eax) # => eax -20595 3d/compare-eax-and 0/imm32/false -20596 0f 85/jump-if-!= $populate-mu-type:error3/disp32 -20597 # if v is a byte, abort -20598 (lookup *esi *(esi+4)) # => eax -20599 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -20600 (simple-mu-type? %eax 8) # byte => eax -20601 3d/compare-eax-and 0/imm32/false -20602 0f 85/jump-if-!= $populate-mu-type:error4/disp32 -20603 # if v is a slice, abort -20604 (lookup *esi *(esi+4)) # => eax -20605 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -20606 (simple-mu-type? %eax 0xc) # slice => eax -20607 3d/compare-eax-and 0/imm32/false -20608 0f 85/jump-if-!= $populate-mu-type:error5/disp32 -20609 # if v is a stream, abort (we could support it, but initialization gets even more complex) -20610 (lookup *esi *(esi+4)) # => eax -20611 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -20612 (mu-stream-type? %eax) # => eax -20613 3d/compare-eax-and 0/imm32/false -20614 0f 85/jump-if-!= $populate-mu-type:error6/disp32 -20615 # var tmp/ecx -20616 51/push-ecx -20617 $populate-mu-type:create-typeinfo-fields: -20618 # var r/ebx: (handle typeinfo-entry) -20619 (find-or-create-typeinfo-fields %edi %edx %ebx) -20620 # r->index = curr-index -20621 (lookup *ebx *(ebx+4)) # => eax -20622 8b/-> *(ebp-4) 1/r32/ecx -20623 #? (write-buffered Stderr "saving index ") -20624 #? (write-int32-hex-buffered Stderr %ecx) -20625 #? (write-buffered Stderr " at ") -20626 #? (write-int32-hex-buffered Stderr %edi) -20627 #? (write-buffered Stderr Newline) -20628 #? (flush Stderr) -20629 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index -20630 # ++curr-index -20631 ff 0/subop/increment *(ebp-4) -20632 $populate-mu-type:set-input-type: -20633 # r->input-var = v -20634 8b/-> *esi 1/r32/ecx -20635 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var -20636 8b/-> *(esi+4) 1/r32/ecx -20637 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var -20638 # restore line -20639 59/pop-to-ecx -20640 { -20641 $populate-mu-type:create-output-type: -20642 # if (r->output-var == 0) create a new var with some placeholder data -20643 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var -20644 75/jump-if-!= break/disp8 -20645 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var -20646 (new-literal Heap %edx %eax) -20647 } -20648 e9/jump loop/disp32 -20649 } -20650 $populate-mu-type:invalidate-total-size-in-bytes: -20651 # Offsets and total size may not be accurate here since we may not yet -20652 # have encountered the element types. -20653 # We'll recompute them separately after parsing the entire program. -20654 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes -20655 $populate-mu-type:end: -20656 # . reclaim locals -20657 81 0/subop/add %esp 0x224/imm32 -20658 # . restore registers -20659 5f/pop-to-edi -20660 5e/pop-to-esi -20661 5b/pop-to-ebx -20662 5a/pop-to-edx -20663 59/pop-to-ecx -20664 58/pop-to-eax -20665 # reclaim curr-index -20666 81 0/subop/add %esp 4/imm32 -20667 # . epilogue -20668 89/<- %esp 5/r32/ebp -20669 5d/pop-to-ebp -20670 c3/return -20671 -20672 $populate-mu-type:error1: -20673 # error("incomplete type definition '" t->name "'\n") -20674 (write-buffered *(ebp+0x10) "incomplete type definition '") -20675 (type-name *edi) # Typeinfo-id => eax -20676 (write-buffered *(ebp+0x10) %eax) -20677 (write-buffered *(ebp+0x10) "\n") -20678 (flush *(ebp+0x10)) -20679 (stop *(ebp+0x14) 1) -20680 # never gets here -20681 -20682 $populate-mu-type:error2: -20683 (write-buffered *(ebp+0x10) "type ") -20684 (type-name *edi) # Typeinfo-id => eax -20685 (write-buffered *(ebp+0x10) %eax) -20686 (write-buffered *(ebp+0x10) ": 'addr' elements not allowed\n") -20687 (flush *(ebp+0x10)) -20688 (stop *(ebp+0x14) 1) -20689 # never gets here -20690 -20691 $populate-mu-type:error3: -20692 (write-buffered *(ebp+0x10) "type ") -20693 (type-name *edi) # Typeinfo-id => eax -20694 (write-buffered *(ebp+0x10) %eax) -20695 (write-buffered *(ebp+0x10) ": 'array' elements not allowed for now\n") -20696 (flush *(ebp+0x10)) -20697 (stop *(ebp+0x14) 1) -20698 # never gets here -20699 -20700 $populate-mu-type:error4: -20701 (write-buffered *(ebp+0x10) "type ") -20702 (type-name *edi) # Typeinfo-id => eax -20703 (write-buffered *(ebp+0x10) %eax) -20704 (write-buffered *(ebp+0x10) ": 'byte' elements not allowed\n") -20705 (flush *(ebp+0x10)) -20706 (stop *(ebp+0x14) 1) -20707 # never gets here -20708 -20709 $populate-mu-type:error5: -20710 (write-buffered *(ebp+0x10) "type ") -20711 (type-name *edi) # Typeinfo-id => eax -20712 (write-buffered *(ebp+0x10) %eax) -20713 (write-buffered *(ebp+0x10) ": 'slice' elements not allowed\n") -20714 (flush *(ebp+0x10)) -20715 (stop *(ebp+0x14) 1) -20716 # never gets here -20717 -20718 $populate-mu-type:error6: -20719 (write-buffered *(ebp+0x10) "type ") -20720 (type-name *edi) # Typeinfo-id => eax -20721 (write-buffered *(ebp+0x10) %eax) -20722 (write-buffered *(ebp+0x10) ": 'stream' elements not allowed for now\n") -20723 (flush *(ebp+0x10)) -20724 (stop *(ebp+0x14) 1) -20725 # never gets here -20726 -20727 type-name: # index: int -> result/eax: (addr array byte) -20728 # . prologue -20729 55/push-ebp -20730 89/<- %ebp 4/r32/esp -20731 # -20732 (index Type-id *(ebp+8)) -20733 $type-name:end: -20734 # . epilogue -20735 89/<- %esp 5/r32/ebp -20736 5d/pop-to-ebp -20737 c3/return -20738 -20739 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) -20740 # . prologue -20741 55/push-ebp -20742 89/<- %ebp 4/r32/esp -20743 # . save registers -20744 56/push-esi -20745 # TODO: bounds-check index -20746 # esi = arr -20747 8b/-> *(ebp+8) 6/r32/esi -20748 # eax = index -20749 8b/-> *(ebp+0xc) 0/r32/eax -20750 # eax = *(arr + 12 + index) -20751 8b/-> *(esi+eax<<2+0xc) 0/r32/eax -20752 $index:end: -20753 # . restore registers -20754 5e/pop-to-esi -20755 # . epilogue -20756 89/<- %esp 5/r32/ebp -20757 5d/pop-to-ebp -20758 c3/return -20759 -20760 ####################################################### -20761 # Compute type sizes -20762 ####################################################### -20763 -20764 # Compute the sizes of all user-defined types. -20765 # We'll need the sizes of their elements, which may be other user-defined -20766 # types, which we will compute as needed. -20767 -20768 # Initially, all user-defined types have their sizes set to -2 (invalid) -20769 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor) -20770 # . prologue -20771 55/push-ebp -20772 89/<- %ebp 4/r32/esp -20773 $populate-mu-type-sizes:total-sizes: -20774 # var curr/eax: (addr typeinfo) = lookup(Program->types) -20775 (lookup *_Program-types *_Program-types->payload) # => eax -20776 { -20777 # if (curr == null) break -20778 3d/compare-eax-and 0/imm32/null -20779 74/jump-if-= break/disp8 -20780 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc)) -20781 # curr = lookup(curr->next) -20782 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -20783 eb/jump loop/disp8 -20784 } -20785 $populate-mu-type-sizes:offsets: -20786 # curr = *Program->types -20787 (lookup *_Program-types *_Program-types->payload) # => eax -20788 { -20789 # if (curr == null) break -20790 3d/compare-eax-and 0/imm32/null -20791 74/jump-if-= break/disp8 -20792 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc)) -20793 # curr = curr->next -20794 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -20795 eb/jump loop/disp8 -20796 } -20797 $populate-mu-type-sizes:end: -20798 # . epilogue -20799 89/<- %esp 5/r32/ebp -20800 5d/pop-to-ebp -20801 c3/return -20802 -20803 # compute sizes of all fields, recursing as necessary -20804 # sum up all their sizes to arrive at total size -20805 # fields may be out of order, but that doesn't affect the answer -20806 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -20807 # . prologue -20808 55/push-ebp -20809 89/<- %ebp 4/r32/esp -20810 # . save registers -20811 50/push-eax -20812 51/push-ecx -20813 52/push-edx -20814 56/push-esi -20815 57/push-edi -20816 # esi = T -20817 8b/-> *(ebp+8) 6/r32/esi -20818 # if T is already computed, return -20819 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes -20820 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 -20821 # if T is being computed, abort -20822 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes -20823 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 -20824 # tag T (-2 to -1) to avoid infinite recursion -20825 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes -20826 # var total-size/edi: int = 0 -20827 bf/copy-to-edi 0/imm32 -20828 # - for every field, if it's a user-defined type, compute its size -20829 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) -20830 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax -20831 89/<- %ecx 0/r32/eax -20832 # var table-size/edx: int = table->write -20833 8b/-> *ecx 2/r32/edx # stream-write -20834 # var curr/ecx: (addr table_row) = table->data -20835 8d/copy-address *(ecx+0xc) 1/r32/ecx -20836 # var max/edx: (addr table_row) = table->data + table->write -20837 8d/copy-address *(ecx+edx) 2/r32/edx -20838 { -20839 $populate-mu-type-sizes-in-type:loop: -20840 # if (curr >= max) break -20841 39/compare %ecx 2/r32/edx -20842 73/jump-if-addr>= break/disp8 -20843 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) -20844 (lookup *(ecx+8) *(ecx+0xc)) # => eax -20845 # if (t->input-var == 0) silently ignore it; we'll emit a nice error message while type-checking -20846 81 7/subop/compare *eax 0/imm32 # Typeinfo-entry-input-var -20847 74/jump-if-= $populate-mu-type-sizes-in-type:end/disp8 -20848 # compute size of t->input-var -20849 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -20850 (compute-size-of-var %eax *(ebp+0xc) *(ebp+0x10)) # => eax -20851 # result += eax -20852 01/add-to %edi 0/r32/eax -20853 # curr += row-size -20854 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size -20855 # -20856 eb/jump loop/disp8 -20857 } -20858 # - save result -20859 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes -20860 $populate-mu-type-sizes-in-type:end: -20861 # . restore registers -20862 5f/pop-to-edi -20863 5e/pop-to-esi -20864 5a/pop-to-edx -20865 59/pop-to-ecx -20866 58/pop-to-eax -20867 # . epilogue -20868 89/<- %esp 5/r32/ebp -20869 5d/pop-to-ebp -20870 c3/return -20871 -20872 $populate-mu-type-sizes-in-type:abort: -20873 (write-buffered *(ebp+0xc) "cycle in type definitions\n") -20874 (flush *(ebp+0xc)) -20875 (stop *(ebp+0x10) 1) -20876 # never gets here -20877 -20878 # Analogous to size-of, except we need to compute what size-of can just read -20879 # off the right data structures. -20880 compute-size-of-var: # in: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -20881 # . prologue -20882 55/push-ebp -20883 89/<- %ebp 4/r32/esp -20884 # . push registers -20885 51/push-ecx -20886 # var t/ecx: (addr type-tree) = lookup(v->type) -20887 8b/-> *(ebp+8) 1/r32/ecx -20888 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -20889 89/<- %ecx 0/r32/eax -20890 # if (t->is-atom == false) t = lookup(t->left) -20891 { -20892 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -20893 75/jump-if-!= break/disp8 -20894 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -20895 89/<- %ecx 0/r32/eax -20896 } -20897 # TODO: ensure t is an atom -20898 (compute-size-of-type-id *(ecx+4) *(ebp+0xc) *(ebp+0x10)) # Type-tree-value => eax -20899 $compute-size-of-var:end: -20900 # . restore registers -20901 59/pop-to-ecx -20902 # . epilogue -20903 89/<- %esp 5/r32/ebp -20904 5d/pop-to-ebp -20905 c3/return -20906 -20907 compute-size-of-type-id: # t: type-id, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -20908 # . prologue -20909 55/push-ebp -20910 89/<- %ebp 4/r32/esp -20911 # . save registers -20912 51/push-ecx -20913 # var out/ecx: (handle typeinfo) -20914 68/push 0/imm32 -20915 68/push 0/imm32 -20916 89/<- %ecx 4/r32/esp -20917 # eax = t -20918 8b/-> *(ebp+8) 0/r32/eax -20919 # if t is a literal, return 0 -20920 3d/compare-eax-and 0/imm32/literal -20921 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int -20922 # if t is a byte, return 4 (because we don't really support non-multiples of 4) -20923 3d/compare-eax-and 8/imm32/byte -20924 { -20925 75/jump-if-!= break/disp8 -20926 b8/copy-to-eax 4/imm32 -20927 eb/jump $compute-size-of-type-id:end/disp8 -20928 } -20929 # if t is a handle, return 8 -20930 3d/compare-eax-and 4/imm32/handle -20931 { -20932 75/jump-if-!= break/disp8 -20933 b8/copy-to-eax 8/imm32 -20934 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int -20935 } -20936 # if t is a slice, return 8 -20937 3d/compare-eax-and 0xc/imm32/slice -20938 { -20939 75/jump-if-!= break/disp8 -20940 b8/copy-to-eax 8/imm32 -20941 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int -20942 } -20943 # if t is a user-defined type, compute its size -20944 # TODO: support non-atom type -20945 (find-typeinfo %eax %ecx) -20946 { -20947 81 7/subop/compare *ecx 0/imm32 -20948 74/jump-if-= break/disp8 -20949 $compute-size-of-type-id:user-defined: -20950 (lookup *ecx *(ecx+4)) # => eax -20951 (populate-mu-type-sizes-in-type %eax *(ebp+0xc) *(ebp+0x10)) -20952 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes -20953 eb/jump $compute-size-of-type-id:end/disp8 -20954 } -20955 # otherwise return the word size -20956 b8/copy-to-eax 4/imm32 -20957 $compute-size-of-type-id:end: -20958 # . reclaim locals -20959 81 0/subop/add %esp 8/imm32 -20960 # . restore registers -20961 59/pop-to-ecx -20962 # . epilogue -20963 89/<- %esp 5/r32/ebp -20964 5d/pop-to-ebp -20965 c3/return -20966 -20967 # at this point we have total sizes for all user-defined types -20968 # compute offsets for each element -20969 # complication: fields may be out of order -20970 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -20971 # . prologue -20972 55/push-ebp -20973 89/<- %ebp 4/r32/esp -20974 # . save registers -20975 50/push-eax -20976 51/push-ecx -20977 52/push-edx -20978 53/push-ebx -20979 56/push-esi -20980 57/push-edi -20981 #? (dump-typeinfos "aaa\n") -20982 # var curr-offset/edi: int = 0 -20983 bf/copy-to-edi 0/imm32 -20984 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) -20985 8b/-> *(ebp+8) 1/r32/ecx -20986 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax -20987 89/<- %ecx 0/r32/eax -20988 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size -20989 8b/-> *ecx 2/r32/edx # stream-write -20990 c1 5/subop/shift-right-logical %edx 4/imm8 -20991 # var i/ebx: int = 0 -20992 bb/copy-to-ebx 0/imm32 -20993 { -20994 $populate-mu-type-offsets:loop: -20995 39/compare %ebx 2/r32/edx -20996 0f 8d/jump-if->= break/disp32 -20997 #? (write-buffered Stderr "looking up index ") -20998 #? (write-int32-hex-buffered Stderr %ebx) -20999 #? (write-buffered Stderr " in ") -21000 #? (write-int32-hex-buffered Stderr *(ebp+8)) -21001 #? (write-buffered Stderr Newline) -21002 #? (flush Stderr) -21003 # var v/esi: (addr typeinfo-entry) -21004 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax -21005 89/<- %esi 0/r32/eax -21006 # if v is null, silently move on; we'll emit a nice error message while type-checking -21007 81 7/subop/compare %esi 0/imm32 # Typeinfo-entry-input-var -21008 74/jump-if-= $populate-mu-type-offsets:end/disp8 -21009 # if (v->input-var == 0) silently ignore v; we'll emit a nice error message while type-checking -21010 81 7/subop/compare *esi 0/imm32 # Typeinfo-entry-input-var -21011 74/jump-if-= $populate-mu-type-offsets:end/disp8 -21012 # v->output-var->offset = curr-offset -21013 # . eax: (addr var) -21014 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax -21015 89/<- *(eax+0x14) 7/r32/edi # Var-offset -21016 # curr-offset += size-of(v->input-var) -21017 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -21018 (size-of %eax) # => eax -21019 01/add-to %edi 0/r32/eax -21020 # ++i -21021 43/increment-ebx -21022 e9/jump loop/disp32 -21023 } -21024 $populate-mu-type-offsets:end: -21025 # . restore registers -21026 5f/pop-to-edi -21027 5e/pop-to-esi -21028 5b/pop-to-ebx -21029 5a/pop-to-edx -21030 59/pop-to-ecx -21031 58/pop-to-eax -21032 # . epilogue -21033 89/<- %esp 5/r32/ebp -21034 5d/pop-to-ebp -21035 c3/return -21036 -21037 locate-typeinfo-entry-with-index: # table: (addr table (handle array byte) (handle typeinfo-entry)), idx: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: (addr typeinfo-entry) -21038 # . prologue -21039 55/push-ebp -21040 89/<- %ebp 4/r32/esp -21041 # . save registers -21042 51/push-ecx -21043 52/push-edx -21044 53/push-ebx -21045 56/push-esi -21046 57/push-edi -21047 # esi = table -21048 8b/-> *(ebp+8) 6/r32/esi -21049 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data -21050 8d/copy-address *(esi+0xc) 1/r32/ecx -21051 # var max/edx: (addr byte) = &table->data[table->write] -21052 8b/-> *esi 2/r32/edx -21053 8d/copy-address *(ecx+edx) 2/r32/edx -21054 { -21055 $locate-typeinfo-entry-with-index:loop: -21056 39/compare %ecx 2/r32/edx -21057 73/jump-if-addr>= break/disp8 -21058 # var v/eax: (addr typeinfo-entry) -21059 (lookup *(ecx+8) *(ecx+0xc)) # => eax -21060 # if (v->index == idx) return v -21061 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index -21062 #? (write-buffered Stderr "comparing ") -21063 #? (write-int32-hex-buffered Stderr %ebx) -21064 #? (write-buffered Stderr " and ") -21065 #? (write-int32-hex-buffered Stderr *(ebp+0xc)) -21066 #? (write-buffered Stderr Newline) -21067 #? (flush Stderr) -21068 39/compare *(ebp+0xc) 3/r32/ebx -21069 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 -21070 # curr += Typeinfo-entry-size -21071 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size -21072 # -21073 eb/jump loop/disp8 -21074 } -21075 # return 0 -21076 b8/copy-to-eax 0/imm32 -21077 $locate-typeinfo-entry-with-index:end: -21078 #? (write-buffered Stderr "returning ") -21079 #? (write-int32-hex-buffered Stderr %eax) -21080 #? (write-buffered Stderr Newline) -21081 #? (flush Stderr) -21082 # . restore registers -21083 5f/pop-to-edi -21084 5e/pop-to-esi -21085 5b/pop-to-ebx -21086 5a/pop-to-edx -21087 59/pop-to-ecx -21088 # . epilogue -21089 89/<- %esp 5/r32/ebp -21090 5d/pop-to-ebp -21091 c3/return -21092 -21093 dump-typeinfos: # hdr: (addr array byte) -21094 # . prologue -21095 55/push-ebp -21096 89/<- %ebp 4/r32/esp -21097 # . save registers -21098 50/push-eax -21099 # -21100 (write-buffered Stderr *(ebp+8)) -21101 (flush Stderr) -21102 # var curr/eax: (addr typeinfo) = lookup(Program->types) -21103 (lookup *_Program-types *_Program-types->payload) # => eax -21104 { -21105 # if (curr == null) break -21106 3d/compare-eax-and 0/imm32 -21107 74/jump-if-= break/disp8 -21108 (write-buffered Stderr "---\n") -21109 (flush Stderr) -21110 (dump-typeinfo %eax) -21111 # curr = lookup(curr->next) -21112 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -21113 eb/jump loop/disp8 -21114 } -21115 $dump-typeinfos:end: -21116 # . restore registers -21117 58/pop-to-eax -21118 # . epilogue -21119 89/<- %esp 5/r32/ebp -21120 5d/pop-to-ebp -21121 c3/return -21122 -21123 dump-typeinfo: # in: (addr typeinfo) -21124 # . prologue -21125 55/push-ebp -21126 89/<- %ebp 4/r32/esp -21127 # . save registers -21128 50/push-eax -21129 51/push-ecx -21130 52/push-edx -21131 53/push-ebx -21132 56/push-esi -21133 57/push-edi -21134 # esi = in -21135 8b/-> *(ebp+8) 6/r32/esi -21136 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) -21137 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax -21138 89/<- %ecx 0/r32/eax -21139 (write-buffered Stderr "id:") -21140 (write-int32-hex-buffered Stderr *esi) -21141 (write-buffered Stderr "\n") -21142 (write-buffered Stderr "fields @ ") -21143 (write-int32-hex-buffered Stderr %ecx) -21144 (write-buffered Stderr Newline) -21145 (flush Stderr) -21146 (write-buffered Stderr " write: ") -21147 (write-int32-hex-buffered Stderr *ecx) -21148 (write-buffered Stderr Newline) -21149 (flush Stderr) -21150 (write-buffered Stderr " read: ") -21151 (write-int32-hex-buffered Stderr *(ecx+4)) -21152 (write-buffered Stderr Newline) -21153 (flush Stderr) -21154 (write-buffered Stderr " size: ") -21155 (write-int32-hex-buffered Stderr *(ecx+8)) -21156 (write-buffered Stderr Newline) -21157 (flush Stderr) -21158 # var table-size/edx: int = table->write -21159 8b/-> *ecx 2/r32/edx # stream-write -21160 # var curr/ecx: (addr table_row) = table->data -21161 8d/copy-address *(ecx+0xc) 1/r32/ecx -21162 # var max/edx: (addr table_row) = table->data + table->write -21163 8d/copy-address *(ecx+edx) 2/r32/edx -21164 { -21165 $dump-typeinfo:loop: -21166 # if (curr >= max) break -21167 39/compare %ecx 2/r32/edx -21168 0f 83/jump-if-addr>= break/disp32 -21169 (write-buffered Stderr " row:\n") -21170 (write-buffered Stderr " key: ") -21171 (write-int32-hex-buffered Stderr *ecx) -21172 (write-buffered Stderr ",") -21173 (write-int32-hex-buffered Stderr *(ecx+4)) -21174 (write-buffered Stderr " = '") -21175 (lookup *ecx *(ecx+4)) -21176 (write-buffered Stderr %eax) -21177 (write-buffered Stderr "' @ ") -21178 (write-int32-hex-buffered Stderr %eax) -21179 (write-buffered Stderr Newline) -21180 (flush Stderr) -21181 (write-buffered Stderr " value: ") -21182 (write-int32-hex-buffered Stderr *(ecx+8)) -21183 (write-buffered Stderr ",") -21184 (write-int32-hex-buffered Stderr *(ecx+0xc)) -21185 (write-buffered Stderr " = typeinfo-entry@") -21186 (lookup *(ecx+8) *(ecx+0xc)) -21187 (write-int32-hex-buffered Stderr %eax) -21188 (write-buffered Stderr Newline) -21189 (flush Stderr) -21190 (write-buffered Stderr " input var@") -21191 (dump-var 5 %eax) -21192 (lookup *(ecx+8) *(ecx+0xc)) -21193 (write-buffered Stderr " index: ") -21194 (write-int32-hex-buffered Stderr *(eax+8)) -21195 (write-buffered Stderr Newline) -21196 (flush Stderr) -21197 (write-buffered Stderr " output var@") -21198 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var -21199 (dump-var 5 %eax) -21200 (flush Stderr) -21201 # curr += row-size -21202 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size -21203 # -21204 e9/jump loop/disp32 -21205 } -21206 $dump-typeinfo:end: -21207 # . restore registers -21208 5f/pop-to-edi -21209 5e/pop-to-esi -21210 5b/pop-to-ebx -21211 5a/pop-to-edx -21212 59/pop-to-ecx -21213 58/pop-to-eax -21214 # . epilogue -21215 89/<- %esp 5/r32/ebp -21216 5d/pop-to-ebp -21217 c3/return -21218 -21219 dump-var: # indent: int, v: (addr handle var) -21220 # . prologue -21221 55/push-ebp -21222 89/<- %ebp 4/r32/esp -21223 # . save registers -21224 50/push-eax -21225 53/push-ebx -21226 # eax = v -21227 8b/-> *(ebp+0xc) 0/r32/eax -21228 # -21229 (write-int32-hex-buffered Stderr *eax) -21230 (write-buffered Stderr ",") -21231 (write-int32-hex-buffered Stderr *(eax+4)) -21232 (write-buffered Stderr "->") -21233 (lookup *eax *(eax+4)) -21234 (write-int32-hex-buffered Stderr %eax) -21235 (write-buffered Stderr Newline) -21236 (flush Stderr) -21237 { -21238 3d/compare-eax-and 0/imm32 -21239 0f 84/jump-if-= break/disp32 -21240 (emit-indent Stderr *(ebp+8)) -21241 (write-buffered Stderr "name: ") -21242 89/<- %ebx 0/r32/eax -21243 (write-int32-hex-buffered Stderr *ebx) # Var-name -21244 (write-buffered Stderr ",") -21245 (write-int32-hex-buffered Stderr *(ebx+4)) # Var-name -21246 (write-buffered Stderr "->") -21247 (lookup *ebx *(ebx+4)) # Var-name -21248 (write-int32-hex-buffered Stderr %eax) -21249 { -21250 3d/compare-eax-and 0/imm32 -21251 74/jump-if-= break/disp8 -21252 (write-buffered Stderr Space) -21253 (write-buffered Stderr %eax) -21254 } -21255 (write-buffered Stderr Newline) -21256 (flush Stderr) -21257 (emit-indent Stderr *(ebp+8)) -21258 (write-buffered Stderr "block depth: ") -21259 (write-int32-hex-buffered Stderr *(ebx+0x10)) # Var-block-depth -21260 (write-buffered Stderr Newline) -21261 (flush Stderr) -21262 (emit-indent Stderr *(ebp+8)) -21263 (write-buffered Stderr "stack offset: ") -21264 (write-int32-hex-buffered Stderr *(ebx+0x14)) # Var-offset -21265 (write-buffered Stderr Newline) -21266 (flush Stderr) -21267 (emit-indent Stderr *(ebp+8)) -21268 (write-buffered Stderr "reg: ") -21269 (write-int32-hex-buffered Stderr *(ebx+0x18)) # Var-register -21270 (write-buffered Stderr ",") -21271 (write-int32-hex-buffered Stderr *(ebx+0x1c)) # Var-register -21272 (write-buffered Stderr "->") -21273 (flush Stderr) -21274 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register -21275 (write-int32-hex-buffered Stderr %eax) -21276 { -21277 3d/compare-eax-and 0/imm32 -21278 74/jump-if-= break/disp8 -21279 (write-buffered Stderr Space) -21280 (write-buffered Stderr %eax) -21281 } -21282 (write-buffered Stderr Newline) -21283 (flush Stderr) -21284 } -21285 $dump-var:end: -21286 # . restore registers -21287 5b/pop-to-ebx -21288 58/pop-to-eax -21289 # . epilogue -21290 89/<- %esp 5/r32/ebp -21291 5d/pop-to-ebp -21292 c3/return -21293 -21294 ####################################################### -21295 # Type-checking -21296 ####################################################### -21297 -21298 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor) -21299 # . prologue -21300 55/push-ebp -21301 89/<- %ebp 4/r32/esp -21302 # . save registers -21303 50/push-eax -21304 # var curr/eax: (addr function) = lookup(Program->functions) -21305 (lookup *_Program-functions *_Program-functions->payload) # => eax -21306 { -21307 $check-mu-types:loop: -21308 # if (curr == null) break -21309 3d/compare-eax-and 0/imm32 -21310 0f 84/jump-if-= break/disp32 -21311 +-- 8 lines: #? # dump curr->name ------------------------------------------------------------------------------------------------------------------------------------------------ -21319 (check-mu-function %eax *(ebp+8) *(ebp+0xc)) -21320 # curr = lookup(curr->next) -21321 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax -21322 e9/jump loop/disp32 -21323 } -21324 $check-mu-types:end: -21325 # . restore registers -21326 58/pop-to-eax -21327 # . epilogue -21328 89/<- %esp 5/r32/ebp -21329 5d/pop-to-ebp -21330 c3/return -21331 -21332 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -21333 # . prologue -21334 55/push-ebp -21335 89/<- %ebp 4/r32/esp -21336 # . save registers -21337 50/push-eax -21338 56/push-esi -21339 # esi = f -21340 8b/-> *(ebp+8) 6/r32/esi -21341 # outputs -21342 (lookup *(esi+0x10) *(esi+0x14)) # Function-outputs Function-outputs => eax -21343 (check-all-unique-registers %eax %esi *(ebp+0xc) *(ebp+0x10)) -21344 # body -21345 (lookup *(esi+0x18) *(esi+0x1c)) # Function-body Function-body => eax -21346 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10)) -21347 # if function has no outputs, we're done -21348 81 7/subop/compare *(esi+0x10) 0/imm32 -21349 74/jump-if-= $check-mu-function:end/disp8 -21350 # some final checks on body -21351 (check-final-stmt-is-return %eax %esi *(ebp+0xc) *(ebp+0x10)) -21352 (check-no-breaks %eax %esi *(ebp+0xc) *(ebp+0x10)) -21353 $check-mu-function:end: -21354 # . restore registers -21355 5e/pop-to-esi -21356 58/pop-to-eax -21357 # . epilogue -21358 89/<- %esp 5/r32/ebp -21359 5d/pop-to-ebp -21360 c3/return -21361 -21362 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -21363 # . prologue -21364 55/push-ebp -21365 89/<- %ebp 4/r32/esp -21366 # . save registers -21367 50/push-eax -21368 # eax = block -21369 8b/-> *(ebp+8) 0/r32/eax -21370 # var stmts/eax: (addr list stmt) = lookup(block->statements) -21371 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax -21372 # -21373 { -21374 $check-mu-block:check-empty: -21375 3d/compare-eax-and 0/imm32 -21376 0f 84/jump-if-= break/disp32 -21377 # emit block->statements -21378 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21379 } -21380 $check-mu-block:end: -21381 # . restore registers -21382 58/pop-to-eax -21383 # . epilogue -21384 89/<- %esp 5/r32/ebp -21385 5d/pop-to-ebp -21386 c3/return -21387 -21388 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -21389 # . prologue -21390 55/push-ebp -21391 89/<- %ebp 4/r32/esp -21392 # . save registers -21393 50/push-eax -21394 56/push-esi -21395 # esi = stmts -21396 8b/-> *(ebp+8) 6/r32/esi -21397 { -21398 $check-mu-stmt-list:loop: -21399 81 7/subop/compare %esi 0/imm32 -21400 0f 84/jump-if-= break/disp32 -21401 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value) -21402 (lookup *esi *(esi+4)) # List-value List-value => eax -21403 { -21404 $check-mu-stmt-list:check-for-block: -21405 81 7/subop/compare *eax 0/imm32/block # Stmt-tag -21406 75/jump-if-!= break/disp8 -21407 $check-mu-stmt-list:block: -21408 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21409 eb/jump $check-mu-stmt-list:continue/disp8 -21410 } -21411 { -21412 $check-mu-stmt-list:check-for-stmt1: -21413 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag -21414 0f 85/jump-if-!= break/disp32 -21415 $check-mu-stmt-list:stmt1: -21416 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21417 eb/jump $check-mu-stmt-list:continue/disp8 -21418 } -21419 { -21420 $check-mu-stmt-list:check-for-reg-var-def: -21421 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag -21422 0f 85/jump-if-!= break/disp32 -21423 $check-mu-stmt-list:reg-var-def: -21424 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21425 eb/jump $check-mu-stmt-list:continue/disp8 -21426 } -21427 $check-mu-stmt-list:continue: -21428 # TODO: raise an error on unrecognized Stmt-tag -21429 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax -21430 89/<- %esi 0/r32/eax -21431 e9/jump loop/disp32 -21432 } -21433 $check-mu-stmt-list:end: -21434 # . restore registers -21435 5e/pop-to-esi -21436 58/pop-to-eax -21437 # . epilogue -21438 89/<- %esp 5/r32/ebp -21439 5d/pop-to-ebp -21440 c3/return -21441 -21442 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -21443 # . prologue -21444 55/push-ebp -21445 89/<- %ebp 4/r32/esp -21446 # . save registers -21447 50/push-eax -21448 # - if stmt's operation matches a primitive, check against it -21449 (has-primitive-name? *(ebp+8)) # => eax -21450 3d/compare-eax-and 0/imm32/false -21451 { -21452 74/jump-if-= break/disp8 -21453 (check-mu-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21454 e9/jump $check-mu-stmt:end/disp32 +19495 $Mu-register-edi: +19496 0x11/imm32/alloc-id +19497 3/imm32/size +19498 0x65/e 0x64/d 0x69/i +19499 +19500 $Mu-register-xmm0: +19501 0x11/imm32/alloc-id:fake:payload +19502 # "xmm0" +19503 0x4/imm32/size +19504 0x78/x 0x6d/m 0x6d/m 0x30/0 +19505 +19506 $Mu-register-xmm1: +19507 0x11/imm32/alloc-id:fake:payload +19508 # "xmm1" +19509 0x4/imm32/size +19510 0x78/x 0x6d/m 0x6d/m 0x31/1 +19511 +19512 $Mu-register-xmm2: +19513 0x11/imm32/alloc-id:fake:payload +19514 # "xmm2" +19515 0x4/imm32/size +19516 0x78/x 0x6d/m 0x6d/m 0x32/2 +19517 +19518 $Mu-register-xmm3: +19519 0x11/imm32/alloc-id:fake:payload +19520 # "xmm3" +19521 0x4/imm32/size +19522 0x78/x 0x6d/m 0x6d/m 0x33/3 +19523 +19524 $Mu-register-xmm4: +19525 0x11/imm32/alloc-id:fake:payload +19526 # "xmm4" +19527 0x4/imm32/size +19528 0x78/x 0x6d/m 0x6d/m 0x34/4 +19529 +19530 $Mu-register-xmm5: +19531 0x11/imm32/alloc-id:fake:payload +19532 # "xmm5" +19533 0x4/imm32/size +19534 0x78/x 0x6d/m 0x6d/m 0x35/5 +19535 +19536 $Mu-register-xmm6: +19537 0x11/imm32/alloc-id:fake:payload +19538 # "xmm6" +19539 0x4/imm32/size +19540 0x78/x 0x6d/m 0x6d/m 0x36/6 +19541 +19542 $Mu-register-xmm7: +19543 0x11/imm32/alloc-id:fake:payload +19544 # "xmm7" +19545 0x4/imm32/size +19546 0x78/x 0x6d/m 0x6d/m 0x37/7 +19547 +19548 == code +19549 +19550 # push 'out' to 'vars' if not already there; it's assumed to be a fn output +19551 maybe-define-var: # out: (handle var), vars: (addr stack live-var) +19552 # . prologue +19553 55/push-ebp +19554 89/<- %ebp 4/r32/esp +19555 # . save registers +19556 50/push-eax +19557 # var out-addr/eax: (addr var) +19558 (lookup *(ebp+8) *(ebp+0xc)) # => eax +19559 # +19560 (binding-exists? %eax *(ebp+0x10)) # => eax +19561 3d/compare-eax-and 0/imm32/false +19562 75/jump-if-!= $maybe-define-var:end/disp8 +19563 # otherwise update vars +19564 (push *(ebp+0x10) *(ebp+8)) +19565 (push *(ebp+0x10) *(ebp+0xc)) +19566 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it +19567 $maybe-define-var:end: +19568 # . restore registers +19569 58/pop-to-eax +19570 # . epilogue +19571 89/<- %esp 5/r32/ebp +19572 5d/pop-to-ebp +19573 c3/return +19574 +19575 # simpler version of lookup-var-helper +19576 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean +19577 # pseudocode: +19578 # var curr: (addr handle var) = &vars->data[vars->top - 12] +19579 # var min = vars->data +19580 # while curr >= min +19581 # var v: (handle var) = *curr +19582 # if v->name == target->name +19583 # return true +19584 # curr -= 12 +19585 # return false +19586 # +19587 # . prologue +19588 55/push-ebp +19589 89/<- %ebp 4/r32/esp +19590 # . save registers +19591 51/push-ecx +19592 52/push-edx +19593 56/push-esi +19594 # var target-name/ecx: (addr array byte) = lookup(target->name) +19595 8b/-> *(ebp+8) 0/r32/eax +19596 (lookup *eax *(eax+4)) # Var-name Var-name => eax +19597 89/<- %ecx 0/r32/eax +19598 # esi = vars +19599 8b/-> *(ebp+0xc) 6/r32/esi +19600 # eax = vars->top +19601 8b/-> *esi 0/r32/eax +19602 # var min/edx: (addr handle var) = vars->data +19603 8d/copy-address *(esi+8) 2/r32/edx +19604 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +19605 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12 +19606 { +19607 $binding-exists?:loop: +19608 # if (curr < min) return +19609 39/compare %esi 2/r32/edx +19610 0f 82/jump-if-addr< break/disp32 +19611 # var v/eax: (addr var) = lookup(*curr) +19612 (lookup *esi *(esi+4)) # => eax +19613 # var vn/eax: (addr array byte) = lookup(v->name) +19614 (lookup *eax *(eax+4)) # Var-name Var-name => eax +19615 # if (vn == target-name) return true +19616 (string-equal? %ecx %eax) # => eax +19617 3d/compare-eax-and 0/imm32/false +19618 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true +19619 # curr -= 12 +19620 81 5/subop/subtract %esi 0xc/imm32 +19621 e9/jump loop/disp32 +19622 } +19623 b8/copy-to-eax 0/imm32/false +19624 $binding-exists?:end: +19625 # . restore registers +19626 5e/pop-to-esi +19627 5a/pop-to-edx +19628 59/pop-to-ecx +19629 # . epilogue +19630 89/<- %esp 5/r32/ebp +19631 5d/pop-to-ebp +19632 c3/return +19633 +19634 test-parse-mu-stmt: +19635 # . prologue +19636 55/push-ebp +19637 89/<- %ebp 4/r32/esp +19638 # setup +19639 8b/-> *Primitive-type-ids 0/r32/eax +19640 89/<- *Type-id 0/r32/eax # stream-write +19641 (clear-stream _test-input-stream) +19642 (write _test-input-stream "increment n\n") +19643 # var vars/ecx: (stack (addr var) 16) +19644 81 5/subop/subtract %esp 0xc0/imm32 +19645 68/push 0xc0/imm32/size +19646 68/push 0/imm32/top +19647 89/<- %ecx 4/r32/esp +19648 (clear-stack %ecx) +19649 # var v/edx: (handle var) +19650 68/push 0/imm32 +19651 68/push 0/imm32 +19652 89/<- %edx 4/r32/esp +19653 # var s/eax: (handle array byte) +19654 68/push 0/imm32 +19655 68/push 0/imm32 +19656 89/<- %eax 4/r32/esp +19657 # v = new var("n") +19658 (copy-array Heap "n" %eax) +19659 (new-var Heap *eax *(eax+4) %edx) +19660 # +19661 (push %ecx *edx) +19662 (push %ecx *(edx+4)) +19663 (push %ecx 0) +19664 # var out/eax: (handle stmt) +19665 68/push 0/imm32 +19666 68/push 0/imm32 +19667 89/<- %eax 4/r32/esp +19668 # convert +19669 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) +19670 # var out-addr/edx: (addr stmt) = lookup(*out) +19671 (lookup *eax *(eax+4)) # => eax +19672 89/<- %edx 0/r32/eax +19673 # out->tag +19674 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 +19675 # out->operation +19676 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax +19677 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation +19678 # out->inouts->value->name +19679 # . eax = out->inouts +19680 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +19681 # . eax = out->inouts->value +19682 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +19683 # . eax = out->inouts->value->name +19684 (lookup *eax *(eax+4)) # Var-name Var-name => eax +19685 # . +19686 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") +19687 # . epilogue +19688 89/<- %esp 5/r32/ebp +19689 5d/pop-to-ebp +19690 c3/return +19691 +19692 test-parse-mu-stmt-with-comma: +19693 # . prologue +19694 55/push-ebp +19695 89/<- %ebp 4/r32/esp +19696 # setup +19697 8b/-> *Primitive-type-ids 0/r32/eax +19698 89/<- *Type-id 0/r32/eax # stream-write +19699 (clear-stream _test-input-stream) +19700 (write _test-input-stream "copy-to n, 3\n") +19701 # var vars/ecx: (stack (addr var) 16) +19702 81 5/subop/subtract %esp 0xc0/imm32 +19703 68/push 0xc0/imm32/size +19704 68/push 0/imm32/top +19705 89/<- %ecx 4/r32/esp +19706 (clear-stack %ecx) +19707 # var v/edx: (handle var) +19708 68/push 0/imm32 +19709 68/push 0/imm32 +19710 89/<- %edx 4/r32/esp +19711 # var s/eax: (handle array byte) +19712 68/push 0/imm32 +19713 68/push 0/imm32 +19714 89/<- %eax 4/r32/esp +19715 # v = new var("n") +19716 (copy-array Heap "n" %eax) +19717 (new-var Heap *eax *(eax+4) %edx) +19718 # +19719 (push %ecx *edx) +19720 (push %ecx *(edx+4)) +19721 (push %ecx 0) +19722 # var out/eax: (handle stmt) +19723 68/push 0/imm32 +19724 68/push 0/imm32 +19725 89/<- %eax 4/r32/esp +19726 # convert +19727 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) +19728 # var out-addr/edx: (addr stmt) = lookup(*out) +19729 (lookup *eax *(eax+4)) # => eax +19730 89/<- %edx 0/r32/eax +19731 # out->tag +19732 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 +19733 # out->operation +19734 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax +19735 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation +19736 # out->inouts->value->name +19737 # . eax = out->inouts +19738 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +19739 # . eax = out->inouts->value +19740 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +19741 # . eax = out->inouts->value->name +19742 (lookup *eax *(eax+4)) # Var-name Var-name => eax +19743 # . +19744 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") +19745 # . epilogue +19746 89/<- %esp 5/r32/ebp +19747 5d/pop-to-ebp +19748 c3/return +19749 +19750 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) +19751 # . prologue +19752 55/push-ebp +19753 89/<- %ebp 4/r32/esp +19754 # . save registers +19755 50/push-eax +19756 51/push-ecx +19757 # ecx = out +19758 8b/-> *(ebp+0x14) 1/r32/ecx +19759 # +19760 (allocate *(ebp+8) *Var-size %ecx) +19761 # var out-addr/eax: (addr var) +19762 (lookup *ecx *(ecx+4)) # => eax +19763 # out-addr->name = name +19764 8b/-> *(ebp+0xc) 1/r32/ecx +19765 89/<- *eax 1/r32/ecx # Var-name +19766 8b/-> *(ebp+0x10) 1/r32/ecx +19767 89/<- *(eax+4) 1/r32/ecx # Var-name +19768 #? (write-buffered Stderr "var ") +19769 #? (lookup *(ebp+0xc) *(ebp+0x10)) +19770 #? (write-buffered Stderr %eax) +19771 #? (write-buffered Stderr " at ") +19772 #? 8b/-> *(ebp+0x14) 1/r32/ecx +19773 #? (lookup *ecx *(ecx+4)) # => eax +19774 #? (write-int32-hex-buffered Stderr %eax) +19775 #? (write-buffered Stderr Newline) +19776 #? (flush Stderr) +19777 $new-var:end: +19778 # . restore registers +19779 59/pop-to-ecx +19780 58/pop-to-eax +19781 # . epilogue +19782 89/<- %esp 5/r32/ebp +19783 5d/pop-to-ebp +19784 c3/return +19785 +19786 # WARNING: modifies name +19787 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +19788 # . prologue +19789 55/push-ebp +19790 89/<- %ebp 4/r32/esp +19791 # . save registers +19792 50/push-eax +19793 51/push-ecx +19794 # first strip out metadata +19795 8b/-> *(ebp+0xc) 1/r32/ecx +19796 (next-token-from-slice *ecx *(ecx+4) 0x2f *(ebp+0xc)) +19797 # if (!is-hex-int?(name)) abort +19798 (hex-int? *(ebp+0xc)) # => eax +19799 3d/compare-eax-and 0/imm32/false +19800 0f 84/jump-if-= $new-literal-integer:abort/disp32 +19801 # a little more error-checking +19802 (check-mu-hex-int *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +19803 # out = new var(s) +19804 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) +19805 # var out-addr/ecx: (addr var) = lookup(*out) +19806 8b/-> *(ebp+0x10) 0/r32/eax +19807 (lookup *eax *(eax+4)) # => eax +19808 89/<- %ecx 0/r32/eax +19809 # out-addr->block-depth = *Curr-block-depth +19810 8b/-> *Curr-block-depth 0/r32/eax +19811 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +19812 # out-addr->type = new tree() +19813 8d/copy-address *(ecx+8) 0/r32/eax # Var-type +19814 (allocate *(ebp+8) *Type-tree-size %eax) +19815 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +19816 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +19817 # nothing else to do; default type is 'literal' +19818 $new-literal-integer:end: +19819 # . reclaim locals +19820 81 0/subop/add %esp 8/imm32 +19821 # . restore registers +19822 59/pop-to-ecx +19823 58/pop-to-eax +19824 # . epilogue +19825 89/<- %esp 5/r32/ebp +19826 5d/pop-to-ebp +19827 c3/return +19828 +19829 $new-literal-integer:abort: +19830 (write-buffered *(ebp+0x18) "fn ") +19831 8b/-> *(ebp+0x14) 0/r32/eax +19832 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19833 (write-buffered *(ebp+0x18) %eax) +19834 (write-buffered *(ebp+0x18) ": variable '") +19835 (write-slice-buffered *(ebp+0x18) *(ebp+0xc)) +19836 (write-buffered *(ebp+0x18) "' cannot begin with a digit (or do you have a typo in a number?)\n") +19837 (flush *(ebp+0x18)) +19838 (stop *(ebp+0x1c) 1) +19839 # never gets here +19840 +19841 # precondition: name is a valid hex integer; require a '0x' prefix +19842 check-mu-hex-int: # name: (addr slice), err: (addr buffered-file), ed: (addr exit-descriptor) +19843 # . prologue +19844 55/push-ebp +19845 89/<- %ebp 4/r32/esp +19846 # . save registers +19847 50/push-eax +19848 51/push-ecx +19849 52/push-edx +19850 # ecx = name +19851 8b/-> *(ebp+8) 1/r32/ecx +19852 # var start/edx: (addr byte) = name->start +19853 8b/-> *ecx 2/r32/edx +19854 # if (*start == '-') ++start +19855 b8/copy-to-eax 0/imm32 +19856 8a/copy-byte *edx 0/r32/AL +19857 3d/compare-eax-and 0x2d/imm32/dash +19858 { +19859 75/jump-if-!= break/disp8 +19860 42/increment-edx +19861 } +19862 # var end/ecx: (addr byte) = name->end +19863 8b/-> *(ecx+4) 1/r32/ecx +19864 # var len/eax: int = name->end - name->start +19865 89/<- %eax 1/r32/ecx +19866 29/subtract-from %eax 2/r32/edx +19867 # if (len <= 1) return +19868 3d/compare-eax-with 1/imm32 +19869 0f 8e/jump-if-<= $check-mu-hex-int:end/disp32 +19870 $check-mu-hex-int:length->-1: +19871 # if slice-starts-with?({start, end}, "0x") return +19872 # . var tmp = {start, end} +19873 51/push-ecx +19874 52/push-edx +19875 89/<- %eax 4/r32/esp +19876 # . +19877 (slice-starts-with? %eax "0x") # => eax +19878 # . reclaim tmp +19879 81 0/subop/add %esp 8/imm32 +19880 # . +19881 3d/compare-eax-with 0/imm32/false +19882 75/jump-if-!= $check-mu-hex-int:end/disp8 +19883 $check-mu-hex-int:abort: +19884 # otherwise abort +19885 (write-buffered *(ebp+0xc) "literal integers are always hex in Mu; start '") +19886 (write-slice-buffered *(ebp+0xc) *(ebp+8)) +19887 (write-buffered *(ebp+0xc) "' with a '0x' to be unambiguous, converting it to hexadecimal as necessary.\n") +19888 (flush *(ebp+0xc)) +19889 (stop *(ebp+0x10) 1) +19890 $check-mu-hex-int:end: +19891 # . restore registers +19892 5a/pop-to-edx +19893 59/pop-to-ecx +19894 58/pop-to-eax +19895 # . epilogue +19896 89/<- %esp 5/r32/ebp +19897 5d/pop-to-ebp +19898 c3/return +19899 +19900 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) +19901 # . prologue +19902 55/push-ebp +19903 89/<- %ebp 4/r32/esp +19904 # . save registers +19905 50/push-eax +19906 51/push-ecx +19907 # var s/ecx: (handle array byte) +19908 68/push 0/imm32 +19909 68/push 0/imm32 +19910 89/<- %ecx 4/r32/esp +19911 # s = slice-to-string(name) +19912 (slice-to-string Heap *(ebp+0xc) %ecx) +19913 # allocate to out +19914 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) +19915 # var out-addr/ecx: (addr var) = lookup(*out) +19916 8b/-> *(ebp+0x10) 1/r32/ecx +19917 (lookup *ecx *(ecx+4)) # => eax +19918 89/<- %ecx 0/r32/eax +19919 # out-addr->block-depth = *Curr-block-depth +19920 8b/-> *Curr-block-depth 0/r32/eax +19921 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +19922 # out-addr->type/eax = new type +19923 8d/copy-address *(ecx+8) 0/r32/eax # Var-type +19924 (allocate *(ebp+8) *Type-tree-size %eax) +19925 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +19926 # nothing else to do; default type is 'literal' +19927 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +19928 $new-literal:end: +19929 # . reclaim locals +19930 81 0/subop/add %esp 8/imm32 +19931 # . restore registers +19932 59/pop-to-ecx +19933 58/pop-to-eax +19934 # . epilogue +19935 89/<- %esp 5/r32/ebp +19936 5d/pop-to-ebp +19937 c3/return +19938 +19939 new-literal-string: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) +19940 # . prologue +19941 55/push-ebp +19942 89/<- %ebp 4/r32/esp +19943 # . save registers +19944 50/push-eax +19945 51/push-ecx +19946 # var s/ecx: (handle array byte) +19947 68/push 0/imm32 +19948 68/push 0/imm32 +19949 89/<- %ecx 4/r32/esp +19950 # s = slice-to-string(name) +19951 (slice-to-string Heap *(ebp+0xc) %ecx) +19952 # allocate to out +19953 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) +19954 # var out-addr/ecx: (addr var) = lookup(*out) +19955 8b/-> *(ebp+0x10) 1/r32/ecx +19956 (lookup *ecx *(ecx+4)) # => eax +19957 89/<- %ecx 0/r32/eax +19958 # out-addr->block-depth = *Curr-block-depth +19959 8b/-> *Curr-block-depth 0/r32/eax +19960 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +19961 # out-addr->type/eax = new type +19962 8d/copy-address *(ecx+8) 0/r32/eax # Var-type +19963 (allocate *(ebp+8) *Type-tree-size %eax) +19964 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +19965 # out-addr->type->value = literal-string +19966 c7 0/subop/copy *(eax+4) 0x10/imm32/type-id-string-literal # Type-tree-value +19967 # out-addr->type->is-atom? = true +19968 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +19969 $new-literal-string:end: +19970 # . reclaim locals +19971 81 0/subop/add %esp 8/imm32 +19972 # . restore registers +19973 59/pop-to-ecx +19974 58/pop-to-eax +19975 # . epilogue +19976 89/<- %esp 5/r32/ebp +19977 5d/pop-to-ebp +19978 c3/return +19979 +19980 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) +19981 # . prologue +19982 55/push-ebp +19983 89/<- %ebp 4/r32/esp +19984 # . save registers +19985 51/push-ecx +19986 # var tmp/ecx: (handle array byte) +19987 68/push 0/imm32 +19988 68/push 0/imm32 +19989 89/<- %ecx 4/r32/esp +19990 # tmp = slice-to-string(name) +19991 (slice-to-string Heap *(ebp+0xc) %ecx) +19992 # out = new-var(tmp) +19993 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) +19994 $new-var-from-slice:end: +19995 # . reclaim locals +19996 81 0/subop/add %esp 8/imm32 +19997 # . restore registers +19998 59/pop-to-ecx +19999 # . epilogue +20000 89/<- %esp 5/r32/ebp +20001 5d/pop-to-ebp +20002 c3/return +20003 +20004 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) +20005 # . prologue +20006 55/push-ebp +20007 89/<- %ebp 4/r32/esp +20008 # . save registers +20009 50/push-eax +20010 51/push-ecx +20011 # +20012 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) +20013 # var out-addr/eax: (addr stmt) = lookup(*out) +20014 8b/-> *(ebp+0x14) 0/r32/eax +20015 (lookup *eax *(eax+4)) # => eax +20016 # out-addr->tag = stmt +20017 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag +20018 # result->var = var +20019 8b/-> *(ebp+0xc) 1/r32/ecx +20020 89/<- *(eax+4) 1/r32/ecx # Vardef-var +20021 8b/-> *(ebp+0x10) 1/r32/ecx +20022 89/<- *(eax+8) 1/r32/ecx # Vardef-var +20023 $new-var-def:end: +20024 # . restore registers +20025 59/pop-to-ecx +20026 58/pop-to-eax +20027 # . epilogue +20028 89/<- %esp 5/r32/ebp +20029 5d/pop-to-ebp +20030 c3/return +20031 +20032 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) +20033 # . prologue +20034 55/push-ebp +20035 89/<- %ebp 4/r32/esp +20036 # . save registers +20037 50/push-eax +20038 # eax = out +20039 8b/-> *(ebp+0x14) 0/r32/eax +20040 # +20041 (allocate *(ebp+8) *Stmt-size %eax) +20042 # var out-addr/eax: (addr stmt) = lookup(*out) +20043 (lookup *eax *(eax+4)) # => eax +20044 # set tag +20045 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag +20046 # set output +20047 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs +20048 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) +20049 $new-reg-var-def:end: +20050 # . restore registers +20051 58/pop-to-eax +20052 # . epilogue +20053 89/<- %esp 5/r32/ebp +20054 5d/pop-to-ebp +20055 c3/return +20056 +20057 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) +20058 # . prologue +20059 55/push-ebp +20060 89/<- %ebp 4/r32/esp +20061 # . save registers +20062 50/push-eax +20063 51/push-ecx +20064 57/push-edi +20065 # edi = out +20066 8b/-> *(ebp+0x1c) 7/r32/edi +20067 # *out = new list +20068 (allocate *(ebp+8) *List-size %edi) +20069 # var out-addr/edi: (addr list _type) = lookup(*out) +20070 (lookup *edi *(edi+4)) # => eax +20071 89/<- %edi 0/r32/eax +20072 # out-addr->value = value +20073 8b/-> *(ebp+0xc) 0/r32/eax +20074 89/<- *edi 0/r32/eax # List-value +20075 8b/-> *(ebp+0x10) 0/r32/eax +20076 89/<- *(edi+4) 0/r32/eax # List-value +20077 # if (list == null) return +20078 81 7/subop/compare *(ebp+0x14) 0/imm32 +20079 74/jump-if-= $append-list:end/disp8 +20080 # otherwise append +20081 $append-list:non-empty-list: +20082 # var curr/eax: (addr list _type) = lookup(list) +20083 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax +20084 # while (curr->next != null) curr = curr->next +20085 { +20086 81 7/subop/compare *(eax+8) 0/imm32 # List-next +20087 74/jump-if-= break/disp8 +20088 # curr = lookup(curr->next) +20089 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax +20090 # +20091 eb/jump loop/disp8 +20092 } +20093 # edi = out +20094 8b/-> *(ebp+0x1c) 7/r32/edi +20095 # curr->next = out +20096 8b/-> *edi 1/r32/ecx +20097 89/<- *(eax+8) 1/r32/ecx # List-next +20098 8b/-> *(edi+4) 1/r32/ecx +20099 89/<- *(eax+0xc) 1/r32/ecx # List-next +20100 # out = list +20101 8b/-> *(ebp+0x14) 1/r32/ecx +20102 89/<- *edi 1/r32/ecx +20103 8b/-> *(ebp+0x18) 1/r32/ecx +20104 89/<- *(edi+4) 1/r32/ecx +20105 $append-list:end: +20106 # . restore registers +20107 5f/pop-to-edi +20108 59/pop-to-ecx +20109 58/pop-to-eax +20110 # . epilogue +20111 89/<- %esp 5/r32/ebp +20112 5d/pop-to-ebp +20113 c3/return +20114 +20115 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) +20116 # . prologue +20117 55/push-ebp +20118 89/<- %ebp 4/r32/esp +20119 # . save registers +20120 50/push-eax +20121 51/push-ecx +20122 57/push-edi +20123 # edi = out +20124 8b/-> *(ebp+0x20) 7/r32/edi +20125 # out = new stmt-var +20126 (allocate *(ebp+8) *Stmt-var-size %edi) +20127 # var out-addr/ecx: (addr stmt-var) = lookup(*out) +20128 (lookup *edi *(edi+4)) # => eax +20129 89/<- %ecx 0/r32/eax +20130 # out-addr->value = v +20131 8b/-> *(ebp+0xc) 0/r32/eax +20132 89/<- *ecx 0/r32/eax # Stmt-var-value +20133 8b/-> *(ebp+0x10) 0/r32/eax +20134 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value +20135 # out-addr->is-deref? = is-deref? +20136 8b/-> *(ebp+0x1c) 0/r32/eax +20137 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref +20138 # if (vars == null) return result +20139 81 7/subop/compare *(ebp+0x14) 0/imm32/null +20140 74/jump-if-= $append-stmt-var:end/disp8 +20141 # otherwise append +20142 # var curr/eax: (addr stmt-var) = lookup(vars) +20143 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax +20144 # while (curr->next != null) curr = curr->next +20145 { +20146 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next +20147 74/jump-if-= break/disp8 +20148 # curr = lookup(curr->next) +20149 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax +20150 # +20151 eb/jump loop/disp8 +20152 } +20153 # curr->next = out +20154 8b/-> *edi 1/r32/ecx +20155 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next +20156 8b/-> *(edi+4) 1/r32/ecx +20157 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next +20158 # out = vars +20159 8b/-> *(ebp+0x14) 1/r32/ecx +20160 89/<- *edi 1/r32/ecx +20161 8b/-> *(ebp+0x18) 1/r32/ecx +20162 89/<- *(edi+4) 1/r32/ecx +20163 $append-stmt-var:end: +20164 # . restore registers +20165 5f/pop-to-edi +20166 59/pop-to-ecx +20167 58/pop-to-eax +20168 # . epilogue +20169 89/<- %esp 5/r32/ebp +20170 5d/pop-to-ebp +20171 c3/return +20172 +20173 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) +20174 # . prologue +20175 55/push-ebp +20176 89/<- %ebp 4/r32/esp +20177 # . save registers +20178 50/push-eax +20179 56/push-esi +20180 # esi = block +20181 8b/-> *(ebp+0xc) 6/r32/esi +20182 # block->stmts = append(x, block->stmts) +20183 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts +20184 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts +20185 $append-to-block:end: +20186 # . restore registers +20187 5e/pop-to-esi +20188 58/pop-to-eax +20189 # . epilogue +20190 89/<- %esp 5/r32/ebp +20191 5d/pop-to-ebp +20192 c3/return +20193 +20194 ## Parsing types +20195 # We need to create metadata on user-defined types, and we need to use this +20196 # metadata as we parse instructions. +20197 # However, we also want to allow types to be used before their definitions. +20198 # This means we can't ever assume any type data structures exist. +20199 +20200 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) +20201 # . prologue +20202 55/push-ebp +20203 89/<- %ebp 4/r32/esp +20204 # . save registers +20205 50/push-eax +20206 56/push-esi +20207 # var container-type/esi: type-id +20208 (container-type *(ebp+8)) # => eax +20209 89/<- %esi 0/r32/eax +20210 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) +20211 68/push 0/imm32 +20212 68/push 0/imm32 +20213 89/<- %eax 4/r32/esp +20214 (find-or-create-typeinfo %esi %eax) +20215 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) +20216 (lookup *eax *(eax+4)) # => eax +20217 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) +20218 #? (write-buffered Stderr "constant: ") +20219 #? (write-slice-buffered Stderr *(ebp+0xc)) +20220 #? (write-buffered Stderr Newline) +20221 #? (flush Stderr) +20222 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) +20223 #? 8b/-> *(ebp+0x10) 0/r32/eax +20224 #? (write-buffered Stderr "@") +20225 #? (lookup *eax *(eax+4)) +20226 #? (write-int32-hex-buffered Stderr %eax) +20227 #? (lookup *eax *(eax+4)) +20228 #? (write-buffered Stderr %eax) +20229 #? (write-buffered Stderr Newline) +20230 #? (flush Stderr) +20231 #? (write-buffered Stderr "offset: ") +20232 #? 8b/-> *(eax+0x14) 0/r32/eax +20233 #? (write-int32-hex-buffered Stderr %eax) +20234 #? (write-buffered Stderr Newline) +20235 #? (flush Stderr) +20236 $lookup-or-create-constant:end: +20237 # . reclaim locals +20238 81 0/subop/add %esp 8/imm32 +20239 # . restore registers +20240 5e/pop-to-esi +20241 58/pop-to-eax +20242 # . epilogue +20243 89/<- %esp 5/r32/ebp +20244 5d/pop-to-ebp +20245 c3/return +20246 +20247 # if addr var: +20248 # container->var->type->right->left->value +20249 # otherwise +20250 # container->var->type->value +20251 container-type: # container: (addr stmt-var) -> result/eax: type-id +20252 # . prologue +20253 55/push-ebp +20254 89/<- %ebp 4/r32/esp +20255 # +20256 8b/-> *(ebp+8) 0/r32/eax +20257 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +20258 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +20259 { +20260 81 7/subop/compare *(eax+8) 0/imm32 # Type-tree-right +20261 74/jump-if-= break/disp8 +20262 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +20263 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +20264 } +20265 8b/-> *(eax+4) 0/r32/eax # Type-tree-value +20266 $container-type:end: +20267 # . epilogue +20268 89/<- %esp 5/r32/ebp +20269 5d/pop-to-ebp +20270 c3/return +20271 +20272 container?: # t: type-id -> result/eax: boolean +20273 # . prologue +20274 55/push-ebp +20275 89/<- %ebp 4/r32/esp +20276 # +20277 8b/-> *(ebp+8) 0/r32/eax +20278 c1/shift 4/subop/left %eax 2/imm8 +20279 3b/compare 0/r32/eax *Primitive-type-ids +20280 0f 9d/set-if->= %al +20281 25/and-eax-with 0xff/imm32 +20282 $container?:end: +20283 # . epilogue +20284 89/<- %esp 5/r32/ebp +20285 5d/pop-to-ebp +20286 c3/return +20287 +20288 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) +20289 # . prologue +20290 55/push-ebp +20291 89/<- %ebp 4/r32/esp +20292 # . save registers +20293 50/push-eax +20294 51/push-ecx +20295 52/push-edx +20296 57/push-edi +20297 # edi = out +20298 8b/-> *(ebp+0xc) 7/r32/edi +20299 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) +20300 68/push 0/imm32 +20301 68/push 0/imm32 +20302 89/<- %ecx 4/r32/esp +20303 # find-typeinfo(t, out) +20304 (find-typeinfo *(ebp+8) %edi) +20305 { +20306 # if (*out != 0) break +20307 81 7/subop/compare *edi 0/imm32 +20308 0f 85/jump-if-!= break/disp32 +20309 $find-or-create-typeinfo:create: +20310 # *out = allocate +20311 (allocate Heap *Typeinfo-size %edi) +20312 # var tmp/eax: (addr typeinfo) = lookup(*out) +20313 (lookup *edi *(edi+4)) # => eax +20314 #? (write-buffered Stderr "created typeinfo at ") +20315 #? (write-int32-hex-buffered Stderr %eax) +20316 #? (write-buffered Stderr " for type-id ") +20317 #? (write-int32-hex-buffered Stderr *(ebp+8)) +20318 #? (write-buffered Stderr Newline) +20319 #? (flush Stderr) +20320 # tmp->id = t +20321 8b/-> *(ebp+8) 2/r32/edx +20322 89/<- *eax 2/r32/edx # Typeinfo-id +20323 # tmp->fields = new table +20324 # . fields = new table +20325 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) +20326 # . tmp->fields = fields +20327 8b/-> *ecx 2/r32/edx +20328 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields +20329 8b/-> *(ecx+4) 2/r32/edx +20330 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields +20331 # tmp->next = Program->types +20332 8b/-> *_Program-types 1/r32/ecx +20333 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next +20334 8b/-> *_Program-types->payload 1/r32/ecx +20335 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next +20336 # Program->types = out +20337 8b/-> *edi 1/r32/ecx +20338 89/<- *_Program-types 1/r32/ecx +20339 8b/-> *(edi+4) 1/r32/ecx +20340 89/<- *_Program-types->payload 1/r32/ecx +20341 } +20342 $find-or-create-typeinfo:end: +20343 # . reclaim locals +20344 81 0/subop/add %esp 8/imm32 +20345 # . restore registers +20346 5f/pop-to-edi +20347 5a/pop-to-edx +20348 59/pop-to-ecx +20349 58/pop-to-eax +20350 # . epilogue +20351 89/<- %esp 5/r32/ebp +20352 5d/pop-to-ebp +20353 c3/return +20354 +20355 find-typeinfo: # t: type-id, out: (addr handle typeinfo) +20356 # . prologue +20357 55/push-ebp +20358 89/<- %ebp 4/r32/esp +20359 # . save registers +20360 50/push-eax +20361 51/push-ecx +20362 52/push-edx +20363 57/push-edi +20364 # ecx = t +20365 8b/-> *(ebp+8) 1/r32/ecx +20366 # edi = out +20367 8b/-> *(ebp+0xc) 7/r32/edi +20368 # *out = Program->types +20369 8b/-> *_Program-types 0/r32/eax +20370 89/<- *edi 0/r32/eax +20371 8b/-> *_Program-types->payload 0/r32/eax +20372 89/<- *(edi+4) 0/r32/eax +20373 { +20374 $find-typeinfo:loop: +20375 # if (*out == 0) break +20376 81 7/subop/compare *edi 0/imm32 +20377 74/jump-if-= break/disp8 +20378 $find-typeinfo:check: +20379 # var tmp/eax: (addr typeinfo) = lookup(*out) +20380 (lookup *edi *(edi+4)) # => eax +20381 # if (tmp->id == t) break +20382 39/compare *eax 1/r32/ecx # Typeinfo-id +20383 74/jump-if-= break/disp8 +20384 $find-typeinfo:continue: +20385 # *out = tmp->next +20386 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next +20387 89/<- *edi 2/r32/edx +20388 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next +20389 89/<- *(edi+4) 2/r32/edx +20390 # +20391 eb/jump loop/disp8 +20392 } +20393 $find-typeinfo:end: +20394 # . restore registers +20395 5f/pop-to-edi +20396 5a/pop-to-edx +20397 59/pop-to-ecx +20398 58/pop-to-eax +20399 # . epilogue +20400 89/<- %esp 5/r32/ebp +20401 5d/pop-to-ebp +20402 c3/return +20403 +20404 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) +20405 # . prologue +20406 55/push-ebp +20407 89/<- %ebp 4/r32/esp +20408 # . save registers +20409 50/push-eax +20410 52/push-edx +20411 57/push-edi +20412 # var dest/edi: (handle typeinfo-entry) +20413 68/push 0/imm32 +20414 68/push 0/imm32 +20415 89/<- %edi 4/r32/esp +20416 # find-or-create-typeinfo-fields(T, f, dest) +20417 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) +20418 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) +20419 (lookup *edi *(edi+4)) # => eax +20420 89/<- %edi 0/r32/eax +20421 # if dest-addr->output-var doesn't exist, create it +20422 { +20423 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var +20424 0f 85/jump-if-!= break/disp32 +20425 # dest-addr->output-var = new var(dummy name, type, -1 offset) +20426 # . var name/eax: (handle array byte) = "field" +20427 68/push 0/imm32 +20428 68/push 0/imm32 +20429 89/<- %eax 4/r32/esp +20430 (slice-to-string Heap *(ebp+0xc) %eax) +20431 # . new var +20432 8d/copy-address *(edi+0xc) 2/r32/edx +20433 (new-var Heap *eax *(eax+4) %edx) +20434 # . reclaim name +20435 81 0/subop/add %esp 8/imm32 +20436 # var result/edx: (addr var) = lookup(dest-addr->output-var) +20437 (lookup *(edi+0xc) *(edi+0x10)) # => eax +20438 89/<- %edx 0/r32/eax +20439 # result->type = new constant type +20440 8d/copy-address *(edx+8) 0/r32/eax # Var-type +20441 (allocate Heap *Type-tree-size %eax) +20442 (lookup *(edx+8) *(edx+0xc)) # => eax +20443 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +20444 c7 0/subop/copy *(eax+4) 6/imm32/constant # Type-tree-value +20445 c7 0/subop/copy *(eax+8) 0/imm32 # Type-tree-left +20446 c7 0/subop/copy *(eax+0xc) 0/imm32 # Type-tree-right +20447 c7 0/subop/copy *(eax+0x10) 0/imm32 # Type-tree-right +20448 # result->offset isn't filled out yet +20449 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset +20450 } +20451 # out = dest-addr->output-var +20452 8b/-> *(ebp+0x10) 2/r32/edx +20453 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var +20454 89/<- *edx 0/r32/eax +20455 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var +20456 89/<- *(edx+4) 0/r32/eax +20457 $find-or-create-typeinfo-output-var:end: +20458 # . reclaim locals +20459 81 0/subop/add %esp 8/imm32 +20460 # . restore registers +20461 5f/pop-to-edi +20462 5a/pop-to-edx +20463 58/pop-to-eax +20464 # . epilogue +20465 89/<- %esp 5/r32/ebp +20466 5d/pop-to-ebp +20467 c3/return +20468 +20469 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) +20470 # . prologue +20471 55/push-ebp +20472 89/<- %ebp 4/r32/esp +20473 # . save registers +20474 50/push-eax +20475 56/push-esi +20476 57/push-edi +20477 # eax = lookup(T->fields) +20478 8b/-> *(ebp+8) 0/r32/eax +20479 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax +20480 # edi = out +20481 8b/-> *(ebp+0x10) 7/r32/edi +20482 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) +20483 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax +20484 89/<- %esi 0/r32/eax +20485 # if src doesn't exist, allocate it +20486 { +20487 81 7/subop/compare *esi 0/imm32 +20488 75/jump-if-!= break/disp8 +20489 (allocate Heap *Typeinfo-entry-size %esi) +20490 #? (write-buffered Stderr "handle at ") +20491 #? (write-int32-hex-buffered Stderr %esi) +20492 #? (write-buffered Stderr ": ") +20493 #? (write-int32-hex-buffered Stderr *esi) +20494 #? (write-buffered Stderr " ") +20495 #? (write-int32-hex-buffered Stderr *(esi+4)) +20496 #? (write-buffered Stderr Newline) +20497 #? (flush Stderr) +20498 #? (lookup *esi *(esi+4)) +20499 #? (write-buffered Stderr "created typeinfo fields at ") +20500 #? (write-int32-hex-buffered Stderr %esi) +20501 #? (write-buffered Stderr " for ") +20502 #? (write-int32-hex-buffered Stderr *(ebp+8)) +20503 #? (write-buffered Stderr Newline) +20504 #? (flush Stderr) +20505 } +20506 # *out = src +20507 # . *edi = *src +20508 8b/-> *esi 0/r32/eax +20509 89/<- *edi 0/r32/eax +20510 8b/-> *(esi+4) 0/r32/eax +20511 89/<- *(edi+4) 0/r32/eax +20512 $find-or-create-typeinfo-fields:end: +20513 # . restore registers +20514 5f/pop-to-edi +20515 5e/pop-to-esi +20516 58/pop-to-eax +20517 # . epilogue +20518 89/<- %esp 5/r32/ebp +20519 5d/pop-to-ebp +20520 c3/return +20521 +20522 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +20523 # pseudocode: +20524 # var line: (stream byte 512) +20525 # curr-index = 0 +20526 # while true +20527 # clear-stream(line) +20528 # read-line-buffered(in, line) +20529 # if line->write == 0 +20530 # abort +20531 # word-slice = next-mu-token(line) +20532 # if slice-empty?(word-slice) # end of line +20533 # continue +20534 # if slice-equal?(word-slice, "}") +20535 # break +20536 # var v: (handle var) = parse-var-with-type(word-slice, line) +20537 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) +20538 # TODO: ensure that r->first is null +20539 # r->index = curr-index +20540 # curr-index++ +20541 # r->input-var = v +20542 # if r->output-var == 0 +20543 # r->output-var = new literal +20544 # TODO: ensure nothing else in line +20545 # t->total-size-in-bytes = -2 (not yet initialized) +20546 # +20547 # . prologue +20548 55/push-ebp +20549 89/<- %ebp 4/r32/esp +20550 # var curr-index: int at *(ebp-4) +20551 68/push 0/imm32 +20552 # . save registers +20553 50/push-eax +20554 51/push-ecx +20555 52/push-edx +20556 53/push-ebx +20557 56/push-esi +20558 57/push-edi +20559 # edi = t +20560 8b/-> *(ebp+0xc) 7/r32/edi +20561 # var line/ecx: (stream byte 512) +20562 81 5/subop/subtract %esp 0x200/imm32 +20563 68/push 0x200/imm32/size +20564 68/push 0/imm32/read +20565 68/push 0/imm32/write +20566 89/<- %ecx 4/r32/esp +20567 # var word-slice/edx: slice +20568 68/push 0/imm32/end +20569 68/push 0/imm32/start +20570 89/<- %edx 4/r32/esp +20571 # var v/esi: (handle var) +20572 68/push 0/imm32 +20573 68/push 0/imm32 +20574 89/<- %esi 4/r32/esp +20575 # var r/ebx: (handle typeinfo-entry) +20576 68/push 0/imm32 +20577 68/push 0/imm32 +20578 89/<- %ebx 4/r32/esp +20579 { +20580 $populate-mu-type:line-loop: +20581 (clear-stream %ecx) +20582 (read-line-buffered *(ebp+8) %ecx) +20583 # if (line->write == 0) abort +20584 81 7/subop/compare *ecx 0/imm32 +20585 0f 84/jump-if-= $populate-mu-type:error1/disp32 +20586 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ +20592 (next-mu-token %ecx %edx) +20593 # if slice-empty?(word-slice) continue +20594 (slice-empty? %edx) # => eax +20595 3d/compare-eax-and 0/imm32 +20596 0f 85/jump-if-!= loop/disp32 +20597 # if slice-equal?(word-slice, "}") break +20598 (slice-equal? %edx "}") +20599 3d/compare-eax-and 0/imm32 +20600 0f 85/jump-if-!= break/disp32 +20601 $populate-mu-type:parse-element: +20602 # v = parse-var-with-type(word-slice, first-line) +20603 # must do this first to strip the trailing ':' from word-slice before +20604 # using it in find-or-create-typeinfo-fields below +20605 # TODO: clean up that mutation in parse-var-with-type +20606 (type-name *edi) # Typeinfo-id => eax +20607 (parse-var-with-type %edx %ecx %esi %eax *(ebp+0x10) *(ebp+0x14)) +20608 # if v is an addr, abort +20609 (lookup *esi *(esi+4)) # => eax +20610 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +20611 (mu-addr-type? %eax) # => eax +20612 3d/compare-eax-and 0/imm32/false +20613 0f 85/jump-if-!= $populate-mu-type:error2/disp32 +20614 # if v is an array, abort (we could support it, but initialization gets complex) +20615 (lookup *esi *(esi+4)) # => eax +20616 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +20617 (mu-array-type? %eax) # => eax +20618 3d/compare-eax-and 0/imm32/false +20619 0f 85/jump-if-!= $populate-mu-type:error3/disp32 +20620 # if v is a byte, abort +20621 (lookup *esi *(esi+4)) # => eax +20622 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +20623 (simple-mu-type? %eax 8) # byte => eax +20624 3d/compare-eax-and 0/imm32/false +20625 0f 85/jump-if-!= $populate-mu-type:error4/disp32 +20626 # if v is a slice, abort +20627 (lookup *esi *(esi+4)) # => eax +20628 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +20629 (simple-mu-type? %eax 0xc) # slice => eax +20630 3d/compare-eax-and 0/imm32/false +20631 0f 85/jump-if-!= $populate-mu-type:error5/disp32 +20632 # if v is a stream, abort (we could support it, but initialization gets even more complex) +20633 (lookup *esi *(esi+4)) # => eax +20634 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +20635 (mu-stream-type? %eax) # => eax +20636 3d/compare-eax-and 0/imm32/false +20637 0f 85/jump-if-!= $populate-mu-type:error6/disp32 +20638 # var tmp/ecx +20639 51/push-ecx +20640 $populate-mu-type:create-typeinfo-fields: +20641 # var r/ebx: (handle typeinfo-entry) +20642 (find-or-create-typeinfo-fields %edi %edx %ebx) +20643 # r->index = curr-index +20644 (lookup *ebx *(ebx+4)) # => eax +20645 8b/-> *(ebp-4) 1/r32/ecx +20646 #? (write-buffered Stderr "saving index ") +20647 #? (write-int32-hex-buffered Stderr %ecx) +20648 #? (write-buffered Stderr " at ") +20649 #? (write-int32-hex-buffered Stderr %edi) +20650 #? (write-buffered Stderr Newline) +20651 #? (flush Stderr) +20652 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index +20653 # ++curr-index +20654 ff 0/subop/increment *(ebp-4) +20655 $populate-mu-type:set-input-type: +20656 # r->input-var = v +20657 8b/-> *esi 1/r32/ecx +20658 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var +20659 8b/-> *(esi+4) 1/r32/ecx +20660 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var +20661 # restore line +20662 59/pop-to-ecx +20663 { +20664 $populate-mu-type:create-output-type: +20665 # if (r->output-var == 0) create a new var with some placeholder data +20666 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var +20667 75/jump-if-!= break/disp8 +20668 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var +20669 (new-literal Heap %edx %eax) +20670 } +20671 e9/jump loop/disp32 +20672 } +20673 $populate-mu-type:invalidate-total-size-in-bytes: +20674 # Offsets and total size may not be accurate here since we may not yet +20675 # have encountered the element types. +20676 # We'll recompute them separately after parsing the entire program. +20677 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes +20678 $populate-mu-type:end: +20679 # . reclaim locals +20680 81 0/subop/add %esp 0x224/imm32 +20681 # . restore registers +20682 5f/pop-to-edi +20683 5e/pop-to-esi +20684 5b/pop-to-ebx +20685 5a/pop-to-edx +20686 59/pop-to-ecx +20687 58/pop-to-eax +20688 # reclaim curr-index +20689 81 0/subop/add %esp 4/imm32 +20690 # . epilogue +20691 89/<- %esp 5/r32/ebp +20692 5d/pop-to-ebp +20693 c3/return +20694 +20695 $populate-mu-type:error1: +20696 # error("incomplete type definition '" t->name "'\n") +20697 (write-buffered *(ebp+0x10) "incomplete type definition '") +20698 (type-name *edi) # Typeinfo-id => eax +20699 (write-buffered *(ebp+0x10) %eax) +20700 (write-buffered *(ebp+0x10) "\n") +20701 (flush *(ebp+0x10)) +20702 (stop *(ebp+0x14) 1) +20703 # never gets here +20704 +20705 $populate-mu-type:error2: +20706 (write-buffered *(ebp+0x10) "type ") +20707 (type-name *edi) # Typeinfo-id => eax +20708 (write-buffered *(ebp+0x10) %eax) +20709 (write-buffered *(ebp+0x10) ": 'addr' elements not allowed\n") +20710 (flush *(ebp+0x10)) +20711 (stop *(ebp+0x14) 1) +20712 # never gets here +20713 +20714 $populate-mu-type:error3: +20715 (write-buffered *(ebp+0x10) "type ") +20716 (type-name *edi) # Typeinfo-id => eax +20717 (write-buffered *(ebp+0x10) %eax) +20718 (write-buffered *(ebp+0x10) ": 'array' elements not allowed for now\n") +20719 (flush *(ebp+0x10)) +20720 (stop *(ebp+0x14) 1) +20721 # never gets here +20722 +20723 $populate-mu-type:error4: +20724 (write-buffered *(ebp+0x10) "type ") +20725 (type-name *edi) # Typeinfo-id => eax +20726 (write-buffered *(ebp+0x10) %eax) +20727 (write-buffered *(ebp+0x10) ": 'byte' elements not allowed\n") +20728 (flush *(ebp+0x10)) +20729 (stop *(ebp+0x14) 1) +20730 # never gets here +20731 +20732 $populate-mu-type:error5: +20733 (write-buffered *(ebp+0x10) "type ") +20734 (type-name *edi) # Typeinfo-id => eax +20735 (write-buffered *(ebp+0x10) %eax) +20736 (write-buffered *(ebp+0x10) ": 'slice' elements not allowed\n") +20737 (flush *(ebp+0x10)) +20738 (stop *(ebp+0x14) 1) +20739 # never gets here +20740 +20741 $populate-mu-type:error6: +20742 (write-buffered *(ebp+0x10) "type ") +20743 (type-name *edi) # Typeinfo-id => eax +20744 (write-buffered *(ebp+0x10) %eax) +20745 (write-buffered *(ebp+0x10) ": 'stream' elements not allowed for now\n") +20746 (flush *(ebp+0x10)) +20747 (stop *(ebp+0x14) 1) +20748 # never gets here +20749 +20750 type-name: # index: int -> result/eax: (addr array byte) +20751 # . prologue +20752 55/push-ebp +20753 89/<- %ebp 4/r32/esp +20754 # +20755 (index Type-id *(ebp+8)) +20756 $type-name:end: +20757 # . epilogue +20758 89/<- %esp 5/r32/ebp +20759 5d/pop-to-ebp +20760 c3/return +20761 +20762 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) +20763 # . prologue +20764 55/push-ebp +20765 89/<- %ebp 4/r32/esp +20766 # . save registers +20767 56/push-esi +20768 # TODO: bounds-check index +20769 # esi = arr +20770 8b/-> *(ebp+8) 6/r32/esi +20771 # eax = index +20772 8b/-> *(ebp+0xc) 0/r32/eax +20773 # eax = *(arr + 12 + index) +20774 8b/-> *(esi+eax<<2+0xc) 0/r32/eax +20775 $index:end: +20776 # . restore registers +20777 5e/pop-to-esi +20778 # . epilogue +20779 89/<- %esp 5/r32/ebp +20780 5d/pop-to-ebp +20781 c3/return +20782 +20783 ####################################################### +20784 # Compute type sizes +20785 ####################################################### +20786 +20787 # Compute the sizes of all user-defined types. +20788 # We'll need the sizes of their elements, which may be other user-defined +20789 # types, which we will compute as needed. +20790 +20791 # Initially, all user-defined types have their sizes set to -2 (invalid) +20792 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor) +20793 # . prologue +20794 55/push-ebp +20795 89/<- %ebp 4/r32/esp +20796 $populate-mu-type-sizes:total-sizes: +20797 # var curr/eax: (addr typeinfo) = lookup(Program->types) +20798 (lookup *_Program-types *_Program-types->payload) # => eax +20799 { +20800 # if (curr == null) break +20801 3d/compare-eax-and 0/imm32/null +20802 74/jump-if-= break/disp8 +20803 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc)) +20804 # curr = lookup(curr->next) +20805 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +20806 eb/jump loop/disp8 +20807 } +20808 $populate-mu-type-sizes:offsets: +20809 # curr = *Program->types +20810 (lookup *_Program-types *_Program-types->payload) # => eax +20811 { +20812 # if (curr == null) break +20813 3d/compare-eax-and 0/imm32/null +20814 74/jump-if-= break/disp8 +20815 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc)) +20816 # curr = curr->next +20817 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +20818 eb/jump loop/disp8 +20819 } +20820 $populate-mu-type-sizes:end: +20821 # . epilogue +20822 89/<- %esp 5/r32/ebp +20823 5d/pop-to-ebp +20824 c3/return +20825 +20826 # compute sizes of all fields, recursing as necessary +20827 # sum up all their sizes to arrive at total size +20828 # fields may be out of order, but that doesn't affect the answer +20829 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +20830 # . prologue +20831 55/push-ebp +20832 89/<- %ebp 4/r32/esp +20833 # . save registers +20834 50/push-eax +20835 51/push-ecx +20836 52/push-edx +20837 56/push-esi +20838 57/push-edi +20839 # esi = T +20840 8b/-> *(ebp+8) 6/r32/esi +20841 # if T is already computed, return +20842 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes +20843 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 +20844 # if T is being computed, abort +20845 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes +20846 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 +20847 # tag T (-2 to -1) to avoid infinite recursion +20848 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes +20849 # var total-size/edi: int = 0 +20850 bf/copy-to-edi 0/imm32 +20851 # - for every field, if it's a user-defined type, compute its size +20852 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) +20853 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax +20854 89/<- %ecx 0/r32/eax +20855 # var table-size/edx: int = table->write +20856 8b/-> *ecx 2/r32/edx # stream-write +20857 # var curr/ecx: (addr table_row) = table->data +20858 8d/copy-address *(ecx+0xc) 1/r32/ecx +20859 # var max/edx: (addr table_row) = table->data + table->write +20860 8d/copy-address *(ecx+edx) 2/r32/edx +20861 { +20862 $populate-mu-type-sizes-in-type:loop: +20863 # if (curr >= max) break +20864 39/compare %ecx 2/r32/edx +20865 73/jump-if-addr>= break/disp8 +20866 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) +20867 (lookup *(ecx+8) *(ecx+0xc)) # => eax +20868 # if (t->input-var == 0) silently ignore it; we'll emit a nice error message while type-checking +20869 81 7/subop/compare *eax 0/imm32 # Typeinfo-entry-input-var +20870 74/jump-if-= $populate-mu-type-sizes-in-type:end/disp8 +20871 # compute size of t->input-var +20872 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +20873 (compute-size-of-var %eax *(ebp+0xc) *(ebp+0x10)) # => eax +20874 # result += eax +20875 01/add-to %edi 0/r32/eax +20876 # curr += row-size +20877 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size +20878 # +20879 eb/jump loop/disp8 +20880 } +20881 # - save result +20882 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes +20883 $populate-mu-type-sizes-in-type:end: +20884 # . restore registers +20885 5f/pop-to-edi +20886 5e/pop-to-esi +20887 5a/pop-to-edx +20888 59/pop-to-ecx +20889 58/pop-to-eax +20890 # . epilogue +20891 89/<- %esp 5/r32/ebp +20892 5d/pop-to-ebp +20893 c3/return +20894 +20895 $populate-mu-type-sizes-in-type:abort: +20896 (write-buffered *(ebp+0xc) "cycle in type definitions\n") +20897 (flush *(ebp+0xc)) +20898 (stop *(ebp+0x10) 1) +20899 # never gets here +20900 +20901 # Analogous to size-of, except we need to compute what size-of can just read +20902 # off the right data structures. +20903 compute-size-of-var: # in: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +20904 # . prologue +20905 55/push-ebp +20906 89/<- %ebp 4/r32/esp +20907 # . push registers +20908 51/push-ecx +20909 # var t/ecx: (addr type-tree) = lookup(v->type) +20910 8b/-> *(ebp+8) 1/r32/ecx +20911 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +20912 89/<- %ecx 0/r32/eax +20913 # if (t->is-atom == false) t = lookup(t->left) +20914 { +20915 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +20916 75/jump-if-!= break/disp8 +20917 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +20918 89/<- %ecx 0/r32/eax +20919 } +20920 # TODO: ensure t is an atom +20921 (compute-size-of-type-id *(ecx+4) *(ebp+0xc) *(ebp+0x10)) # Type-tree-value => eax +20922 $compute-size-of-var:end: +20923 # . restore registers +20924 59/pop-to-ecx +20925 # . epilogue +20926 89/<- %esp 5/r32/ebp +20927 5d/pop-to-ebp +20928 c3/return +20929 +20930 compute-size-of-type-id: # t: type-id, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +20931 # . prologue +20932 55/push-ebp +20933 89/<- %ebp 4/r32/esp +20934 # . save registers +20935 51/push-ecx +20936 # var out/ecx: (handle typeinfo) +20937 68/push 0/imm32 +20938 68/push 0/imm32 +20939 89/<- %ecx 4/r32/esp +20940 # eax = t +20941 8b/-> *(ebp+8) 0/r32/eax +20942 # if t is a literal, return 0 +20943 3d/compare-eax-and 0/imm32/literal +20944 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int +20945 # if t is a byte, return 4 (because we don't really support non-multiples of 4) +20946 3d/compare-eax-and 8/imm32/byte +20947 { +20948 75/jump-if-!= break/disp8 +20949 b8/copy-to-eax 4/imm32 +20950 eb/jump $compute-size-of-type-id:end/disp8 +20951 } +20952 # if t is a handle, return 8 +20953 3d/compare-eax-and 4/imm32/handle +20954 { +20955 75/jump-if-!= break/disp8 +20956 b8/copy-to-eax 8/imm32 +20957 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int +20958 } +20959 # if t is a slice, return 8 +20960 3d/compare-eax-and 0xc/imm32/slice +20961 { +20962 75/jump-if-!= break/disp8 +20963 b8/copy-to-eax 8/imm32 +20964 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int +20965 } +20966 # if t is a user-defined type, compute its size +20967 # TODO: support non-atom type +20968 (find-typeinfo %eax %ecx) +20969 { +20970 81 7/subop/compare *ecx 0/imm32 +20971 74/jump-if-= break/disp8 +20972 $compute-size-of-type-id:user-defined: +20973 (lookup *ecx *(ecx+4)) # => eax +20974 (populate-mu-type-sizes-in-type %eax *(ebp+0xc) *(ebp+0x10)) +20975 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes +20976 eb/jump $compute-size-of-type-id:end/disp8 +20977 } +20978 # otherwise return the word size +20979 b8/copy-to-eax 4/imm32 +20980 $compute-size-of-type-id:end: +20981 # . reclaim locals +20982 81 0/subop/add %esp 8/imm32 +20983 # . restore registers +20984 59/pop-to-ecx +20985 # . epilogue +20986 89/<- %esp 5/r32/ebp +20987 5d/pop-to-ebp +20988 c3/return +20989 +20990 # at this point we have total sizes for all user-defined types +20991 # compute offsets for each element +20992 # complication: fields may be out of order +20993 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +20994 # . prologue +20995 55/push-ebp +20996 89/<- %ebp 4/r32/esp +20997 # . save registers +20998 50/push-eax +20999 51/push-ecx +21000 52/push-edx +21001 53/push-ebx +21002 56/push-esi +21003 57/push-edi +21004 #? (dump-typeinfos "aaa\n") +21005 # var curr-offset/edi: int = 0 +21006 bf/copy-to-edi 0/imm32 +21007 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) +21008 8b/-> *(ebp+8) 1/r32/ecx +21009 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax +21010 89/<- %ecx 0/r32/eax +21011 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size +21012 8b/-> *ecx 2/r32/edx # stream-write +21013 c1 5/subop/shift-right-logical %edx 4/imm8 +21014 # var i/ebx: int = 0 +21015 bb/copy-to-ebx 0/imm32 +21016 { +21017 $populate-mu-type-offsets:loop: +21018 39/compare %ebx 2/r32/edx +21019 0f 8d/jump-if->= break/disp32 +21020 #? (write-buffered Stderr "looking up index ") +21021 #? (write-int32-hex-buffered Stderr %ebx) +21022 #? (write-buffered Stderr " in ") +21023 #? (write-int32-hex-buffered Stderr *(ebp+8)) +21024 #? (write-buffered Stderr Newline) +21025 #? (flush Stderr) +21026 # var v/esi: (addr typeinfo-entry) +21027 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax +21028 89/<- %esi 0/r32/eax +21029 # if v is null, silently move on; we'll emit a nice error message while type-checking +21030 81 7/subop/compare %esi 0/imm32 # Typeinfo-entry-input-var +21031 74/jump-if-= $populate-mu-type-offsets:end/disp8 +21032 # if (v->input-var == 0) silently ignore v; we'll emit a nice error message while type-checking +21033 81 7/subop/compare *esi 0/imm32 # Typeinfo-entry-input-var +21034 74/jump-if-= $populate-mu-type-offsets:end/disp8 +21035 # v->output-var->offset = curr-offset +21036 # . eax: (addr var) +21037 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax +21038 89/<- *(eax+0x14) 7/r32/edi # Var-offset +21039 # curr-offset += size-of(v->input-var) +21040 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +21041 (size-of %eax) # => eax +21042 01/add-to %edi 0/r32/eax +21043 # ++i +21044 43/increment-ebx +21045 e9/jump loop/disp32 +21046 } +21047 $populate-mu-type-offsets:end: +21048 # . restore registers +21049 5f/pop-to-edi +21050 5e/pop-to-esi +21051 5b/pop-to-ebx +21052 5a/pop-to-edx +21053 59/pop-to-ecx +21054 58/pop-to-eax +21055 # . epilogue +21056 89/<- %esp 5/r32/ebp +21057 5d/pop-to-ebp +21058 c3/return +21059 +21060 locate-typeinfo-entry-with-index: # table: (addr table (handle array byte) (handle typeinfo-entry)), idx: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: (addr typeinfo-entry) +21061 # . prologue +21062 55/push-ebp +21063 89/<- %ebp 4/r32/esp +21064 # . save registers +21065 51/push-ecx +21066 52/push-edx +21067 53/push-ebx +21068 56/push-esi +21069 57/push-edi +21070 # esi = table +21071 8b/-> *(ebp+8) 6/r32/esi +21072 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data +21073 8d/copy-address *(esi+0xc) 1/r32/ecx +21074 # var max/edx: (addr byte) = &table->data[table->write] +21075 8b/-> *esi 2/r32/edx +21076 8d/copy-address *(ecx+edx) 2/r32/edx +21077 { +21078 $locate-typeinfo-entry-with-index:loop: +21079 39/compare %ecx 2/r32/edx +21080 73/jump-if-addr>= break/disp8 +21081 # var v/eax: (addr typeinfo-entry) +21082 (lookup *(ecx+8) *(ecx+0xc)) # => eax +21083 # if (v->index == idx) return v +21084 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index +21085 #? (write-buffered Stderr "comparing ") +21086 #? (write-int32-hex-buffered Stderr %ebx) +21087 #? (write-buffered Stderr " and ") +21088 #? (write-int32-hex-buffered Stderr *(ebp+0xc)) +21089 #? (write-buffered Stderr Newline) +21090 #? (flush Stderr) +21091 39/compare *(ebp+0xc) 3/r32/ebx +21092 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 +21093 # curr += Typeinfo-entry-size +21094 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size +21095 # +21096 eb/jump loop/disp8 +21097 } +21098 # return 0 +21099 b8/copy-to-eax 0/imm32 +21100 $locate-typeinfo-entry-with-index:end: +21101 #? (write-buffered Stderr "returning ") +21102 #? (write-int32-hex-buffered Stderr %eax) +21103 #? (write-buffered Stderr Newline) +21104 #? (flush Stderr) +21105 # . restore registers +21106 5f/pop-to-edi +21107 5e/pop-to-esi +21108 5b/pop-to-ebx +21109 5a/pop-to-edx +21110 59/pop-to-ecx +21111 # . epilogue +21112 89/<- %esp 5/r32/ebp +21113 5d/pop-to-ebp +21114 c3/return +21115 +21116 dump-typeinfos: # hdr: (addr array byte) +21117 # . prologue +21118 55/push-ebp +21119 89/<- %ebp 4/r32/esp +21120 # . save registers +21121 50/push-eax +21122 # +21123 (write-buffered Stderr *(ebp+8)) +21124 (flush Stderr) +21125 # var curr/eax: (addr typeinfo) = lookup(Program->types) +21126 (lookup *_Program-types *_Program-types->payload) # => eax +21127 { +21128 # if (curr == null) break +21129 3d/compare-eax-and 0/imm32 +21130 74/jump-if-= break/disp8 +21131 (write-buffered Stderr "---\n") +21132 (flush Stderr) +21133 (dump-typeinfo %eax) +21134 # curr = lookup(curr->next) +21135 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +21136 eb/jump loop/disp8 +21137 } +21138 $dump-typeinfos:end: +21139 # . restore registers +21140 58/pop-to-eax +21141 # . epilogue +21142 89/<- %esp 5/r32/ebp +21143 5d/pop-to-ebp +21144 c3/return +21145 +21146 dump-typeinfo: # in: (addr typeinfo) +21147 # . prologue +21148 55/push-ebp +21149 89/<- %ebp 4/r32/esp +21150 # . save registers +21151 50/push-eax +21152 51/push-ecx +21153 52/push-edx +21154 53/push-ebx +21155 56/push-esi +21156 57/push-edi +21157 # esi = in +21158 8b/-> *(ebp+8) 6/r32/esi +21159 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) +21160 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax +21161 89/<- %ecx 0/r32/eax +21162 (write-buffered Stderr "id:") +21163 (write-int32-hex-buffered Stderr *esi) +21164 (write-buffered Stderr "\n") +21165 (write-buffered Stderr "fields @ ") +21166 (write-int32-hex-buffered Stderr %ecx) +21167 (write-buffered Stderr Newline) +21168 (flush Stderr) +21169 (write-buffered Stderr " write: ") +21170 (write-int32-hex-buffered Stderr *ecx) +21171 (write-buffered Stderr Newline) +21172 (flush Stderr) +21173 (write-buffered Stderr " read: ") +21174 (write-int32-hex-buffered Stderr *(ecx+4)) +21175 (write-buffered Stderr Newline) +21176 (flush Stderr) +21177 (write-buffered Stderr " size: ") +21178 (write-int32-hex-buffered Stderr *(ecx+8)) +21179 (write-buffered Stderr Newline) +21180 (flush Stderr) +21181 # var table-size/edx: int = table->write +21182 8b/-> *ecx 2/r32/edx # stream-write +21183 # var curr/ecx: (addr table_row) = table->data +21184 8d/copy-address *(ecx+0xc) 1/r32/ecx +21185 # var max/edx: (addr table_row) = table->data + table->write +21186 8d/copy-address *(ecx+edx) 2/r32/edx +21187 { +21188 $dump-typeinfo:loop: +21189 # if (curr >= max) break +21190 39/compare %ecx 2/r32/edx +21191 0f 83/jump-if-addr>= break/disp32 +21192 (write-buffered Stderr " row:\n") +21193 (write-buffered Stderr " key: ") +21194 (write-int32-hex-buffered Stderr *ecx) +21195 (write-buffered Stderr ",") +21196 (write-int32-hex-buffered Stderr *(ecx+4)) +21197 (write-buffered Stderr " = '") +21198 (lookup *ecx *(ecx+4)) +21199 (write-buffered Stderr %eax) +21200 (write-buffered Stderr "' @ ") +21201 (write-int32-hex-buffered Stderr %eax) +21202 (write-buffered Stderr Newline) +21203 (flush Stderr) +21204 (write-buffered Stderr " value: ") +21205 (write-int32-hex-buffered Stderr *(ecx+8)) +21206 (write-buffered Stderr ",") +21207 (write-int32-hex-buffered Stderr *(ecx+0xc)) +21208 (write-buffered Stderr " = typeinfo-entry@") +21209 (lookup *(ecx+8) *(ecx+0xc)) +21210 (write-int32-hex-buffered Stderr %eax) +21211 (write-buffered Stderr Newline) +21212 (flush Stderr) +21213 (write-buffered Stderr " input var@") +21214 (dump-var 5 %eax) +21215 (lookup *(ecx+8) *(ecx+0xc)) +21216 (write-buffered Stderr " index: ") +21217 (write-int32-hex-buffered Stderr *(eax+8)) +21218 (write-buffered Stderr Newline) +21219 (flush Stderr) +21220 (write-buffered Stderr " output var@") +21221 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var +21222 (dump-var 5 %eax) +21223 (flush Stderr) +21224 # curr += row-size +21225 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size +21226 # +21227 e9/jump loop/disp32 +21228 } +21229 $dump-typeinfo:end: +21230 # . restore registers +21231 5f/pop-to-edi +21232 5e/pop-to-esi +21233 5b/pop-to-ebx +21234 5a/pop-to-edx +21235 59/pop-to-ecx +21236 58/pop-to-eax +21237 # . epilogue +21238 89/<- %esp 5/r32/ebp +21239 5d/pop-to-ebp +21240 c3/return +21241 +21242 dump-var: # indent: int, v: (addr handle var) +21243 # . prologue +21244 55/push-ebp +21245 89/<- %ebp 4/r32/esp +21246 # . save registers +21247 50/push-eax +21248 53/push-ebx +21249 # eax = v +21250 8b/-> *(ebp+0xc) 0/r32/eax +21251 # +21252 (write-int32-hex-buffered Stderr *eax) +21253 (write-buffered Stderr ",") +21254 (write-int32-hex-buffered Stderr *(eax+4)) +21255 (write-buffered Stderr "->") +21256 (lookup *eax *(eax+4)) +21257 (write-int32-hex-buffered Stderr %eax) +21258 (write-buffered Stderr Newline) +21259 (flush Stderr) +21260 { +21261 3d/compare-eax-and 0/imm32 +21262 0f 84/jump-if-= break/disp32 +21263 (emit-indent Stderr *(ebp+8)) +21264 (write-buffered Stderr "name: ") +21265 89/<- %ebx 0/r32/eax +21266 (write-int32-hex-buffered Stderr *ebx) # Var-name +21267 (write-buffered Stderr ",") +21268 (write-int32-hex-buffered Stderr *(ebx+4)) # Var-name +21269 (write-buffered Stderr "->") +21270 (lookup *ebx *(ebx+4)) # Var-name +21271 (write-int32-hex-buffered Stderr %eax) +21272 { +21273 3d/compare-eax-and 0/imm32 +21274 74/jump-if-= break/disp8 +21275 (write-buffered Stderr Space) +21276 (write-buffered Stderr %eax) +21277 } +21278 (write-buffered Stderr Newline) +21279 (flush Stderr) +21280 (emit-indent Stderr *(ebp+8)) +21281 (write-buffered Stderr "block depth: ") +21282 (write-int32-hex-buffered Stderr *(ebx+0x10)) # Var-block-depth +21283 (write-buffered Stderr Newline) +21284 (flush Stderr) +21285 (emit-indent Stderr *(ebp+8)) +21286 (write-buffered Stderr "stack offset: ") +21287 (write-int32-hex-buffered Stderr *(ebx+0x14)) # Var-offset +21288 (write-buffered Stderr Newline) +21289 (flush Stderr) +21290 (emit-indent Stderr *(ebp+8)) +21291 (write-buffered Stderr "reg: ") +21292 (write-int32-hex-buffered Stderr *(ebx+0x18)) # Var-register +21293 (write-buffered Stderr ",") +21294 (write-int32-hex-buffered Stderr *(ebx+0x1c)) # Var-register +21295 (write-buffered Stderr "->") +21296 (flush Stderr) +21297 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register +21298 (write-int32-hex-buffered Stderr %eax) +21299 { +21300 3d/compare-eax-and 0/imm32 +21301 74/jump-if-= break/disp8 +21302 (write-buffered Stderr Space) +21303 (write-buffered Stderr %eax) +21304 } +21305 (write-buffered Stderr Newline) +21306 (flush Stderr) +21307 } +21308 $dump-var:end: +21309 # . restore registers +21310 5b/pop-to-ebx +21311 58/pop-to-eax +21312 # . epilogue +21313 89/<- %esp 5/r32/ebp +21314 5d/pop-to-ebp +21315 c3/return +21316 +21317 ####################################################### +21318 # Type-checking +21319 ####################################################### +21320 +21321 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor) +21322 # . prologue +21323 55/push-ebp +21324 89/<- %ebp 4/r32/esp +21325 # . save registers +21326 50/push-eax +21327 # var curr/eax: (addr function) = lookup(Program->functions) +21328 (lookup *_Program-functions *_Program-functions->payload) # => eax +21329 { +21330 $check-mu-types:loop: +21331 # if (curr == null) break +21332 3d/compare-eax-and 0/imm32 +21333 0f 84/jump-if-= break/disp32 +21334 +-- 8 lines: #? # dump curr->name ------------------------------------------------------------------------------------------------------------------------------------------------ +21342 (check-mu-function %eax *(ebp+8) *(ebp+0xc)) +21343 # curr = lookup(curr->next) +21344 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax +21345 e9/jump loop/disp32 +21346 } +21347 $check-mu-types:end: +21348 # . restore registers +21349 58/pop-to-eax +21350 # . epilogue +21351 89/<- %esp 5/r32/ebp +21352 5d/pop-to-ebp +21353 c3/return +21354 +21355 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +21356 # . prologue +21357 55/push-ebp +21358 89/<- %ebp 4/r32/esp +21359 # . save registers +21360 50/push-eax +21361 56/push-esi +21362 # esi = f +21363 8b/-> *(ebp+8) 6/r32/esi +21364 # outputs +21365 (lookup *(esi+0x10) *(esi+0x14)) # Function-outputs Function-outputs => eax +21366 (check-all-unique-registers %eax %esi *(ebp+0xc) *(ebp+0x10)) +21367 # body +21368 (lookup *(esi+0x18) *(esi+0x1c)) # Function-body Function-body => eax +21369 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10)) +21370 # if function has no outputs, we're done +21371 81 7/subop/compare *(esi+0x10) 0/imm32 +21372 74/jump-if-= $check-mu-function:end/disp8 +21373 # some final checks on body +21374 (check-final-stmt-is-return %eax %esi *(ebp+0xc) *(ebp+0x10)) +21375 (check-no-breaks %eax %esi *(ebp+0xc) *(ebp+0x10)) +21376 $check-mu-function:end: +21377 # . restore registers +21378 5e/pop-to-esi +21379 58/pop-to-eax +21380 # . epilogue +21381 89/<- %esp 5/r32/ebp +21382 5d/pop-to-ebp +21383 c3/return +21384 +21385 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +21386 # . prologue +21387 55/push-ebp +21388 89/<- %ebp 4/r32/esp +21389 # . save registers +21390 50/push-eax +21391 # eax = block +21392 8b/-> *(ebp+8) 0/r32/eax +21393 # var stmts/eax: (addr list stmt) = lookup(block->statements) +21394 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax +21395 # +21396 { +21397 $check-mu-block:check-empty: +21398 3d/compare-eax-and 0/imm32 +21399 0f 84/jump-if-= break/disp32 +21400 # emit block->statements +21401 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21402 } +21403 $check-mu-block:end: +21404 # . restore registers +21405 58/pop-to-eax +21406 # . epilogue +21407 89/<- %esp 5/r32/ebp +21408 5d/pop-to-ebp +21409 c3/return +21410 +21411 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +21412 # . prologue +21413 55/push-ebp +21414 89/<- %ebp 4/r32/esp +21415 # . save registers +21416 50/push-eax +21417 56/push-esi +21418 # esi = stmts +21419 8b/-> *(ebp+8) 6/r32/esi +21420 { +21421 $check-mu-stmt-list:loop: +21422 81 7/subop/compare %esi 0/imm32 +21423 0f 84/jump-if-= break/disp32 +21424 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value) +21425 (lookup *esi *(esi+4)) # List-value List-value => eax +21426 { +21427 $check-mu-stmt-list:check-for-block: +21428 81 7/subop/compare *eax 0/imm32/block # Stmt-tag +21429 75/jump-if-!= break/disp8 +21430 $check-mu-stmt-list:block: +21431 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21432 eb/jump $check-mu-stmt-list:continue/disp8 +21433 } +21434 { +21435 $check-mu-stmt-list:check-for-stmt1: +21436 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag +21437 0f 85/jump-if-!= break/disp32 +21438 $check-mu-stmt-list:stmt1: +21439 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21440 eb/jump $check-mu-stmt-list:continue/disp8 +21441 } +21442 { +21443 $check-mu-stmt-list:check-for-reg-var-def: +21444 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag +21445 0f 85/jump-if-!= break/disp32 +21446 $check-mu-stmt-list:reg-var-def: +21447 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21448 eb/jump $check-mu-stmt-list:continue/disp8 +21449 } +21450 $check-mu-stmt-list:continue: +21451 # TODO: raise an error on unrecognized Stmt-tag +21452 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax +21453 89/<- %esi 0/r32/eax +21454 e9/jump loop/disp32 21455 } -21456 # - otherwise find a function to check against -21457 # var f/eax: (addr function) = lookup(*Program->functions) -21458 (lookup *_Program-functions *_Program-functions->payload) # => eax -21459 (find-matching-function %eax *(ebp+8)) # => eax -21460 3d/compare-eax-and 0/imm32 -21461 { -21462 74/jump-if-= break/disp8 -21463 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21464 eb/jump $check-mu-stmt:end/disp8 -21465 } -21466 # var f/eax: (addr function) = lookup(*Program->signatures) -21467 (lookup *_Program-signatures *_Program-signatures->payload) # => eax -21468 (find-matching-function %eax *(ebp+8)) # => eax -21469 3d/compare-eax-and 0/imm32 -21470 { -21471 74/jump-if-= break/disp8 -21472 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21473 eb/jump $check-mu-stmt:end/disp8 -21474 } -21475 # - otherwise abort -21476 e9/jump $check-mu-stmt:unknown-call/disp32 -21477 $check-mu-stmt:end: -21478 # . restore registers -21479 58/pop-to-eax -21480 # . epilogue -21481 89/<- %esp 5/r32/ebp -21482 5d/pop-to-ebp -21483 c3/return -21484 -21485 $check-mu-stmt:unknown-call: -21486 (write-buffered *(ebp+0x10) "unknown function '") -21487 8b/-> *(ebp+8) 0/r32/eax -21488 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -21489 (write-buffered *(ebp+0x10) %eax) -21490 (write-buffered *(ebp+0x10) "'\n") -21491 (flush *(ebp+0x10)) -21492 (stop *(ebp+0x14) 1) -21493 # never gets here -21494 -21495 has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean -21496 # . prologue -21497 55/push-ebp -21498 89/<- %ebp 4/r32/esp -21499 # . save registers -21500 51/push-ecx -21501 56/push-esi -21502 # var name/esi: (addr array byte) = lookup(stmt->operation) -21503 8b/-> *(ebp+8) 6/r32/esi -21504 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -21505 89/<- %esi 0/r32/eax -21506 # if (name == "return") return true -21507 (string-equal? %esi "return") # => eax -21508 3d/compare-eax-and 0/imm32/false -21509 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21510 # if (name == "get") return true -21511 (string-equal? %esi "get") # => eax -21512 3d/compare-eax-and 0/imm32/false -21513 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21514 # if (name == "index") return true -21515 (string-equal? %esi "index") # => eax -21516 3d/compare-eax-and 0/imm32/false -21517 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21518 # if (name == "length") return true -21519 (string-equal? %esi "length") # => eax -21520 3d/compare-eax-and 0/imm32/false -21521 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21522 # if (name == "compute-offset") return true -21523 (string-equal? %esi "compute-offset") # => eax -21524 3d/compare-eax-and 0/imm32/false -21525 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21526 # if (name == "copy-object") return true -21527 (string-equal? %esi "copy-object") # => eax -21528 3d/compare-eax-and 0/imm32/false -21529 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21530 # if (name == "clear-object") return true -21531 (string-equal? %esi "clear-object") # => eax -21532 3d/compare-eax-and 0/imm32/false -21533 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21534 # if (name == "allocate") return true -21535 (string-equal? %esi "allocate") # => eax -21536 3d/compare-eax-and 0/imm32/false -21537 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21538 # if (name == "populate") return true -21539 (string-equal? %esi "populate") # => eax -21540 3d/compare-eax-and 0/imm32/false -21541 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21542 # if (name == "populate-stream") return true -21543 (string-equal? %esi "populate-stream") # => eax -21544 3d/compare-eax-and 0/imm32/false -21545 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21546 # if (name == "read-from-stream") return true -21547 (string-equal? %esi "read-from-stream") # => eax -21548 3d/compare-eax-and 0/imm32/false -21549 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21550 # if (name == "write-to-stream") return true -21551 (string-equal? %esi "write-to-stream") # => eax -21552 3d/compare-eax-and 0/imm32/false -21553 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -21554 # var curr/ecx: (addr primitive) = Primitives -21555 b9/copy-to-ecx Primitives/imm32 -21556 { -21557 $has-primitive-name?:loop: -21558 # if (curr == null) break -21559 81 7/subop/compare %ecx 0/imm32 -21560 74/jump-if-= break/disp8 -21561 # if (primitive->name == name) return true -21562 (lookup *ecx *(ecx+4)) # Primitive-name Primitive-name => eax -21563 #? (write-buffered Stderr %eax) -21564 #? (write-buffered Stderr Newline) -21565 #? (flush Stderr) -21566 (string-equal? %esi %eax) # => eax -21567 3d/compare-eax-and 0/imm32/false -21568 75/jump-if-!= $has-primitive-name?:end/disp8 -21569 $has-primitive-name?:next-primitive: -21570 # curr = curr->next -21571 (lookup *(ecx+0x3c) *(ecx+0x40)) # Primitive-next Primitive-next => eax -21572 89/<- %ecx 0/r32/eax -21573 # -21574 e9/jump loop/disp32 -21575 } -21576 # return null -21577 b8/copy-to-eax 0/imm32 -21578 $has-primitive-name?:end: -21579 # . restore registers -21580 5e/pop-to-esi -21581 59/pop-to-ecx -21582 # . epilogue -21583 89/<- %esp 5/r32/ebp -21584 5d/pop-to-ebp -21585 c3/return -21586 -21587 check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -21588 # . prologue -21589 55/push-ebp -21590 89/<- %ebp 4/r32/esp -21591 # . save registers -21592 50/push-eax -21593 51/push-ecx -21594 # var op/ecx: (addr array byte) = lookup(stmt->operation) -21595 8b/-> *(ebp+8) 0/r32/eax -21596 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -21597 89/<- %ecx 0/r32/eax -21598 # if (op == "copy") check-mu-copy-stmt -21599 { -21600 (string-equal? %ecx "copy") # => eax -21601 3d/compare-eax-and 0/imm32/false -21602 74/jump-if-= break/disp8 -21603 (check-mu-copy-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21604 e9/jump $check-mu-primitive:end/disp32 -21605 } -21606 # if (op == "copy-to") check-mu-copy-to-stmt -21607 { -21608 (string-equal? %ecx "copy-to") # => eax -21609 3d/compare-eax-and 0/imm32/false -21610 74/jump-if-= break/disp8 -21611 (check-mu-copy-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21612 e9/jump $check-mu-primitive:end/disp32 -21613 } -21614 # if (op == "copy-byte") check-mu-copy-byte-stmt -21615 { -21616 (string-equal? %ecx "copy-byte") # => eax -21617 3d/compare-eax-and 0/imm32/false -21618 74/jump-if-= break/disp8 -21619 (check-mu-copy-byte-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21620 e9/jump $check-mu-primitive:end/disp32 -21621 } -21622 # if (op == "copy-byte-to") check-mu-copy-byte-to-stmt -21623 { -21624 (string-equal? %ecx "copy-byte-to") # => eax -21625 3d/compare-eax-and 0/imm32/false -21626 74/jump-if-= break/disp8 -21627 (check-mu-copy-byte-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21628 e9/jump $check-mu-primitive:end/disp32 -21629 } -21630 # if (op == "compare") check-mu-compare-stmt -21631 { -21632 (string-equal? %ecx "compare") # => eax -21633 3d/compare-eax-and 0/imm32/false -21634 74/jump-if-= break/disp8 -21635 (check-mu-compare-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21636 e9/jump $check-mu-primitive:end/disp32 -21637 } -21638 # if (op == "address") check-mu-address-stmt -21639 { -21640 (string-equal? %ecx "address") # => eax -21641 3d/compare-eax-and 0/imm32/false -21642 74/jump-if-= break/disp8 -21643 (check-mu-address-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21644 e9/jump $check-mu-primitive:end/disp32 -21645 } -21646 # if (op == "return") check-mu-return-stmt -21647 { -21648 (string-equal? %ecx "return") # => eax -21649 3d/compare-eax-and 0/imm32/false -21650 74/jump-if-= break/disp8 -21651 (check-mu-return-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21652 e9/jump $check-mu-primitive:end/disp32 -21653 } -21654 # if (op == "get") check-mu-get-stmt -21655 { -21656 (string-equal? %ecx "get") # => eax -21657 3d/compare-eax-and 0/imm32/false -21658 74/jump-if-= break/disp8 -21659 (check-mu-get-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21660 e9/jump $check-mu-primitive:end/disp32 -21661 } -21662 # if (op == "index") check-mu-index-stmt -21663 { -21664 (string-equal? %ecx "index") # => eax -21665 3d/compare-eax-and 0/imm32/false -21666 74/jump-if-= break/disp8 -21667 (check-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21668 e9/jump $check-mu-primitive:end/disp32 -21669 } -21670 # if (op == "length") check-mu-length-stmt -21671 { -21672 (string-equal? %ecx "length") # => eax -21673 3d/compare-eax-and 0/imm32/false -21674 74/jump-if-= break/disp8 -21675 (check-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21676 e9/jump $check-mu-primitive:end/disp32 -21677 } -21678 # if (op == "compute-offset") check-mu-compute-offset-stmt -21679 { -21680 (string-equal? %ecx "compute-offset") # => eax -21681 3d/compare-eax-and 0/imm32/false -21682 74/jump-if-= break/disp8 -21683 (check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21684 e9/jump $check-mu-primitive:end/disp32 -21685 } -21686 # if (op == "copy-object") check-mu-copy-object-stmt -21687 { -21688 (string-equal? %ecx "copy-object") # => eax -21689 3d/compare-eax-and 0/imm32/false -21690 74/jump-if-= break/disp8 -21691 (check-mu-copy-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21692 e9/jump $check-mu-primitive:end/disp32 -21693 } -21694 # if (op == "clear-object") check-mu-clear-object-stmt -21695 { -21696 (string-equal? %ecx "clear-object") # => eax -21697 3d/compare-eax-and 0/imm32/false -21698 74/jump-if-= break/disp8 -21699 (check-mu-clear-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21700 e9/jump $check-mu-primitive:end/disp32 -21701 } -21702 # if (op == "allocate") check-mu-allocate-stmt -21703 { -21704 (string-equal? %ecx "allocate") # => eax -21705 3d/compare-eax-and 0/imm32/false -21706 74/jump-if-= break/disp8 -21707 (check-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21708 e9/jump $check-mu-primitive:end/disp32 -21709 } -21710 # if (op == "populate") check-mu-populate-stmt -21711 { -21712 (string-equal? %ecx "populate") # => eax -21713 3d/compare-eax-and 0/imm32/false -21714 74/jump-if-= break/disp8 -21715 (check-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21716 e9/jump $check-mu-primitive:end/disp32 -21717 } -21718 # if (op == "populate-stream") check-mu-populate-stream-stmt -21719 { -21720 (string-equal? %ecx "populate-stream") # => eax -21721 3d/compare-eax-and 0/imm32/false -21722 74/jump-if-= break/disp8 -21723 (check-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21724 e9/jump $check-mu-primitive:end/disp32 -21725 } -21726 # if (op == "read-from-stream") check-mu-read-from-stream-stmt -21727 { -21728 (string-equal? %ecx "read-from-stream") # => eax -21729 3d/compare-eax-and 0/imm32/false -21730 74/jump-if-= break/disp8 -21731 (check-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21732 e9/jump $check-mu-primitive:end/disp32 -21733 } -21734 # if (op == "write-to-stream") check-mu-write-to-stream-stmt -21735 { -21736 (string-equal? %ecx "write-to-stream") # => eax -21737 3d/compare-eax-and 0/imm32/false -21738 74/jump-if-= break/disp8 -21739 (check-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21740 e9/jump $check-mu-primitive:end/disp32 -21741 } -21742 # if (op == "convert") check-mu-convert-stmt -21743 { -21744 (string-equal? %ecx "convert") # => eax -21745 3d/compare-eax-and 0/imm32/false -21746 74/jump-if-= break/disp8 -21747 (check-mu-convert-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21748 e9/jump $check-mu-primitive:end/disp32 -21749 } -21750 # otherwise check-numberlike-stmt -21751 (check-mu-numberlike-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21752 $check-mu-primitive:end: -21753 # . restore registers -21754 59/pop-to-ecx -21755 58/pop-to-eax -21756 # . epilogue -21757 89/<- %esp 5/r32/ebp -21758 5d/pop-to-ebp -21759 c3/return -21760 -21761 # by default, Mu primitives should only operate on 'number-like' types -21762 check-mu-numberlike-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -21763 # . prologue -21764 55/push-ebp -21765 89/<- %ebp 4/r32/esp -21766 # . save registers -21767 50/push-eax -21768 51/push-ecx -21769 56/push-esi -21770 # esi = stmt -21771 8b/-> *(ebp+8) 6/r32/esi -21772 # var gas/ecx: int = 2 -21773 b9/copy-to-ecx 2/imm32 -21774 # - check at most 1 output -21775 # var output/eax: (addr stmt-var) = stmt->outputs -21776 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -21777 { -21778 3d/compare-eax-and 0/imm32 -21779 74/jump-if-= break/disp8 -21780 $check-mu-numberlike-primitive:output: -21781 (check-mu-numberlike-output %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21782 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -21783 3d/compare-eax-and 0/imm32 -21784 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-outputs/disp32 -21785 # check output is in a register -21786 # --gas -21787 49/decrement-ecx -21788 } -21789 # - check first inout -21790 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -21791 { -21792 3d/compare-eax-and 0/imm32 -21793 0f 84/jump-if-= $check-mu-numberlike-primitive:end/disp32 -21794 $check-mu-numberlike-primitive:first-inout: -21795 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21796 # --gas -21797 49/decrement-ecx -21798 } -21799 # - check second inout -21800 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -21801 { -21802 3d/compare-eax-and 0/imm32 -21803 74/jump-if-= $check-mu-numberlike-primitive:end/disp8 -21804 $check-mu-numberlike-primitive:second-inout: -21805 # is a second inout allowed? -21806 81 7/subop/compare %ecx 0/imm32 -21807 0f 84/jump-if-= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 -21808 $check-mu-numberlike-primitive:second-inout-permitted: -21809 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -21810 } -21811 $check-mu-numberlike-primitive:third-inout: -21812 # if there's a third arg, raise an error -21813 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next -21814 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 -21815 $check-mu-numberlike-primitive:end: -21816 # . restore registers -21817 5e/pop-to-esi -21818 59/pop-to-ecx -21819 58/pop-to-eax -21820 # . epilogue -21821 89/<- %esp 5/r32/ebp -21822 5d/pop-to-ebp -21823 c3/return -21824 -21825 $check-mu-numberlike-primitive:error-too-many-inouts: -21826 (write-buffered *(ebp+0x10) "fn ") -21827 8b/-> *(ebp+0xc) 0/r32/eax -21828 (lookup *eax *(eax+4)) # Function-name Function-name => eax -21829 (write-buffered *(ebp+0x10) %eax) -21830 (write-buffered *(ebp+0x10) ": stmt ") -21831 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -21832 (write-buffered *(ebp+0x10) %eax) -21833 (write-buffered *(ebp+0x10) ": too many inouts; most primitives support at most two arguments, across inouts and outputs\n") -21834 (flush *(ebp+0x10)) -21835 (stop *(ebp+0x14) 1) -21836 # never gets here -21837 -21838 $check-mu-numberlike-primitive:error-too-many-outputs: -21839 (write-buffered *(ebp+0x10) "fn ") -21840 8b/-> *(ebp+0xc) 0/r32/eax -21841 (lookup *eax *(eax+4)) # Function-name Function-name => eax -21842 (write-buffered *(ebp+0x10) %eax) -21843 (write-buffered *(ebp+0x10) ": stmt ") -21844 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -21845 (write-buffered *(ebp+0x10) %eax) -21846 (write-buffered *(ebp+0x10) ": too many outputs; most primitives support at most one output\n") -21847 (flush *(ebp+0x10)) -21848 (stop *(ebp+0x14) 1) -21849 # never gets here -21850 -21851 check-mu-numberlike-arg: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -21852 # . prologue -21853 55/push-ebp -21854 89/<- %ebp 4/r32/esp -21855 # . save registers -21856 50/push-eax -21857 56/push-esi -21858 # var t/esi: (addr type-tree) = lookup(v->value->type) -21859 8b/-> *(ebp+8) 0/r32/eax -21860 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -21861 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -21862 89/<- %esi 0/r32/eax -21863 $check-mu-numberlike-arg:check-literal: -21864 # if t is an int, return -21865 (simple-mu-type? %esi 0) # literal => eax -21866 3d/compare-eax-and 0/imm32/false -21867 0f 85/jump-if-!= $check-mu-numberlike-arg:end/disp32 -21868 $check-mu-numberlike-arg:check-addr: -21869 # if t is an addr and v is dereferenced, return whether t->payload is an addr -21870 { -21871 (mu-addr-type? %esi) # => eax -21872 3d/compare-eax-and 0/imm32/false -21873 74/jump-if-= break/disp8 -21874 8b/-> *(ebp+8) 0/r32/eax -21875 8b/-> *(eax+0x10) 0/r32/eax # Stmt-var-is-deref -21876 3d/compare-eax-and 0/imm32/false -21877 { -21878 74/jump-if-= break/disp8 -21879 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax -21880 # if t->right is null, t = t->left -21881 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -21882 { -21883 75/jump-if-!= break/disp8 -21884 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -21885 } -21886 (mu-addr-type? %eax) # => eax -21887 3d/compare-eax-and 0/imm32/false -21888 74/jump-if-= $check-mu-numberlike-arg:end/disp8 -21889 } -21890 } -21891 $check-mu-numberlike-arg:output-checks: -21892 (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) -21893 $check-mu-numberlike-arg:end: -21894 # . restore registers -21895 5e/pop-to-esi -21896 58/pop-to-eax -21897 # . epilogue -21898 89/<- %esp 5/r32/ebp -21899 5d/pop-to-ebp -21900 c3/return -21901 -21902 check-mu-numberlike-output: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -21903 # . prologue -21904 55/push-ebp -21905 89/<- %ebp 4/r32/esp -21906 # . save registers -21907 50/push-eax -21908 # -21909 (mu-numberlike-output-var? *(ebp+8)) # => eax -21910 3d/compare-eax-and 0/imm32/false -21911 0f 84/jump-if-= $check-mu-numberlike-output:fail/disp32 -21912 $check-mu-numberlike-output:end: -21913 # . restore registers -21914 58/pop-to-eax -21915 # . epilogue -21916 89/<- %esp 5/r32/ebp -21917 5d/pop-to-ebp -21918 c3/return -21919 -21920 $check-mu-numberlike-output:fail: -21921 # otherwise raise an error -21922 (write-buffered *(ebp+0x14) "fn ") -21923 8b/-> *(ebp+0x10) 0/r32/eax -21924 (lookup *eax *(eax+4)) # Function-name Function-name => eax -21925 (write-buffered *(ebp+0x14) %eax) -21926 (write-buffered *(ebp+0x14) ": stmt ") -21927 8b/-> *(ebp+0xc) 0/r32/eax -21928 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -21929 (write-buffered *(ebp+0x14) %eax) -21930 (write-buffered *(ebp+0x14) ": '") -21931 8b/-> *(ebp+8) 0/r32/eax -21932 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -21933 (lookup *eax *(eax+4)) # Var-name Var-name => eax -21934 (write-buffered *(ebp+0x14) %eax) -21935 (write-buffered *(ebp+0x14) "' must be a non-addr non-offset scalar\n") -21936 (flush *(ebp+0x14)) -21937 (stop *(ebp+0x18) 1) -21938 # never gets here -21939 -21940 mu-numberlike-output-var?: # v: (addr stmt-var) -> result/eax: boolean -21941 # . prologue -21942 55/push-ebp -21943 89/<- %ebp 4/r32/esp -21944 # -21945 8b/-> *(ebp+8) 0/r32/eax -21946 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -21947 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -21948 (mu-numberlike-output? %eax) # => eax -21949 $mu-numberlike-output-var?:end: -21950 # . epilogue -21951 89/<- %esp 5/r32/ebp -21952 5d/pop-to-ebp -21953 c3/return -21954 -21955 mu-numberlike-output?: # v: (addr type-tree) -> result/eax: boolean -21956 # . prologue -21957 55/push-ebp -21958 89/<- %ebp 4/r32/esp -21959 # . save registers -21960 56/push-esi -21961 # var t/esi: (addr type-tree) = lookup(v->value->type) -21962 8b/-> *(ebp+8) 6/r32/esi -21963 $mu-numberlike-output?:check-int: -21964 # if t is an int, return -21965 (simple-mu-type? %esi 1) # int => eax -21966 3d/compare-eax-and 0/imm32/false -21967 0f 85/jump-if-!= $mu-numberlike-output?:return-true/disp32 -21968 $mu-numberlike-output?:check-float: -21969 # if t is a float, return -21970 (simple-mu-type? %esi 0xf) # float => eax -21971 3d/compare-eax-and 0/imm32/false -21972 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 -21973 $mu-numberlike-output?:check-boolean: -21974 # if t is a boolean, return -21975 (simple-mu-type? %esi 5) # boolean => eax -21976 3d/compare-eax-and 0/imm32/false -21977 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 -21978 $mu-numberlike-output?:check-byte: -21979 # if t is a byte, return -21980 (simple-mu-type? %esi 8) # byte => eax -21981 3d/compare-eax-and 0/imm32/false -21982 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 -21983 $mu-numberlike-output?:check-code-point: -21984 # if t is a code-point, return -21985 (simple-mu-type? %esi 0xd) # code-point => eax -21986 3d/compare-eax-and 0/imm32/false -21987 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 -21988 $mu-numberlike-output?:check-grapheme: -21989 # if t is a grapheme, return -21990 (simple-mu-type? %esi 0xe) # grapheme => eax -21991 3d/compare-eax-and 0/imm32/false -21992 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 -21993 $mu-numberlike-output?:return-false: -21994 b8/copy-to-eax 0/imm32/false -21995 eb/jump $mu-numberlike-output?:end/disp8 -21996 $mu-numberlike-output?:return-true: -21997 b8/copy-to-eax 1/imm32/true -21998 $mu-numberlike-output?:end: -21999 # . restore registers -22000 5e/pop-to-esi -22001 # . epilogue -22002 89/<- %esp 5/r32/ebp -22003 5d/pop-to-ebp -22004 c3/return -22005 -22006 check-mu-copy-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -22007 # . prologue -22008 55/push-ebp -22009 89/<- %ebp 4/r32/esp -22010 # . save registers -22011 50/push-eax -22012 51/push-ecx -22013 52/push-edx -22014 56/push-esi -22015 57/push-edi -22016 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) -22017 81 5/subop/subtract %esp 0x60/imm32 -22018 68/push 0x60/imm32/size -22019 68/push 0/imm32/read -22020 68/push 0/imm32/write -22021 89/<- %edx 4/r32/esp -22022 $check-mu-copy-stmt:get-output: -22023 # esi = stmt -22024 8b/-> *(ebp+8) 6/r32/esi -22025 # var output/edi: (addr stmt-var) = stmt->outputs -22026 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -22027 89/<- %edi 0/r32/eax -22028 # zero outputs -22029 3d/compare-eax-and 0/imm32 -22030 0f 84/jump-if-= $check-mu-copy-stmt:error-no-output/disp32 -22031 # > 1 output -22032 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -22033 3d/compare-eax-and 0/imm32 -22034 0f 85/jump-if-!= $check-mu-copy-stmt:error-too-many-outputs/disp32 -22035 $check-mu-copy-stmt:get-inout: -22036 # var inout/esi: (addr stmt-var) = stmt->inouts -22037 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -22038 89/<- %esi 0/r32/eax -22039 # zero inouts -22040 3d/compare-eax-and 0/imm32 -22041 0f 84/jump-if-= $check-mu-copy-stmt:error-no-inout/disp32 -22042 # > 1 inout -22043 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -22044 3d/compare-eax-and 0/imm32 -22045 0f 85/jump-if-!= $check-mu-copy-stmt:error-too-many-inouts/disp32 -22046 $check-mu-copy-stmt:types: -22047 # if inout is not a scalar, abort -22048 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22049 (size-of %eax) # => eax -22050 3d/compare-eax-and 4/imm32 -22051 0f 8f/jump-if-> $check-mu-copy-stmt:error-inout-too-large/disp32 -22052 # var inout-type/ecx: (addr type-tree) = inout->value->type -22053 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22054 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22055 89/<- %ecx 0/r32/eax -22056 # if (inout->is-deref?) inout-type = inout-type->payload -22057 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref -22058 3d/compare-eax-and 0/imm32/false -22059 { -22060 74/jump-if-= break/disp8 -22061 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -22062 # if inout-type->right is null, t = inout-type->left -22063 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -22064 { -22065 75/jump-if-!= break/disp8 -22066 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -22067 } -22068 89/<- %ecx 0/r32/eax -22069 } -22070 # if output not in register, abort -22071 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22072 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -22073 3d/compare-eax-and 0/imm32 -22074 0f 84/jump-if-= $check-mu-copy-stmt:error-output-not-in-register/disp32 -22075 # var output-type/eax: (addr type-tree) = output->value->type -22076 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +21456 $check-mu-stmt-list:end: +21457 # . restore registers +21458 5e/pop-to-esi +21459 58/pop-to-eax +21460 # . epilogue +21461 89/<- %esp 5/r32/ebp +21462 5d/pop-to-ebp +21463 c3/return +21464 +21465 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +21466 # . prologue +21467 55/push-ebp +21468 89/<- %ebp 4/r32/esp +21469 # . save registers +21470 50/push-eax +21471 # - if stmt's operation matches a primitive, check against it +21472 (has-primitive-name? *(ebp+8)) # => eax +21473 3d/compare-eax-and 0/imm32/false +21474 { +21475 74/jump-if-= break/disp8 +21476 (check-mu-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21477 e9/jump $check-mu-stmt:end/disp32 +21478 } +21479 # - otherwise find a function to check against +21480 # var f/eax: (addr function) = lookup(*Program->functions) +21481 (lookup *_Program-functions *_Program-functions->payload) # => eax +21482 (find-matching-function %eax *(ebp+8)) # => eax +21483 3d/compare-eax-and 0/imm32 +21484 { +21485 74/jump-if-= break/disp8 +21486 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21487 eb/jump $check-mu-stmt:end/disp8 +21488 } +21489 # var f/eax: (addr function) = lookup(*Program->signatures) +21490 (lookup *_Program-signatures *_Program-signatures->payload) # => eax +21491 (find-matching-function %eax *(ebp+8)) # => eax +21492 3d/compare-eax-and 0/imm32 +21493 { +21494 74/jump-if-= break/disp8 +21495 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21496 eb/jump $check-mu-stmt:end/disp8 +21497 } +21498 # - otherwise abort +21499 e9/jump $check-mu-stmt:unknown-call/disp32 +21500 $check-mu-stmt:end: +21501 # . restore registers +21502 58/pop-to-eax +21503 # . epilogue +21504 89/<- %esp 5/r32/ebp +21505 5d/pop-to-ebp +21506 c3/return +21507 +21508 $check-mu-stmt:unknown-call: +21509 (write-buffered *(ebp+0x10) "unknown function '") +21510 8b/-> *(ebp+8) 0/r32/eax +21511 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +21512 (write-buffered *(ebp+0x10) %eax) +21513 (write-buffered *(ebp+0x10) "'\n") +21514 (flush *(ebp+0x10)) +21515 (stop *(ebp+0x14) 1) +21516 # never gets here +21517 +21518 has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean +21519 # . prologue +21520 55/push-ebp +21521 89/<- %ebp 4/r32/esp +21522 # . save registers +21523 51/push-ecx +21524 56/push-esi +21525 # var name/esi: (addr array byte) = lookup(stmt->operation) +21526 8b/-> *(ebp+8) 6/r32/esi +21527 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +21528 89/<- %esi 0/r32/eax +21529 # if (name == "return") return true +21530 (string-equal? %esi "return") # => eax +21531 3d/compare-eax-and 0/imm32/false +21532 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21533 # if (name == "get") return true +21534 (string-equal? %esi "get") # => eax +21535 3d/compare-eax-and 0/imm32/false +21536 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21537 # if (name == "index") return true +21538 (string-equal? %esi "index") # => eax +21539 3d/compare-eax-and 0/imm32/false +21540 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21541 # if (name == "length") return true +21542 (string-equal? %esi "length") # => eax +21543 3d/compare-eax-and 0/imm32/false +21544 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21545 # if (name == "compute-offset") return true +21546 (string-equal? %esi "compute-offset") # => eax +21547 3d/compare-eax-and 0/imm32/false +21548 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21549 # if (name == "copy-object") return true +21550 (string-equal? %esi "copy-object") # => eax +21551 3d/compare-eax-and 0/imm32/false +21552 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21553 # if (name == "clear-object") return true +21554 (string-equal? %esi "clear-object") # => eax +21555 3d/compare-eax-and 0/imm32/false +21556 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21557 # if (name == "allocate") return true +21558 (string-equal? %esi "allocate") # => eax +21559 3d/compare-eax-and 0/imm32/false +21560 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21561 # if (name == "populate") return true +21562 (string-equal? %esi "populate") # => eax +21563 3d/compare-eax-and 0/imm32/false +21564 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21565 # if (name == "populate-stream") return true +21566 (string-equal? %esi "populate-stream") # => eax +21567 3d/compare-eax-and 0/imm32/false +21568 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21569 # if (name == "read-from-stream") return true +21570 (string-equal? %esi "read-from-stream") # => eax +21571 3d/compare-eax-and 0/imm32/false +21572 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21573 # if (name == "write-to-stream") return true +21574 (string-equal? %esi "write-to-stream") # => eax +21575 3d/compare-eax-and 0/imm32/false +21576 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +21577 # var curr/ecx: (addr primitive) = Primitives +21578 b9/copy-to-ecx Primitives/imm32 +21579 { +21580 $has-primitive-name?:loop: +21581 # if (curr == null) break +21582 81 7/subop/compare %ecx 0/imm32 +21583 74/jump-if-= break/disp8 +21584 # if (primitive->name == name) return true +21585 (lookup *ecx *(ecx+4)) # Primitive-name Primitive-name => eax +21586 #? (write-buffered Stderr %eax) +21587 #? (write-buffered Stderr Newline) +21588 #? (flush Stderr) +21589 (string-equal? %esi %eax) # => eax +21590 3d/compare-eax-and 0/imm32/false +21591 75/jump-if-!= $has-primitive-name?:end/disp8 +21592 $has-primitive-name?:next-primitive: +21593 # curr = curr->next +21594 (lookup *(ecx+0x3c) *(ecx+0x40)) # Primitive-next Primitive-next => eax +21595 89/<- %ecx 0/r32/eax +21596 # +21597 e9/jump loop/disp32 +21598 } +21599 # return null +21600 b8/copy-to-eax 0/imm32 +21601 $has-primitive-name?:end: +21602 # . restore registers +21603 5e/pop-to-esi +21604 59/pop-to-ecx +21605 # . epilogue +21606 89/<- %esp 5/r32/ebp +21607 5d/pop-to-ebp +21608 c3/return +21609 +21610 check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +21611 # . prologue +21612 55/push-ebp +21613 89/<- %ebp 4/r32/esp +21614 # . save registers +21615 50/push-eax +21616 51/push-ecx +21617 # var op/ecx: (addr array byte) = lookup(stmt->operation) +21618 8b/-> *(ebp+8) 0/r32/eax +21619 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +21620 89/<- %ecx 0/r32/eax +21621 # if (op == "copy") check-mu-copy-stmt +21622 { +21623 (string-equal? %ecx "copy") # => eax +21624 3d/compare-eax-and 0/imm32/false +21625 74/jump-if-= break/disp8 +21626 (check-mu-copy-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21627 e9/jump $check-mu-primitive:end/disp32 +21628 } +21629 # if (op == "copy-to") check-mu-copy-to-stmt +21630 { +21631 (string-equal? %ecx "copy-to") # => eax +21632 3d/compare-eax-and 0/imm32/false +21633 74/jump-if-= break/disp8 +21634 (check-mu-copy-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21635 e9/jump $check-mu-primitive:end/disp32 +21636 } +21637 # if (op == "copy-byte") check-mu-copy-byte-stmt +21638 { +21639 (string-equal? %ecx "copy-byte") # => eax +21640 3d/compare-eax-and 0/imm32/false +21641 74/jump-if-= break/disp8 +21642 (check-mu-copy-byte-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21643 e9/jump $check-mu-primitive:end/disp32 +21644 } +21645 # if (op == "copy-byte-to") check-mu-copy-byte-to-stmt +21646 { +21647 (string-equal? %ecx "copy-byte-to") # => eax +21648 3d/compare-eax-and 0/imm32/false +21649 74/jump-if-= break/disp8 +21650 (check-mu-copy-byte-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21651 e9/jump $check-mu-primitive:end/disp32 +21652 } +21653 # if (op == "compare") check-mu-compare-stmt +21654 { +21655 (string-equal? %ecx "compare") # => eax +21656 3d/compare-eax-and 0/imm32/false +21657 74/jump-if-= break/disp8 +21658 (check-mu-compare-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21659 e9/jump $check-mu-primitive:end/disp32 +21660 } +21661 # if (op == "address") check-mu-address-stmt +21662 { +21663 (string-equal? %ecx "address") # => eax +21664 3d/compare-eax-and 0/imm32/false +21665 74/jump-if-= break/disp8 +21666 (check-mu-address-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21667 e9/jump $check-mu-primitive:end/disp32 +21668 } +21669 # if (op == "return") check-mu-return-stmt +21670 { +21671 (string-equal? %ecx "return") # => eax +21672 3d/compare-eax-and 0/imm32/false +21673 74/jump-if-= break/disp8 +21674 (check-mu-return-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21675 e9/jump $check-mu-primitive:end/disp32 +21676 } +21677 # if (op == "get") check-mu-get-stmt +21678 { +21679 (string-equal? %ecx "get") # => eax +21680 3d/compare-eax-and 0/imm32/false +21681 74/jump-if-= break/disp8 +21682 (check-mu-get-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21683 e9/jump $check-mu-primitive:end/disp32 +21684 } +21685 # if (op == "index") check-mu-index-stmt +21686 { +21687 (string-equal? %ecx "index") # => eax +21688 3d/compare-eax-and 0/imm32/false +21689 74/jump-if-= break/disp8 +21690 (check-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21691 e9/jump $check-mu-primitive:end/disp32 +21692 } +21693 # if (op == "length") check-mu-length-stmt +21694 { +21695 (string-equal? %ecx "length") # => eax +21696 3d/compare-eax-and 0/imm32/false +21697 74/jump-if-= break/disp8 +21698 (check-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21699 e9/jump $check-mu-primitive:end/disp32 +21700 } +21701 # if (op == "compute-offset") check-mu-compute-offset-stmt +21702 { +21703 (string-equal? %ecx "compute-offset") # => eax +21704 3d/compare-eax-and 0/imm32/false +21705 74/jump-if-= break/disp8 +21706 (check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21707 e9/jump $check-mu-primitive:end/disp32 +21708 } +21709 # if (op == "copy-object") check-mu-copy-object-stmt +21710 { +21711 (string-equal? %ecx "copy-object") # => eax +21712 3d/compare-eax-and 0/imm32/false +21713 74/jump-if-= break/disp8 +21714 (check-mu-copy-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21715 e9/jump $check-mu-primitive:end/disp32 +21716 } +21717 # if (op == "clear-object") check-mu-clear-object-stmt +21718 { +21719 (string-equal? %ecx "clear-object") # => eax +21720 3d/compare-eax-and 0/imm32/false +21721 74/jump-if-= break/disp8 +21722 (check-mu-clear-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21723 e9/jump $check-mu-primitive:end/disp32 +21724 } +21725 # if (op == "allocate") check-mu-allocate-stmt +21726 { +21727 (string-equal? %ecx "allocate") # => eax +21728 3d/compare-eax-and 0/imm32/false +21729 74/jump-if-= break/disp8 +21730 (check-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21731 e9/jump $check-mu-primitive:end/disp32 +21732 } +21733 # if (op == "populate") check-mu-populate-stmt +21734 { +21735 (string-equal? %ecx "populate") # => eax +21736 3d/compare-eax-and 0/imm32/false +21737 74/jump-if-= break/disp8 +21738 (check-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21739 e9/jump $check-mu-primitive:end/disp32 +21740 } +21741 # if (op == "populate-stream") check-mu-populate-stream-stmt +21742 { +21743 (string-equal? %ecx "populate-stream") # => eax +21744 3d/compare-eax-and 0/imm32/false +21745 74/jump-if-= break/disp8 +21746 (check-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21747 e9/jump $check-mu-primitive:end/disp32 +21748 } +21749 # if (op == "read-from-stream") check-mu-read-from-stream-stmt +21750 { +21751 (string-equal? %ecx "read-from-stream") # => eax +21752 3d/compare-eax-and 0/imm32/false +21753 74/jump-if-= break/disp8 +21754 (check-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21755 e9/jump $check-mu-primitive:end/disp32 +21756 } +21757 # if (op == "write-to-stream") check-mu-write-to-stream-stmt +21758 { +21759 (string-equal? %ecx "write-to-stream") # => eax +21760 3d/compare-eax-and 0/imm32/false +21761 74/jump-if-= break/disp8 +21762 (check-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21763 e9/jump $check-mu-primitive:end/disp32 +21764 } +21765 # if (op == "convert") check-mu-convert-stmt +21766 { +21767 (string-equal? %ecx "convert") # => eax +21768 3d/compare-eax-and 0/imm32/false +21769 74/jump-if-= break/disp8 +21770 (check-mu-convert-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21771 e9/jump $check-mu-primitive:end/disp32 +21772 } +21773 # otherwise check-numberlike-stmt +21774 (check-mu-numberlike-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21775 $check-mu-primitive:end: +21776 # . restore registers +21777 59/pop-to-ecx +21778 58/pop-to-eax +21779 # . epilogue +21780 89/<- %esp 5/r32/ebp +21781 5d/pop-to-ebp +21782 c3/return +21783 +21784 # by default, Mu primitives should only operate on 'number-like' types +21785 check-mu-numberlike-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +21786 # . prologue +21787 55/push-ebp +21788 89/<- %ebp 4/r32/esp +21789 # . save registers +21790 50/push-eax +21791 51/push-ecx +21792 56/push-esi +21793 # esi = stmt +21794 8b/-> *(ebp+8) 6/r32/esi +21795 # var gas/ecx: int = 2 +21796 b9/copy-to-ecx 2/imm32 +21797 # - check at most 1 output +21798 # var output/eax: (addr stmt-var) = stmt->outputs +21799 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +21800 { +21801 3d/compare-eax-and 0/imm32 +21802 74/jump-if-= break/disp8 +21803 $check-mu-numberlike-primitive:output: +21804 (check-mu-numberlike-output %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21805 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +21806 3d/compare-eax-and 0/imm32 +21807 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-outputs/disp32 +21808 # check output is in a register +21809 # --gas +21810 49/decrement-ecx +21811 } +21812 # - check first inout +21813 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +21814 { +21815 3d/compare-eax-and 0/imm32 +21816 0f 84/jump-if-= $check-mu-numberlike-primitive:end/disp32 +21817 $check-mu-numberlike-primitive:first-inout: +21818 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21819 # --gas +21820 49/decrement-ecx +21821 } +21822 # - check second inout +21823 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +21824 { +21825 3d/compare-eax-and 0/imm32 +21826 74/jump-if-= $check-mu-numberlike-primitive:end/disp8 +21827 $check-mu-numberlike-primitive:second-inout: +21828 # is a second inout allowed? +21829 81 7/subop/compare %ecx 0/imm32 +21830 0f 84/jump-if-= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 +21831 $check-mu-numberlike-primitive:second-inout-permitted: +21832 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +21833 } +21834 $check-mu-numberlike-primitive:third-inout: +21835 # if there's a third arg, raise an error +21836 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next +21837 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 +21838 $check-mu-numberlike-primitive:end: +21839 # . restore registers +21840 5e/pop-to-esi +21841 59/pop-to-ecx +21842 58/pop-to-eax +21843 # . epilogue +21844 89/<- %esp 5/r32/ebp +21845 5d/pop-to-ebp +21846 c3/return +21847 +21848 $check-mu-numberlike-primitive:error-too-many-inouts: +21849 (write-buffered *(ebp+0x10) "fn ") +21850 8b/-> *(ebp+0xc) 0/r32/eax +21851 (lookup *eax *(eax+4)) # Function-name Function-name => eax +21852 (write-buffered *(ebp+0x10) %eax) +21853 (write-buffered *(ebp+0x10) ": stmt ") +21854 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +21855 (write-buffered *(ebp+0x10) %eax) +21856 (write-buffered *(ebp+0x10) ": too many inouts; most primitives support at most two arguments, across inouts and outputs\n") +21857 (flush *(ebp+0x10)) +21858 (stop *(ebp+0x14) 1) +21859 # never gets here +21860 +21861 $check-mu-numberlike-primitive:error-too-many-outputs: +21862 (write-buffered *(ebp+0x10) "fn ") +21863 8b/-> *(ebp+0xc) 0/r32/eax +21864 (lookup *eax *(eax+4)) # Function-name Function-name => eax +21865 (write-buffered *(ebp+0x10) %eax) +21866 (write-buffered *(ebp+0x10) ": stmt ") +21867 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +21868 (write-buffered *(ebp+0x10) %eax) +21869 (write-buffered *(ebp+0x10) ": too many outputs; most primitives support at most one output\n") +21870 (flush *(ebp+0x10)) +21871 (stop *(ebp+0x14) 1) +21872 # never gets here +21873 +21874 check-mu-numberlike-arg: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +21875 # . prologue +21876 55/push-ebp +21877 89/<- %ebp 4/r32/esp +21878 # . save registers +21879 50/push-eax +21880 56/push-esi +21881 # var t/esi: (addr type-tree) = lookup(v->value->type) +21882 8b/-> *(ebp+8) 0/r32/eax +21883 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +21884 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +21885 89/<- %esi 0/r32/eax +21886 $check-mu-numberlike-arg:check-literal: +21887 # if t is an int, return +21888 (simple-mu-type? %esi 0) # literal => eax +21889 3d/compare-eax-and 0/imm32/false +21890 0f 85/jump-if-!= $check-mu-numberlike-arg:end/disp32 +21891 $check-mu-numberlike-arg:check-addr: +21892 # if t is an addr and v is dereferenced, return whether t->payload is an addr +21893 { +21894 (mu-addr-type? %esi) # => eax +21895 3d/compare-eax-and 0/imm32/false +21896 74/jump-if-= break/disp8 +21897 8b/-> *(ebp+8) 0/r32/eax +21898 8b/-> *(eax+0x10) 0/r32/eax # Stmt-var-is-deref +21899 3d/compare-eax-and 0/imm32/false +21900 { +21901 74/jump-if-= break/disp8 +21902 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax +21903 # if t->right is null, t = t->left +21904 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +21905 { +21906 75/jump-if-!= break/disp8 +21907 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +21908 } +21909 (mu-addr-type? %eax) # => eax +21910 3d/compare-eax-and 0/imm32/false +21911 74/jump-if-= $check-mu-numberlike-arg:end/disp8 +21912 } +21913 } +21914 $check-mu-numberlike-arg:output-checks: +21915 (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) +21916 $check-mu-numberlike-arg:end: +21917 # . restore registers +21918 5e/pop-to-esi +21919 58/pop-to-eax +21920 # . epilogue +21921 89/<- %esp 5/r32/ebp +21922 5d/pop-to-ebp +21923 c3/return +21924 +21925 check-mu-numberlike-output: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +21926 # . prologue +21927 55/push-ebp +21928 89/<- %ebp 4/r32/esp +21929 # . save registers +21930 50/push-eax +21931 # +21932 (mu-numberlike-output-var? *(ebp+8)) # => eax +21933 3d/compare-eax-and 0/imm32/false +21934 0f 84/jump-if-= $check-mu-numberlike-output:fail/disp32 +21935 $check-mu-numberlike-output:end: +21936 # . restore registers +21937 58/pop-to-eax +21938 # . epilogue +21939 89/<- %esp 5/r32/ebp +21940 5d/pop-to-ebp +21941 c3/return +21942 +21943 $check-mu-numberlike-output:fail: +21944 # otherwise raise an error +21945 (write-buffered *(ebp+0x14) "fn ") +21946 8b/-> *(ebp+0x10) 0/r32/eax +21947 (lookup *eax *(eax+4)) # Function-name Function-name => eax +21948 (write-buffered *(ebp+0x14) %eax) +21949 (write-buffered *(ebp+0x14) ": stmt ") +21950 8b/-> *(ebp+0xc) 0/r32/eax +21951 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +21952 (write-buffered *(ebp+0x14) %eax) +21953 (write-buffered *(ebp+0x14) ": '") +21954 8b/-> *(ebp+8) 0/r32/eax +21955 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +21956 (lookup *eax *(eax+4)) # Var-name Var-name => eax +21957 (write-buffered *(ebp+0x14) %eax) +21958 (write-buffered *(ebp+0x14) "' must be a non-addr non-offset scalar\n") +21959 (flush *(ebp+0x14)) +21960 (stop *(ebp+0x18) 1) +21961 # never gets here +21962 +21963 mu-numberlike-output-var?: # v: (addr stmt-var) -> result/eax: boolean +21964 # . prologue +21965 55/push-ebp +21966 89/<- %ebp 4/r32/esp +21967 # +21968 8b/-> *(ebp+8) 0/r32/eax +21969 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +21970 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +21971 (mu-numberlike-output? %eax) # => eax +21972 $mu-numberlike-output-var?:end: +21973 # . epilogue +21974 89/<- %esp 5/r32/ebp +21975 5d/pop-to-ebp +21976 c3/return +21977 +21978 mu-numberlike-output?: # v: (addr type-tree) -> result/eax: boolean +21979 # . prologue +21980 55/push-ebp +21981 89/<- %ebp 4/r32/esp +21982 # . save registers +21983 56/push-esi +21984 # var t/esi: (addr type-tree) = lookup(v->value->type) +21985 8b/-> *(ebp+8) 6/r32/esi +21986 $mu-numberlike-output?:check-int: +21987 # if t is an int, return +21988 (simple-mu-type? %esi 1) # int => eax +21989 3d/compare-eax-and 0/imm32/false +21990 0f 85/jump-if-!= $mu-numberlike-output?:return-true/disp32 +21991 $mu-numberlike-output?:check-float: +21992 # if t is a float, return +21993 (simple-mu-type? %esi 0xf) # float => eax +21994 3d/compare-eax-and 0/imm32/false +21995 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 +21996 $mu-numberlike-output?:check-boolean: +21997 # if t is a boolean, return +21998 (simple-mu-type? %esi 5) # boolean => eax +21999 3d/compare-eax-and 0/imm32/false +22000 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 +22001 $mu-numberlike-output?:check-byte: +22002 # if t is a byte, return +22003 (simple-mu-type? %esi 8) # byte => eax +22004 3d/compare-eax-and 0/imm32/false +22005 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 +22006 $mu-numberlike-output?:check-code-point: +22007 # if t is a code-point, return +22008 (simple-mu-type? %esi 0xd) # code-point => eax +22009 3d/compare-eax-and 0/imm32/false +22010 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 +22011 $mu-numberlike-output?:check-grapheme: +22012 # if t is a grapheme, return +22013 (simple-mu-type? %esi 0xe) # grapheme => eax +22014 3d/compare-eax-and 0/imm32/false +22015 75/jump-if-!= $mu-numberlike-output?:return-true/disp8 +22016 $mu-numberlike-output?:return-false: +22017 b8/copy-to-eax 0/imm32/false +22018 eb/jump $mu-numberlike-output?:end/disp8 +22019 $mu-numberlike-output?:return-true: +22020 b8/copy-to-eax 1/imm32/true +22021 $mu-numberlike-output?:end: +22022 # . restore registers +22023 5e/pop-to-esi +22024 # . epilogue +22025 89/<- %esp 5/r32/ebp +22026 5d/pop-to-ebp +22027 c3/return +22028 +22029 check-mu-copy-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +22030 # . prologue +22031 55/push-ebp +22032 89/<- %ebp 4/r32/esp +22033 # . save registers +22034 50/push-eax +22035 51/push-ecx +22036 52/push-edx +22037 56/push-esi +22038 57/push-edi +22039 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) +22040 81 5/subop/subtract %esp 0x60/imm32 +22041 68/push 0x60/imm32/size +22042 68/push 0/imm32/read +22043 68/push 0/imm32/write +22044 89/<- %edx 4/r32/esp +22045 $check-mu-copy-stmt:get-output: +22046 # esi = stmt +22047 8b/-> *(ebp+8) 6/r32/esi +22048 # var output/edi: (addr stmt-var) = stmt->outputs +22049 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +22050 89/<- %edi 0/r32/eax +22051 # zero outputs +22052 3d/compare-eax-and 0/imm32 +22053 0f 84/jump-if-= $check-mu-copy-stmt:error-no-output/disp32 +22054 # > 1 output +22055 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +22056 3d/compare-eax-and 0/imm32 +22057 0f 85/jump-if-!= $check-mu-copy-stmt:error-too-many-outputs/disp32 +22058 $check-mu-copy-stmt:get-inout: +22059 # var inout/esi: (addr stmt-var) = stmt->inouts +22060 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +22061 89/<- %esi 0/r32/eax +22062 # zero inouts +22063 3d/compare-eax-and 0/imm32 +22064 0f 84/jump-if-= $check-mu-copy-stmt:error-no-inout/disp32 +22065 # > 1 inout +22066 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +22067 3d/compare-eax-and 0/imm32 +22068 0f 85/jump-if-!= $check-mu-copy-stmt:error-too-many-inouts/disp32 +22069 $check-mu-copy-stmt:types: +22070 # if inout is not a scalar, abort +22071 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22072 (size-of %eax) # => eax +22073 3d/compare-eax-and 4/imm32 +22074 0f 8f/jump-if-> $check-mu-copy-stmt:error-inout-too-large/disp32 +22075 # var inout-type/ecx: (addr type-tree) = inout->value->type +22076 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax 22077 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22078 # if (inout-type == output-type) return -22079 (type-match? %eax %ecx %edx) # => eax -22080 3d/compare-eax-and 0/imm32 -22081 0f 85/jump-if-!= $check-mu-copy-stmt:end/disp32 -22082 # if output is an addr and inout is 0, return -22083 { -22084 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22085 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22086 (mu-addr-type? %eax) # => eax -22087 3d/compare-eax-and 0/imm32/false -22088 74/jump-if-= break/disp8 -22089 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22090 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22091 (string-equal? %eax "0") # => eax -22092 3d/compare-eax-and 0/imm32/false -22093 74/jump-if-= break/disp8 -22094 e9/jump $check-mu-copy-stmt:end/disp32 -22095 } -22096 # if output is an offset and inout is 0, return -22097 { -22098 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22099 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22100 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -22101 75/jump-if-!= break/disp8 -22102 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -22103 (simple-mu-type? %eax 7) # offset => eax -22104 3d/compare-eax-and 0/imm32/false -22105 74/jump-if-= break/disp8 -22106 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22107 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22108 (string-equal? %eax "0") # => eax -22109 3d/compare-eax-and 0/imm32/false -22110 74/jump-if-= break/disp8 -22111 e9/jump $check-mu-copy-stmt:end/disp32 -22112 } -22113 # if output is a byte, abort if inout is not a literal. Otherwise return. -22114 { -22115 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22116 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22117 (simple-mu-type? %eax 8) # byte => eax -22118 3d/compare-eax-and 0/imm32/false -22119 74/jump-if-= break/disp8 -22120 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22121 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22122 (simple-mu-type? %eax 0) # literal => eax -22123 3d/compare-eax-and 0/imm32/false -22124 0f 84/jump-if-= $check-mu-copy-stmt:error-non-literal-to-byte/disp32 -22125 eb/jump $check-mu-copy-stmt:end/disp8 -22126 } -22127 # if output is not number-like, abort -22128 (check-mu-numberlike-output %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -22129 $check-mu-copy-stmt:end: -22130 # . reclaim locals -22131 81 0/subop/add %esp 0x6c/imm32 -22132 # . restore registers -22133 5f/pop-to-edi -22134 5e/pop-to-esi -22135 5a/pop-to-edx -22136 59/pop-to-ecx -22137 58/pop-to-eax -22138 # . epilogue -22139 89/<- %esp 5/r32/ebp -22140 5d/pop-to-ebp -22141 c3/return -22142 -22143 $check-mu-copy-stmt:error-no-inout: -22144 (write-buffered *(ebp+0x10) "fn ") -22145 8b/-> *(ebp+0xc) 0/r32/eax -22146 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22147 (write-buffered *(ebp+0x10) %eax) -22148 (write-buffered *(ebp+0x10) ": stmt 'copy' expects an inout\n") -22149 (flush *(ebp+0x10)) -22150 (stop *(ebp+0x14) 1) -22151 # never gets here -22152 -22153 $check-mu-copy-stmt:error-too-many-inouts: -22154 (write-buffered *(ebp+0x10) "fn ") -22155 8b/-> *(ebp+0xc) 0/r32/eax -22156 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22157 (write-buffered *(ebp+0x10) %eax) -22158 (write-buffered *(ebp+0x10) ": stmt 'copy' must have just one inout\n") -22159 (flush *(ebp+0x10)) -22160 (stop *(ebp+0x14) 1) -22161 # never gets here -22162 -22163 $check-mu-copy-stmt:error-no-output: -22164 (write-buffered *(ebp+0x10) "fn ") -22165 8b/-> *(ebp+0xc) 0/r32/eax -22166 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22167 (write-buffered *(ebp+0x10) %eax) -22168 (write-buffered *(ebp+0x10) ": stmt 'copy' expects an output\n") -22169 (flush *(ebp+0x10)) -22170 (stop *(ebp+0x14) 1) -22171 # never gets here -22172 -22173 $check-mu-copy-stmt:error-output-not-in-register: -22174 (write-buffered *(ebp+0x10) "fn ") -22175 8b/-> *(ebp+0xc) 0/r32/eax -22176 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22177 (write-buffered *(ebp+0x10) %eax) -22178 (write-buffered *(ebp+0x10) ": stmt copy: output '") -22179 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22180 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22181 (write-buffered *(ebp+0x10) %eax) -22182 (write-buffered *(ebp+0x10) "' not in a register\n") -22183 (flush *(ebp+0x10)) -22184 (stop *(ebp+0x14) 1) -22185 # never gets here -22186 -22187 $check-mu-copy-stmt:error-too-many-outputs: -22188 (write-buffered *(ebp+0x10) "fn ") -22189 8b/-> *(ebp+0xc) 0/r32/eax -22190 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22191 (write-buffered *(ebp+0x10) %eax) -22192 (write-buffered *(ebp+0x10) ": stmt 'copy' must have just one output\n") -22193 (flush *(ebp+0x10)) -22194 (stop *(ebp+0x14) 1) -22195 # never gets here -22196 -22197 $check-mu-copy-stmt:error-inout-too-large: -22198 (write-buffered *(ebp+0x10) "fn ") -22199 8b/-> *(ebp+0xc) 0/r32/eax -22200 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22201 (write-buffered *(ebp+0x10) %eax) -22202 (write-buffered *(ebp+0x10) ": stmt copy: '") -22203 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22204 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22205 (write-buffered *(ebp+0x10) %eax) -22206 (write-buffered *(ebp+0x10) "' is too large to fit in a register\n") -22207 (flush *(ebp+0x10)) -22208 (stop *(ebp+0x14) 1) -22209 # never gets here -22210 -22211 $check-mu-copy-stmt:error-non-literal-to-byte: -22212 (write-buffered *(ebp+0x10) "fn ") -22213 8b/-> *(ebp+0xc) 0/r32/eax -22214 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22215 (write-buffered *(ebp+0x10) %eax) -22216 (write-buffered *(ebp+0x10) ": stmt copy: cannot copy non-literal to '") -22217 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22218 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22219 (write-buffered *(ebp+0x10) %eax) -22220 (write-buffered *(ebp+0x10) "' of type byte; use copy-byte\n") -22221 (flush *(ebp+0x10)) -22222 (stop *(ebp+0x14) 1) -22223 # never gets here -22224 -22225 check-mu-copy-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -22226 # . prologue -22227 55/push-ebp -22228 89/<- %ebp 4/r32/esp -22229 # . save registers -22230 50/push-eax -22231 51/push-ecx -22232 52/push-edx -22233 53/push-ebx -22234 56/push-esi -22235 57/push-edi -22236 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) -22237 81 5/subop/subtract %esp 0x60/imm32 -22238 68/push 0x60/imm32/size -22239 68/push 0/imm32/read -22240 68/push 0/imm32/write -22241 89/<- %edx 4/r32/esp -22242 # esi = stmt -22243 8b/-> *(ebp+8) 6/r32/esi -22244 $check-mu-copy-to-stmt:check-for-output: -22245 # if stmt->outputs abort -22246 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -22247 3d/compare-eax-and 0/imm32 -22248 0f 85/jump-if-!= $check-mu-copy-to-stmt:error-too-many-outputs/disp32 -22249 $check-mu-copy-to-stmt:get-dest: -22250 # var dest/edi: (addr stmt-var) = stmt->inouts -22251 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -22252 89/<- %edi 0/r32/eax -22253 # zero inouts -22254 3d/compare-eax-and 0/imm32 -22255 0f 84/jump-if-= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32 -22256 $check-mu-copy-to-stmt:get-src: -22257 # var src/esi: (addr stmt-var) = dest->next -22258 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -22259 89/<- %esi 0/r32/eax -22260 # 1 inout -22261 3d/compare-eax-and 0/imm32 -22262 0f 84/jump-if-= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32 -22263 # > 2 inouts -22264 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -22265 3d/compare-eax-and 0/imm32 -22266 0f 85/jump-if-!= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32 -22267 $check-mu-copy-to-stmt:types: -22268 # if src is not a scalar, abort -22269 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22270 (size-of %eax) # => eax -22271 3d/compare-eax-and 4/imm32 -22272 0f 8f/jump-if-> $check-mu-copy-to-stmt:error-src-too-large/disp32 -22273 # var src-type/ecx: (addr type-tree) = src->value->type -22274 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22275 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22276 89/<- %ecx 0/r32/eax -22277 # if src not in register or literal, abort -22278 # (we can't use stack-offset because it hasn't been computed yet) -22279 { -22280 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22281 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax -22282 (simple-mu-type? %eax 0) # => eax -22283 3d/compare-eax-and 0/imm32 -22284 75/jump-if-!= break/disp8 -22285 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22286 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -22287 3d/compare-eax-and 0/imm32 -22288 75/jump-if-!= break/disp8 -22289 e9/jump $check-mu-copy-to-stmt:error-src-not-literal-or-in-register/disp32 -22290 } -22291 # var dest-type/ebx: (addr type-tree) = dest->value->type -22292 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22293 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22294 89/<- %ebx 0/r32/eax -22295 # if (dest->is-deref?) dest-type = dest-type->payload -22296 $check-mu-copy-to-stmt:check-dest-deref: -22297 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref -22298 3d/compare-eax-and 0/imm32/false -22299 { -22300 74/jump-if-= break/disp8 -22301 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -22302 $check-mu-copy-to-stmt:dest-is-deref: -22303 # if dest-type->right is null, dest-type = dest-type->left -22304 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -22305 { -22306 75/jump-if-!= break/disp8 -22307 $check-mu-copy-to-stmt:dest-is-deref2: -22308 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -22309 } -22310 89/<- %ebx 0/r32/eax -22311 } -22312 # if dest is a byte and src is not a literal, abort -22313 { -22314 $check-mu-copy-to-stmt:final-check-byte: -22315 (simple-mu-type? %ebx 8) # byte => eax -22316 3d/compare-eax-and 0/imm32/false -22317 74/jump-if-= break/disp8 -22318 (simple-mu-type? %ecx 0) # literal => eax -22319 3d/compare-eax-and 0/imm32/false -22320 0f 84/jump-if-= $check-mu-copy-to-stmt:error-non-literal-to-byte/disp32 -22321 } -22322 # if (src-type == dest-type) return -22323 (type-match? %ebx %ecx %edx) # => eax -22324 3d/compare-eax-and 0/imm32 -22325 0f 85/jump-if-!= $check-mu-copy-to-stmt:end/disp32 -22326 # if dest is an addr and src is 0, return -22327 { -22328 $check-mu-copy-to-stmt:final-check-addr: -22329 (mu-addr-type? %ebx) # => eax -22330 3d/compare-eax-and 0/imm32/false -22331 74/jump-if-= break/disp8 -22332 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22333 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22334 (string-equal? %eax "0") # => eax -22335 3d/compare-eax-and 0/imm32/false -22336 74/jump-if-= break/disp8 -22337 e9/jump $check-mu-copy-to-stmt:end/disp32 -22338 } -22339 # if dest is an offset and src is 0, return -22340 { -22341 $check-mu-copy-to-stmt:final-check-offset: -22342 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -22343 75/jump-if-!= break/disp8 -22344 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -22345 (simple-mu-type? %eax 7) # offset => eax -22346 3d/compare-eax-and 0/imm32/false -22347 74/jump-if-= break/disp8 -22348 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22349 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22350 (string-equal? %eax "0") # => eax -22351 3d/compare-eax-and 0/imm32/false -22352 74/jump-if-= break/disp8 -22353 e9/jump $check-mu-copy-to-stmt:end/disp32 -22354 } -22355 # if dest is not number-like, abort -22356 (check-mu-numberlike-arg %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -22357 $check-mu-copy-to-stmt:end: -22358 # . reclaim locals -22359 81 0/subop/add %esp 0x6c/imm32 -22360 # . restore registers -22361 5f/pop-to-edi -22362 5e/pop-to-esi -22363 5b/pop-to-ebx -22364 5a/pop-to-edx -22365 59/pop-to-ecx -22366 58/pop-to-eax -22367 # . epilogue -22368 89/<- %esp 5/r32/ebp -22369 5d/pop-to-ebp -22370 c3/return -22371 -22372 $check-mu-copy-to-stmt:error-incorrect-inouts: -22373 (write-buffered *(ebp+0x10) "fn ") -22374 8b/-> *(ebp+0xc) 0/r32/eax -22375 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22376 (write-buffered *(ebp+0x10) %eax) -22377 (write-buffered *(ebp+0x10) ": stmt 'copy-to' must have two inouts\n") -22378 (flush *(ebp+0x10)) -22379 (stop *(ebp+0x14) 1) -22380 # never gets here -22381 -22382 $check-mu-copy-to-stmt:error-too-many-outputs: -22383 (write-buffered *(ebp+0x10) "fn ") -22384 8b/-> *(ebp+0xc) 0/r32/eax -22385 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22386 (write-buffered *(ebp+0x10) %eax) -22387 (write-buffered *(ebp+0x10) ": stmt 'copy-to' must not have any outputs\n") -22388 (flush *(ebp+0x10)) -22389 (stop *(ebp+0x14) 1) -22390 # never gets here -22391 -22392 $check-mu-copy-to-stmt:error-src-not-literal-or-in-register: -22393 (write-buffered *(ebp+0x10) "fn ") -22394 8b/-> *(ebp+0xc) 0/r32/eax -22395 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22396 (write-buffered *(ebp+0x10) %eax) -22397 (write-buffered *(ebp+0x10) ": stmt copy-to: source (second inout) is in memory\n") -22398 (flush *(ebp+0x10)) -22399 (stop *(ebp+0x14) 1) -22400 # never gets here -22401 -22402 $check-mu-copy-to-stmt:error-src-too-large: -22403 (write-buffered *(ebp+0x10) "fn ") -22404 8b/-> *(ebp+0xc) 0/r32/eax -22405 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22406 (write-buffered *(ebp+0x10) %eax) -22407 (write-buffered *(ebp+0x10) ": stmt copy-to: '") -22408 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22409 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22410 (write-buffered *(ebp+0x10) %eax) -22411 (write-buffered *(ebp+0x10) "' is too large to copy\n") -22412 (flush *(ebp+0x10)) -22413 (stop *(ebp+0x14) 1) -22414 # never gets here -22415 -22416 $check-mu-copy-to-stmt:error-non-literal-to-byte: -22417 (write-buffered *(ebp+0x10) "fn ") -22418 8b/-> *(ebp+0xc) 0/r32/eax -22419 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22420 (write-buffered *(ebp+0x10) %eax) -22421 (write-buffered *(ebp+0x10) ": stmt copy-to: cannot copy non-literal to type byte; use copy-byte-to\n") -22422 (flush *(ebp+0x10)) -22423 (stop *(ebp+0x14) 1) -22424 # never gets here -22425 -22426 check-mu-copy-byte-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -22427 # . prologue -22428 55/push-ebp -22429 89/<- %ebp 4/r32/esp -22430 # . save registers -22431 50/push-eax -22432 51/push-ecx -22433 52/push-edx -22434 56/push-esi -22435 57/push-edi -22436 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) -22437 81 5/subop/subtract %esp 0x60/imm32 -22438 68/push 0x60/imm32/size -22439 68/push 0/imm32/read -22440 68/push 0/imm32/write -22441 89/<- %edx 4/r32/esp -22442 $check-mu-copy-byte-stmt:get-output: -22443 # esi = stmt -22444 8b/-> *(ebp+8) 6/r32/esi -22445 # var output/edi: (addr stmt-var) = stmt->outputs -22446 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -22447 89/<- %edi 0/r32/eax -22448 # zero outputs -22449 3d/compare-eax-and 0/imm32 -22450 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-no-output/disp32 -22451 # > 1 output -22452 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -22453 3d/compare-eax-and 0/imm32 -22454 0f 85/jump-if-!= $check-mu-copy-byte-stmt:error-too-many-outputs/disp32 -22455 $check-mu-copy-byte-stmt:get-inout: -22456 # var inout/esi: (addr stmt-var) = stmt->inouts -22457 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -22458 89/<- %esi 0/r32/eax -22459 # zero inouts -22460 3d/compare-eax-and 0/imm32 -22461 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-no-inout/disp32 -22462 # > 1 inout -22463 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -22464 3d/compare-eax-and 0/imm32 -22465 0f 85/jump-if-!= $check-mu-copy-byte-stmt:error-too-many-inouts/disp32 -22466 $check-mu-copy-byte-stmt:types: -22467 # if inout is not a scalar, abort -22468 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22469 (size-of %eax) # => eax -22470 3d/compare-eax-and 4/imm32 -22471 0f 8f/jump-if-> $check-mu-copy-byte-stmt:error-inout-too-large/disp32 -22472 # var inout-type/ecx: (addr type-tree) = inout->value->type -22473 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22474 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22475 89/<- %ecx 0/r32/eax -22476 $check-mu-copy-byte-stmt:check-inout-deref: -22477 # if (inout->is-deref?) inout-type = inout-type->payload -22478 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref -22479 3d/compare-eax-and 0/imm32/false -22480 { -22481 74/jump-if-= break/disp8 -22482 $check-mu-copy-byte-stmt:inout-is-deref: -22483 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -22484 # if inout-type->right is null, t = inout-type->left -22485 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -22486 { -22487 75/jump-if-!= break/disp8 -22488 $check-mu-copy-byte-stmt:inout-is-deref2: -22489 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -22490 } -22491 89/<- %ecx 0/r32/eax -22492 } -22493 # if output not in register, abort -22494 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22495 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -22496 3d/compare-eax-and 0/imm32 -22497 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-output-not-in-register/disp32 -22498 # var output-type/eax: (addr type-tree) = output->value->type -22499 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22500 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22501 # if output is not of type byte, abort -22502 (simple-mu-type? %eax 8) # byte => eax -22503 3d/compare-eax-and 0/imm32 -22504 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-invalid-output-type/disp32 -22505 $check-mu-copy-byte-stmt:end: -22506 # . reclaim locals -22507 81 0/subop/add %esp 0x6c/imm32 -22508 # . restore registers -22509 5f/pop-to-edi -22510 5e/pop-to-esi -22511 5a/pop-to-edx -22512 59/pop-to-ecx -22513 58/pop-to-eax -22514 # . epilogue -22515 89/<- %esp 5/r32/ebp -22516 5d/pop-to-ebp -22517 c3/return -22518 -22519 $check-mu-copy-byte-stmt:error-no-inout: -22520 (write-buffered *(ebp+0x10) "fn ") -22521 8b/-> *(ebp+0xc) 0/r32/eax -22522 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22523 (write-buffered *(ebp+0x10) %eax) -22524 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' expects an inout\n") -22525 (flush *(ebp+0x10)) -22526 (stop *(ebp+0x14) 1) -22527 # never gets here -22528 -22529 $check-mu-copy-byte-stmt:error-too-many-inouts: -22530 (write-buffered *(ebp+0x10) "fn ") -22531 8b/-> *(ebp+0xc) 0/r32/eax -22532 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22533 (write-buffered *(ebp+0x10) %eax) -22534 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must have just one inout\n") -22535 (flush *(ebp+0x10)) -22536 (stop *(ebp+0x14) 1) -22537 # never gets here -22538 -22539 $check-mu-copy-byte-stmt:error-no-output: -22540 (write-buffered *(ebp+0x10) "fn ") -22541 8b/-> *(ebp+0xc) 0/r32/eax -22542 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22543 (write-buffered *(ebp+0x10) %eax) -22544 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' expects an output\n") -22545 (flush *(ebp+0x10)) -22546 (stop *(ebp+0x14) 1) -22547 # never gets here -22548 -22549 $check-mu-copy-byte-stmt:error-output-not-in-register: -22550 (write-buffered *(ebp+0x10) "fn ") -22551 8b/-> *(ebp+0xc) 0/r32/eax -22552 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22553 (write-buffered *(ebp+0x10) %eax) -22554 (write-buffered *(ebp+0x10) ": stmt copy-byte: output '") -22555 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22556 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22557 (write-buffered *(ebp+0x10) %eax) -22558 (write-buffered *(ebp+0x10) "' not in a register\n") -22559 (flush *(ebp+0x10)) -22560 (stop *(ebp+0x14) 1) -22561 # never gets here -22562 -22563 $check-mu-copy-byte-stmt:error-too-many-outputs: -22564 (write-buffered *(ebp+0x10) "fn ") -22565 8b/-> *(ebp+0xc) 0/r32/eax -22566 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22567 (write-buffered *(ebp+0x10) %eax) -22568 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must have just one output\n") -22569 (flush *(ebp+0x10)) -22570 (stop *(ebp+0x14) 1) -22571 # never gets here -22572 -22573 $check-mu-copy-byte-stmt:error-invalid-output-type: -22574 (write-buffered *(ebp+0x10) "fn ") -22575 8b/-> *(ebp+0xc) 0/r32/eax -22576 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22577 (write-buffered *(ebp+0x10) %eax) -22578 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must write to output of type byte\n") -22579 (flush *(ebp+0x10)) -22580 (stop *(ebp+0x14) 1) -22581 # never gets here -22582 -22583 $check-mu-copy-byte-stmt:error-inout-too-large: -22584 (write-buffered *(ebp+0x10) "fn ") -22585 8b/-> *(ebp+0xc) 0/r32/eax -22586 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22587 (write-buffered *(ebp+0x10) %eax) -22588 (write-buffered *(ebp+0x10) ": stmt copy-byte: '") -22589 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22590 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22591 (write-buffered *(ebp+0x10) %eax) -22592 (write-buffered *(ebp+0x10) "' is too large to fit in a register\n") -22593 (flush *(ebp+0x10)) -22594 (stop *(ebp+0x14) 1) -22595 # never gets here -22596 -22597 check-mu-copy-byte-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -22598 # . prologue -22599 55/push-ebp -22600 89/<- %ebp 4/r32/esp -22601 # . save registers -22602 50/push-eax -22603 52/push-edx -22604 53/push-ebx -22605 56/push-esi -22606 57/push-edi -22607 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) -22608 81 5/subop/subtract %esp 0x60/imm32 -22609 68/push 0x60/imm32/size -22610 68/push 0/imm32/read -22611 68/push 0/imm32/write -22612 89/<- %edx 4/r32/esp -22613 # esi = stmt -22614 8b/-> *(ebp+8) 6/r32/esi -22615 $check-mu-copy-byte-to-stmt:check-for-output: -22616 # if stmt->outputs abort -22617 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -22618 3d/compare-eax-and 0/imm32 -22619 0f 85/jump-if-!= $check-mu-copy-byte-to-stmt:error-too-many-outputs/disp32 -22620 $check-mu-copy-byte-to-stmt:get-dest: -22621 # var dest/edi: (addr stmt-var) = stmt->inouts -22622 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -22623 89/<- %edi 0/r32/eax -22624 # zero inouts -22625 3d/compare-eax-and 0/imm32 -22626 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32 -22627 $check-mu-copy-byte-to-stmt:get-src: -22628 # var src/esi: (addr stmt-var) = dest->next -22629 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -22630 89/<- %esi 0/r32/eax -22631 # 1 inout -22632 3d/compare-eax-and 0/imm32 -22633 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32 -22634 # > 2 inouts -22635 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -22636 3d/compare-eax-and 0/imm32 -22637 0f 85/jump-if-!= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32 -22638 $check-mu-copy-byte-to-stmt:types: -22639 # if src is not a scalar, abort -22640 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22641 (size-of %eax) # => eax -22642 3d/compare-eax-and 4/imm32 -22643 0f 8f/jump-if-> $check-mu-copy-byte-to-stmt:error-src-too-large/disp32 -22644 # if src not in register, abort -22645 { -22646 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22647 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -22648 3d/compare-eax-and 0/imm32 -22649 75/jump-if-!= break/disp8 -22650 e9/jump $check-mu-copy-byte-to-stmt:error-src-not-in-register/disp32 -22651 } -22652 # var dest-type/ebx: (addr type-tree) = dest->value->type -22653 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22654 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22655 89/<- %ebx 0/r32/eax -22656 # if (dest->is-deref?) dest-type = dest-type->payload -22657 $check-mu-copy-byte-to-stmt:check-dest-deref: -22658 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref -22659 3d/compare-eax-and 0/imm32/false -22660 { -22661 74/jump-if-= break/disp8 -22662 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -22663 $check-mu-copy-byte-to-stmt:dest-is-deref: -22664 # if dest-type->right is null, dest-type = dest-type->left -22665 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -22666 { -22667 75/jump-if-!= break/disp8 -22668 $check-mu-copy-byte-to-stmt:dest-is-deref2: -22669 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -22670 } -22671 89/<- %ebx 0/r32/eax -22672 } -22673 # if dest is not a byte, abort -22674 (simple-mu-type? %ebx 8) # byte => eax -22675 3d/compare-eax-and 0/imm32/false -22676 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-invalid-dest-type/disp32 -22677 $check-mu-copy-byte-to-stmt:end: -22678 # . reclaim locals -22679 81 0/subop/add %esp 0x6c/imm32 -22680 # . restore registers -22681 5f/pop-to-edi -22682 5e/pop-to-esi -22683 5b/pop-to-ebx -22684 5a/pop-to-edx -22685 58/pop-to-eax -22686 # . epilogue -22687 89/<- %esp 5/r32/ebp -22688 5d/pop-to-ebp -22689 c3/return -22690 -22691 $check-mu-copy-byte-to-stmt:error-incorrect-inouts: -22692 (write-buffered *(ebp+0x10) "fn ") -22693 8b/-> *(ebp+0xc) 0/r32/eax -22694 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22695 (write-buffered *(ebp+0x10) %eax) -22696 (write-buffered *(ebp+0x10) ": stmt 'copy-byte-to' must have two inouts\n") -22697 (flush *(ebp+0x10)) -22698 (stop *(ebp+0x14) 1) -22699 # never gets here -22700 -22701 $check-mu-copy-byte-to-stmt:error-too-many-outputs: -22702 (write-buffered *(ebp+0x10) "fn ") -22703 8b/-> *(ebp+0xc) 0/r32/eax -22704 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22705 (write-buffered *(ebp+0x10) %eax) -22706 (write-buffered *(ebp+0x10) ": stmt 'copy-byte-to' must not have any outputs\n") -22707 (flush *(ebp+0x10)) -22708 (stop *(ebp+0x14) 1) -22709 # never gets here -22710 -22711 $check-mu-copy-byte-to-stmt:error-src-not-in-register: -22712 (write-buffered *(ebp+0x10) "fn ") -22713 8b/-> *(ebp+0xc) 0/r32/eax -22714 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22715 (write-buffered *(ebp+0x10) %eax) -22716 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: source (second inout) must be in a register\n") -22717 (flush *(ebp+0x10)) -22718 (stop *(ebp+0x14) 1) -22719 # never gets here -22720 -22721 $check-mu-copy-byte-to-stmt:error-invalid-dest-type: -22722 (write-buffered *(ebp+0x10) "fn ") -22723 8b/-> *(ebp+0xc) 0/r32/eax -22724 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22725 (write-buffered *(ebp+0x10) %eax) -22726 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: '") -22727 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22728 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22729 (write-buffered *(ebp+0x10) %eax) -22730 (write-buffered *(ebp+0x10) "' must be a byte\n") -22731 (flush *(ebp+0x10)) -22732 (stop *(ebp+0x14) 1) -22733 # never gets here -22734 -22735 $check-mu-copy-byte-to-stmt:error-src-too-large: -22736 (write-buffered *(ebp+0x10) "fn ") -22737 8b/-> *(ebp+0xc) 0/r32/eax -22738 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22739 (write-buffered *(ebp+0x10) %eax) -22740 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: '") -22741 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22742 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22743 (write-buffered *(ebp+0x10) %eax) -22744 (write-buffered *(ebp+0x10) "' is too large to copy\n") -22745 (flush *(ebp+0x10)) -22746 (stop *(ebp+0x14) 1) -22747 # never gets here -22748 -22749 check-mu-compare-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -22750 # . prologue -22751 55/push-ebp -22752 89/<- %ebp 4/r32/esp -22753 # . save registers -22754 50/push-eax -22755 51/push-ecx -22756 52/push-edx -22757 53/push-ebx -22758 56/push-esi -22759 57/push-edi -22760 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) -22761 81 5/subop/subtract %esp 0x60/imm32 -22762 68/push 0x60/imm32/size -22763 68/push 0/imm32/read -22764 68/push 0/imm32/write -22765 89/<- %edx 4/r32/esp -22766 # esi = stmt -22767 8b/-> *(ebp+8) 6/r32/esi -22768 $check-mu-compare-stmt:check-for-output: -22769 # if stmt->outputs abort -22770 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -22771 3d/compare-eax-and 0/imm32 -22772 0f 85/jump-if-!= $check-mu-compare-stmt:error-too-many-outputs/disp32 -22773 $check-mu-compare-stmt:get-left: -22774 # var left/edi: (addr stmt-var) = stmt->inouts -22775 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -22776 89/<- %edi 0/r32/eax -22777 # zero inouts -22778 3d/compare-eax-and 0/imm32 -22779 0f 84/jump-if-= $check-mu-compare-stmt:error-incorrect-inouts/disp32 -22780 $check-mu-compare-stmt:get-right: -22781 # var right/esi: (addr stmt-var) = left->next -22782 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -22783 89/<- %esi 0/r32/eax -22784 # 1 inout -22785 3d/compare-eax-and 0/imm32 -22786 0f 84/jump-if-= $check-mu-compare-stmt:error-incorrect-inouts/disp32 -22787 # > 2 inouts -22788 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -22789 3d/compare-eax-and 0/imm32 -22790 0f 85/jump-if-!= $check-mu-compare-stmt:error-incorrect-inouts/disp32 -22791 # if both inouts are in memory, abort -22792 { -22793 $check-mu-compare-stmt:both-in-mem: -22794 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22795 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax -22796 (simple-mu-type? %eax 0) # => eax -22797 3d/compare-eax-and 0/imm32 -22798 0f 85/jump-if-!= break/disp32 -22799 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22800 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -22801 3d/compare-eax-and 0/imm32 -22802 75/jump-if-!= break/disp8 -22803 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22804 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax -22805 (simple-mu-type? %eax 0) # => eax -22806 3d/compare-eax-and 0/imm32 -22807 75/jump-if-!= break/disp8 -22808 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22809 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -22810 3d/compare-eax-and 0/imm32 -22811 75/jump-if-!= break/disp8 -22812 e9/jump $check-mu-compare-stmt:error-both-in-memory/disp32 -22813 } -22814 $check-mu-compare-stmt:types: -22815 # var right-type/ecx: (addr type-tree) = right->value->type -22816 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22817 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22818 89/<- %ecx 0/r32/eax -22819 # if (right->is-deref?) right-type = right-type->payload -22820 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref -22821 3d/compare-eax-and 0/imm32/false -22822 { -22823 74/jump-if-= break/disp8 -22824 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -22825 # if right-type->right is null, right-type = right-type->left -22826 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -22827 { -22828 75/jump-if-!= break/disp8 -22829 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -22830 } -22831 89/<- %ecx 0/r32/eax -22832 } -22833 # if right-type is a literal string, abort -22834 (simple-mu-type? %ecx 0x10) # string-literal => eax -22835 3d/compare-eax-and 0/imm32/false -22836 0f 85/jump-if-!= $check-mu-compare-stmt:error-right-string-literal/disp32 -22837 # if right is not a scalar, abort -22838 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22839 (size-of %eax) # => eax -22840 3d/compare-eax-and 4/imm32 -22841 0f 8f/jump-if-> $check-mu-compare-stmt:error-right-too-large/disp32 -22842 # if left is not a scalar, abort -22843 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22844 (size-of %eax) # => eax -22845 3d/compare-eax-and 4/imm32 -22846 0f 8f/jump-if-> $check-mu-compare-stmt:error-left-too-large/disp32 -22847 # var left-type/ebx: (addr type-tree) = left->value->type -22848 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22849 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22850 89/<- %ebx 0/r32/eax -22851 # if (left->is-deref?) left-type = left-type->payload -22852 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref -22853 3d/compare-eax-and 0/imm32/false -22854 { -22855 74/jump-if-= break/disp8 -22856 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -22857 # if left-type->right is null, left-type = left-type->left -22858 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -22859 { -22860 75/jump-if-!= break/disp8 -22861 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -22862 } -22863 89/<- %ebx 0/r32/eax -22864 } -22865 # if (left-type == right-type) return -22866 (type-match? %ebx %ecx %edx) # => eax -22867 3d/compare-eax-and 0/imm32 -22868 0f 85/jump-if-!= $check-mu-compare-stmt:end/disp32 -22869 # if left is an addr and right is 0, return -22870 { -22871 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22872 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -22873 (mu-addr-type? %eax) # => eax -22874 3d/compare-eax-and 0/imm32/false -22875 74/jump-if-= break/disp8 -22876 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22877 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22878 (string-equal? %eax "0") # => eax -22879 3d/compare-eax-and 0/imm32/false -22880 74/jump-if-= break/disp8 -22881 eb/jump $check-mu-compare-stmt:end/disp8 -22882 } -22883 # if left is not number-like, abort -22884 (check-mu-numberlike-arg %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -22885 $check-mu-compare-stmt:end: -22886 # . reclaim locals -22887 81 0/subop/add %esp 0x6c/imm32 -22888 # . restore registers -22889 5f/pop-to-edi -22890 5e/pop-to-esi -22891 5b/pop-to-ebx -22892 5a/pop-to-edx -22893 59/pop-to-ecx -22894 58/pop-to-eax -22895 # . epilogue -22896 89/<- %esp 5/r32/ebp -22897 5d/pop-to-ebp -22898 c3/return -22899 -22900 $check-mu-compare-stmt:error-incorrect-inouts: -22901 (write-buffered *(ebp+0x10) "fn ") -22902 8b/-> *(ebp+0xc) 0/r32/eax -22903 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22904 (write-buffered *(ebp+0x10) %eax) -22905 (write-buffered *(ebp+0x10) ": stmt 'compare' must have two inouts\n") -22906 (flush *(ebp+0x10)) -22907 (stop *(ebp+0x14) 1) -22908 # never gets here -22909 -22910 $check-mu-compare-stmt:error-too-many-outputs: -22911 (write-buffered *(ebp+0x10) "fn ") -22912 8b/-> *(ebp+0xc) 0/r32/eax -22913 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22914 (write-buffered *(ebp+0x10) %eax) -22915 (write-buffered *(ebp+0x10) ": stmt 'compare' must not have any outputs\n") -22916 (flush *(ebp+0x10)) -22917 (stop *(ebp+0x14) 1) -22918 # never gets here -22919 -22920 $check-mu-compare-stmt:error-both-in-memory: -22921 (write-buffered *(ebp+0x10) "fn ") -22922 8b/-> *(ebp+0xc) 0/r32/eax -22923 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22924 (write-buffered *(ebp+0x10) %eax) -22925 (write-buffered *(ebp+0x10) ": stmt compare: both inouts are in memory\n") -22926 (flush *(ebp+0x10)) -22927 (stop *(ebp+0x14) 1) -22928 # never gets here -22929 -22930 $check-mu-compare-stmt:error-left-too-large: -22931 (write-buffered *(ebp+0x10) "fn ") -22932 8b/-> *(ebp+0xc) 0/r32/eax -22933 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22934 (write-buffered *(ebp+0x10) %eax) -22935 (write-buffered *(ebp+0x10) ": stmt compare: '") -22936 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -22937 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22938 (write-buffered *(ebp+0x10) %eax) -22939 (write-buffered *(ebp+0x10) "' is too large to compare\n") -22940 (flush *(ebp+0x10)) -22941 (stop *(ebp+0x14) 1) -22942 # never gets here -22943 -22944 $check-mu-compare-stmt:error-right-too-large: -22945 (write-buffered *(ebp+0x10) "fn ") -22946 8b/-> *(ebp+0xc) 0/r32/eax -22947 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22948 (write-buffered *(ebp+0x10) %eax) -22949 (write-buffered *(ebp+0x10) ": stmt compare: '") -22950 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22951 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22952 (write-buffered *(ebp+0x10) %eax) -22953 (write-buffered *(ebp+0x10) "' is too large to compare\n") -22954 (flush *(ebp+0x10)) -22955 (stop *(ebp+0x14) 1) -22956 # never gets here -22957 -22958 $check-mu-compare-stmt:error-right-string-literal: -22959 (write-buffered *(ebp+0x10) "fn ") -22960 8b/-> *(ebp+0xc) 0/r32/eax -22961 (lookup *eax *(eax+4)) # Function-name Function-name => eax -22962 (write-buffered *(ebp+0x10) %eax) -22963 (write-buffered *(ebp+0x10) ": stmt compare: string literal ") -22964 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -22965 (lookup *eax *(eax+4)) # Var-name Var-name => eax -22966 (write-buffered *(ebp+0x10) %eax) -22967 (write-buffered *(ebp+0x10) " is not supported; use the string-equal? function\n") -22968 (flush *(ebp+0x10)) -22969 (stop *(ebp+0x14) 1) -22970 # never gets here -22971 -22972 check-mu-address-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -22973 # . prologue -22974 55/push-ebp -22975 89/<- %ebp 4/r32/esp -22976 # . save registers -22977 50/push-eax -22978 51/push-ecx -22979 52/push-edx -22980 56/push-esi -22981 57/push-edi -22982 $check-mu-address-stmt:get-output: -22983 # esi = stmt -22984 8b/-> *(ebp+8) 6/r32/esi -22985 # var output/edi: (addr stmt-var) = stmt->outputs -22986 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -22987 89/<- %edi 0/r32/eax -22988 # zero outputs -22989 3d/compare-eax-and 0/imm32 -22990 0f 84/jump-if-= $check-mu-address-stmt:error-no-output/disp32 -22991 # > 1 output -22992 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -22993 3d/compare-eax-and 0/imm32 -22994 0f 85/jump-if-!= $check-mu-address-stmt:error-too-many-outputs/disp32 -22995 $check-mu-address-stmt:get-inout: -22996 # var inout/esi: (addr stmt-var) = stmt->inouts -22997 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -22998 89/<- %esi 0/r32/eax -22999 # zero inouts -23000 3d/compare-eax-and 0/imm32 -23001 0f 84/jump-if-= $check-mu-address-stmt:error-no-inout/disp32 -23002 # > 1 inout -23003 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -23004 3d/compare-eax-and 0/imm32 -23005 0f 85/jump-if-!= $check-mu-address-stmt:error-too-many-inouts/disp32 -23006 $check-mu-address-stmt:types: -23007 # if output not in register, abort -23008 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23009 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -23010 3d/compare-eax-and 0/imm32 -23011 0f 84/jump-if-= $check-mu-address-stmt:error-output-not-in-register/disp32 -23012 # var output-type/edx: (addr type-tree) = output->value->type -23013 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23014 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -23015 89/<- %edx 0/r32/eax -23016 # if output-type not an addr, abort -23017 (mu-addr-type? %edx) # => eax -23018 3d/compare-eax-and 0/imm32/false -23019 0f 84/jump-if-= $check-mu-address-stmt:error-output-not-address/disp32 -23020 # output-type = output-type->right -23021 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax -23022 # if output-type->right is null, output-type = output-type->left -23023 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -23024 { -23025 75/jump-if-!= break/disp8 -23026 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23027 } -23028 89/<- %edx 0/r32/eax -23029 # var inout-type/ecx: (addr type-tree) = inout->value->type -23030 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -23031 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -23032 89/<- %ecx 0/r32/eax -23033 # if (inout->is-deref?) inout-type = inout-type->payload -23034 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref -23035 3d/compare-eax-and 0/imm32/false -23036 { -23037 74/jump-if-= break/disp8 -23038 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -23039 # if inout-type->right is null, t = inout-type->left -23040 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -23041 { -23042 75/jump-if-!= break/disp8 -23043 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23044 } -23045 89/<- %ecx 0/r32/eax -23046 } -23047 # if (inout-type != output-type) abort -23048 (type-equal-ignoring-capacity? %edx %ecx) # => eax -23049 3d/compare-eax-and 0/imm32 -23050 0f 84/jump-if-= $check-mu-address-stmt:error-type-mismatch/disp32 -23051 $check-mu-address-stmt:end: -23052 # . restore registers -23053 5f/pop-to-edi -23054 5e/pop-to-esi -23055 5a/pop-to-edx -23056 59/pop-to-ecx -23057 58/pop-to-eax -23058 # . epilogue -23059 89/<- %esp 5/r32/ebp -23060 5d/pop-to-ebp -23061 c3/return -23062 -23063 $check-mu-address-stmt:error-no-inout: -23064 (write-buffered *(ebp+0x10) "fn ") -23065 8b/-> *(ebp+0xc) 0/r32/eax -23066 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23067 (write-buffered *(ebp+0x10) %eax) -23068 (write-buffered *(ebp+0x10) ": stmt 'address' expects an inout\n") -23069 (flush *(ebp+0x10)) -23070 (stop *(ebp+0x14) 1) -23071 # never gets here -23072 -23073 $check-mu-address-stmt:error-too-many-inouts: -23074 (write-buffered *(ebp+0x10) "fn ") -23075 8b/-> *(ebp+0xc) 0/r32/eax -23076 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23077 (write-buffered *(ebp+0x10) %eax) -23078 (write-buffered *(ebp+0x10) ": stmt 'address' must have just one inout\n") -23079 (flush *(ebp+0x10)) -23080 (stop *(ebp+0x14) 1) -23081 # never gets here -23082 -23083 $check-mu-address-stmt:error-no-output: -23084 (write-buffered *(ebp+0x10) "fn ") -23085 8b/-> *(ebp+0xc) 0/r32/eax -23086 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23087 (write-buffered *(ebp+0x10) %eax) -23088 (write-buffered *(ebp+0x10) ": stmt 'address' expects an output\n") -23089 (flush *(ebp+0x10)) -23090 (stop *(ebp+0x14) 1) -23091 # never gets here -23092 -23093 $check-mu-address-stmt:error-output-not-in-register: -23094 (write-buffered *(ebp+0x10) "fn ") -23095 8b/-> *(ebp+0xc) 0/r32/eax -23096 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23097 (write-buffered *(ebp+0x10) %eax) -23098 (write-buffered *(ebp+0x10) ": stmt address: output '") -23099 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23100 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23101 (write-buffered *(ebp+0x10) %eax) -23102 (write-buffered *(ebp+0x10) "' not in a register\n") -23103 (flush *(ebp+0x10)) -23104 (stop *(ebp+0x14) 1) -23105 # never gets here -23106 -23107 $check-mu-address-stmt:error-too-many-outputs: -23108 (write-buffered *(ebp+0x10) "fn ") -23109 8b/-> *(ebp+0xc) 0/r32/eax -23110 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23111 (write-buffered *(ebp+0x10) %eax) -23112 (write-buffered *(ebp+0x10) ": stmt 'address' must have just one output\n") -23113 (flush *(ebp+0x10)) -23114 (stop *(ebp+0x14) 1) -23115 # never gets here -23116 -23117 $check-mu-address-stmt:error-output-not-address: -23118 (write-buffered *(ebp+0x10) "fn ") -23119 8b/-> *(ebp+0xc) 0/r32/eax -23120 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23121 (write-buffered *(ebp+0x10) %eax) -23122 (write-buffered *(ebp+0x10) ": stmt address: output '") -23123 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23124 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23125 (write-buffered *(ebp+0x10) %eax) -23126 (write-buffered *(ebp+0x10) "' is not an addr\n") -23127 (flush *(ebp+0x10)) -23128 (stop *(ebp+0x14) 1) -23129 # never gets here -23130 -23131 $check-mu-address-stmt:error-type-mismatch: -23132 (write-buffered *(ebp+0x10) "fn ") -23133 8b/-> *(ebp+0xc) 0/r32/eax -23134 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23135 (write-buffered *(ebp+0x10) %eax) -23136 (write-buffered *(ebp+0x10) ": stmt address: output '") -23137 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23138 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23139 (write-buffered *(ebp+0x10) %eax) -23140 (write-buffered *(ebp+0x10) "' cannot hold address of '") -23141 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -23142 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23143 (write-buffered *(ebp+0x10) %eax) -23144 (write-buffered *(ebp+0x10) "'\n") -23145 (flush *(ebp+0x10)) -23146 (stop *(ebp+0x14) 1) -23147 # never gets here -23148 -23149 type-equal-ignoring-capacity?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean -23150 # . prologue -23151 55/push-ebp -23152 89/<- %ebp 4/r32/esp -23153 # . save registers -23154 51/push-ecx -23155 52/push-edx -23156 53/push-ebx -23157 # var curr-a/ecx: (addr type-tree) = a -23158 8b/-> *(ebp+8) 1/r32/ecx -23159 # var curr-b/ebx: (addr type-tree) = b -23160 8b/-> *(ebp+0xc) 3/r32/ebx -23161 # if (curr-a->is-atom?) fall back to regular equality -23162 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -23163 0f 85/jump-if-!= $type-equal-ignoring-capacity?:base-case/disp32 -23164 # if (curr-a->left != curr-b->left) return false -23165 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -23166 89/<- %edx 0/r32/eax -23167 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -23168 (type-equal? %edx %eax) # => eax -23169 3d/compare-eax-and 0/imm32/false -23170 0f 84/jump-if-= $type-equal-ignoring-capacity?:end/disp32 # eax switches meaning -23171 # if (curr-a->left == "array") curr-a = curr-a->element-type -23172 { -23173 (mu-array? %edx) # => eax -23174 3d/compare-eax-and 0/imm32/false -23175 75/jump-if-!= break/disp8 -23176 $type-equal-ignoring-capacity?:array: -23177 # curr-a = curr-a->right->left -23178 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -23179 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23180 89/<- %ecx 0/r32/eax -23181 # curr-b = curr-b->right->left -23182 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -23183 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23184 89/<- %ebx 0/r32/eax -23185 eb/jump $type-equal-ignoring-capacity?:base-case/disp8 -23186 } -23187 # if (curr-a->left == "stream") curr-a = curr-a->element-type -23188 { -23189 (mu-stream? %edx) # => eax -23190 3d/compare-eax-and 0/imm32/false -23191 75/jump-if-!= break/disp8 -23192 $type-equal-ignoring-capacity?:stream: -23193 # curr-a = curr-a->right->left -23194 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -23195 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23196 89/<- %ecx 0/r32/eax -23197 # curr-b = curr-b->right->left -23198 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -23199 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23200 89/<- %ebx 0/r32/eax -23201 eb/jump $type-equal-ignoring-capacity?:base-case/disp8 -23202 } -23203 $type-equal-ignoring-capacity?:base-case: -23204 # return type-equal?(curr-a, curr-b) -23205 (type-equal? %ecx %ebx) # => eax -23206 $type-equal-ignoring-capacity?:end: -23207 # . restore registers -23208 5b/pop-to-ebx -23209 5a/pop-to-edx -23210 59/pop-to-ecx -23211 # . epilogue -23212 89/<- %esp 5/r32/ebp -23213 5d/pop-to-ebp -23214 c3/return -23215 -23216 check-mu-return-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -23217 # . prologue -23218 55/push-ebp -23219 89/<- %ebp 4/r32/esp -23220 # . save registers -23221 50/push-eax -23222 51/push-ecx -23223 52/push-edx -23224 53/push-ebx -23225 56/push-esi -23226 57/push-edi -23227 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) -23228 81 5/subop/subtract %esp 0x60/imm32 -23229 68/push 0x60/imm32/size -23230 68/push 0/imm32/read -23231 68/push 0/imm32/write -23232 89/<- %edx 4/r32/esp -23233 # var template/esi: (addr list var) = fn->outputs -23234 8b/-> *(ebp+0xc) 0/r32/eax -23235 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax -23236 89/<- %esi 0/r32/eax -23237 # var curr-template/ebx: (addr list var) = fn->outputs -23238 89/<- %ebx 0/r32/eax -23239 # var curr/edi: (addr stmt-var) = stmt->inouts -23240 8b/-> *(ebp+8) 0/r32/eax -23241 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -23242 89/<- %edi 0/r32/eax -23243 { -23244 # if template is null, break -23245 81 7/subop/compare %ebx 0/imm32 -23246 0f 84/jump-if-= break/disp32 -23247 # if curr is null, abort -23248 81 7/subop/compare %edi 0/imm32 -23249 0f 84/jump-if-= $check-mu-return-stmt:error-too-few-inouts/disp32 -23250 # var template-type/ecx: (addr type-tree) = template->value->type -23251 (lookup *ebx *(ebx+4)) # List-value List-value => eax -23252 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -23253 89/<- %ecx 0/r32/eax -23254 # var curr-type/eax: (addr type-tree) = curr->value->type -23255 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23256 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -23257 # if (curr->is-deref?) curr-type = payload of curr-type -23258 81 7/subop/compare *(edi+0x10) 0/imm32/false # Stmt-var-is-deref -23259 { -23260 74/jump-if-= break/disp8 -23261 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -23262 # if t->right is null, t = t->left -23263 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -23264 75/jump-if-!= break/disp8 -23265 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23266 } -23267 # if curr-type is literal and template-type is float, abort -23268 50/push-eax -23269 { -23270 (simple-mu-type? %eax 0) # literal => eax -23271 3d/compare-eax-and 0/imm32/false -23272 74/jump-if-= break/disp8 -23273 (simple-mu-type? %ecx 0xf) # float => eax -23274 3d/compare-eax-and 0/imm32/false -23275 0f 85/jump-if-!= $check-mu-return-stmt:error-literal-to-float/disp32 -23276 } -23277 58/pop-to-eax -23278 # if (curr-type != template-type) abort -23279 (type-match? %ecx %eax %edx) # => eax -23280 3d/compare-eax-and 0/imm32/false -23281 0f 84/jump-if-= $check-mu-return-stmt:error1/disp32 -23282 # if register-within-list-with-conflict?(curr, original template, curr-template, stmt) abort -23283 (register-within-list-with-conflict? %edi %esi %ebx *(ebp+8)) # => eax -23284 3d/compare-eax-and 0/imm32/false -23285 0f 85/jump-if-!= $check-mu-return-stmt:error2/disp32 -23286 # template = template->next -23287 (lookup *(ebx+8) *(ebx+0xc)) # List-next List-next => eax -23288 89/<- %ebx 0/r32/eax -23289 # curr = curr->next -23290 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -23291 89/<- %edi 0/r32/eax -23292 # -23293 e9/jump loop/disp32 -23294 } -23295 # if curr is not null, abort -23296 81 7/subop/compare %edi 0/imm32 -23297 0f 85/jump-if-!= $check-mu-return-stmt:error-too-many-inouts/disp32 -23298 $check-mu-return-stmt:end: -23299 # . reclaim locals -23300 81 0/subop/add %esp 0x6c/imm32 -23301 # . restore registers -23302 5f/pop-to-edi -23303 5e/pop-to-esi -23304 5b/pop-to-ebx -23305 5a/pop-to-edx -23306 59/pop-to-ecx -23307 58/pop-to-eax -23308 # . epilogue -23309 89/<- %esp 5/r32/ebp -23310 5d/pop-to-ebp -23311 c3/return -23312 -23313 $check-mu-return-stmt:error1: -23314 (write-buffered *(ebp+0x10) "fn ") -23315 8b/-> *(ebp+0xc) 0/r32/eax -23316 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23317 (write-buffered *(ebp+0x10) %eax) -23318 (write-buffered *(ebp+0x10) ": return: '") -23319 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23320 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23321 (write-buffered *(ebp+0x10) %eax) -23322 (write-buffered *(ebp+0x10) "' has the wrong type\n") -23323 (flush *(ebp+0x10)) -23324 (stop *(ebp+0x14) 1) -23325 # never gets here -23326 -23327 $check-mu-return-stmt:error2: -23328 (write-buffered *(ebp+0x10) "fn ") -23329 8b/-> *(ebp+0xc) 0/r32/eax -23330 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23331 (write-buffered *(ebp+0x10) %eax) -23332 (write-buffered *(ebp+0x10) ": return: '") -23333 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23334 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23335 (write-buffered *(ebp+0x10) %eax) -23336 (write-buffered *(ebp+0x10) "' is no longer available\n") -23337 (flush *(ebp+0x10)) -23338 (stop *(ebp+0x14) 1) -23339 # never gets here -23340 -23341 $check-mu-return-stmt:error-literal-to-float: -23342 (write-buffered *(ebp+0x10) "fn ") -23343 8b/-> *(ebp+0xc) 0/r32/eax -23344 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23345 (write-buffered *(ebp+0x10) %eax) -23346 (write-buffered *(ebp+0x10) ": return: cannot copy literal '") -23347 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -23348 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23349 (write-buffered *(ebp+0x10) %eax) -23350 (write-buffered *(ebp+0x10) "' to float\n") -23351 (flush *(ebp+0x10)) -23352 (stop *(ebp+0x14) 1) -23353 # never gets here -23354 -23355 $check-mu-return-stmt:error-too-few-inouts: -23356 (write-buffered *(ebp+0x10) "fn ") -23357 8b/-> *(ebp+0xc) 0/r32/eax -23358 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23359 (write-buffered *(ebp+0x10) %eax) -23360 (write-buffered *(ebp+0x10) ": return: too few inouts\n") -23361 (flush *(ebp+0x10)) -23362 (stop *(ebp+0x14) 1) -23363 # never gets here -23364 -23365 $check-mu-return-stmt:error-too-many-inouts: -23366 (write-buffered *(ebp+0x10) "fn ") -23367 8b/-> *(ebp+0xc) 0/r32/eax -23368 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23369 (write-buffered *(ebp+0x10) %eax) -23370 (write-buffered *(ebp+0x10) ": return: too many inouts\n") -23371 (flush *(ebp+0x10)) -23372 (stop *(ebp+0x14) 1) -23373 # never gets here -23374 -23375 check-all-unique-registers: # outputs: (addr list var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -23376 # . prologue -23377 55/push-ebp -23378 89/<- %ebp 4/r32/esp -23379 # . save registers -23380 50/push-eax -23381 51/push-ecx -23382 56/push-esi -23383 # var table/esi: (addr table (handle array byte) int 8) -23384 81 5/subop/subtract %esp 0x60/imm32 -23385 68/push 0x60/imm32/size -23386 68/push 0/imm32/read -23387 68/push 0/imm32/write -23388 89/<- %esi 4/r32/esp -23389 # var curr/ecx: (addr list var) = outputs -23390 8b/-> *(ebp+8) 1/r32/ecx -23391 { -23392 # if (curr == 0) break -23393 81 7/subop/compare %ecx 0/imm32 -23394 0f 84/jump-if-= break/disp32 -23395 # var reg/eax: (addr array byte) = curr->value->register # guaranteed to exist -23396 (lookup *ecx *(ecx+4)) # List-value List-value => eax -23397 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -23398 # if reg exists in table, abort -23399 (maybe-get %esi %eax 0xc) # => eax -23400 3d/compare-eax-and 0/imm32 -23401 0f 85/jump-if-!= $check-all-unique-registers:abort/disp32 -23402 # insert reg in table -23403 (lookup *ecx *(ecx+4)) # List-value List-value => eax -23404 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -23405 (get-or-insert %esi %eax 0xc Heap) -23406 # curr = curr->next -23407 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -23408 89/<- %ecx 0/r32/eax -23409 e9/jump loop/disp32 -23410 } -23411 $check-all-unique-registers:end: -23412 # . reclaim locals -23413 81 0/subop/add %esp 0x6c/imm32 -23414 # . restore registers -23415 5e/pop-to-esi -23416 59/pop-to-ecx -23417 58/pop-to-eax -23418 # . epilogue -23419 89/<- %esp 5/r32/ebp -23420 5d/pop-to-ebp -23421 c3/return -23422 -23423 $check-all-unique-registers:abort: -23424 (write-buffered *(ebp+0x10) "fn ") -23425 8b/-> *(ebp+0xc) 0/r32/eax -23426 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23427 (write-buffered *(ebp+0x10) %eax) -23428 (write-buffered *(ebp+0x10) ": outputs must be in unique registers\n") -23429 (flush *(ebp+0x10)) -23430 (stop *(ebp+0x14) 1) -23431 # never gets here -23432 -23433 # return false if s's register is not between start (inclusive) and end (exclusive) -23434 # return false if the positionally corresponding register in stmt->inouts (where s comes from) is also s's register -23435 # otherwise return true -23436 register-within-list-with-conflict?: # s: (addr stmt-var), start: (addr list var), end: (addr list var), stmt: (addr stmt) -> result/eax: boolean -23437 # . prologue -23438 55/push-ebp -23439 89/<- %ebp 4/r32/esp -23440 # . save registers -23441 51/push-ecx -23442 52/push-edx -23443 53/push-ebx -23444 56/push-esi -23445 57/push-edi -23446 # var target/ebx: (addr array byte) = s->value->register -23447 8b/-> *(ebp+8) 0/r32/eax -23448 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -23449 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -23450 #? (write-buffered Stderr "AA: ") -23451 #? (write-buffered Stderr %eax) -23452 #? (write-buffered Stderr Newline) -23453 #? (flush Stderr) -23454 # if (var->register == 0) return false -23455 3d/compare-eax-and 0/imm32 -23456 0f 84/jump-if-= $register-within-list-with-conflict?:end/disp32 # eax turns into result -23457 89/<- %ebx 0/r32/eax -23458 # var curr/ecx: (addr list var) = start -23459 8b/-> *(ebp+0xc) 1/r32/ecx -23460 # edx = end -23461 8b/-> *(ebp+0x10) 2/r32/edx -23462 { -23463 # if (curr == 0) break -23464 81 7/subop/compare %edi 0/imm32 -23465 0f 84/jump-if-= break/disp32 -23466 # if (curr == end) break -23467 39/compare %ecx 2/r32/edx -23468 0f 84/jump-if-= break/disp32 -23469 # var curr-reg/eax: (addr array byte) = curr->value->register -23470 (lookup *ecx *(ecx+4)) # List-value List-value => eax -23471 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -23472 # if (curr-reg == 0) continue -23473 3d/compare-eax-and 0/imm32 -23474 74/jump-if-= $register-within-list-with-conflict?:continue/disp8 -23475 # if (curr-reg == target) check for conflict -23476 (string-equal? %eax %ebx) # => eax -23477 3d/compare-eax-and 0/imm32/false -23478 { -23479 74/jump-if-= break/disp8 -23480 #? (write-buffered Stderr "conflict?\n") -23481 #? (flush Stderr) -23482 # var return-inouts/eax: (addr stmt-var) = stmt->inouts -23483 8b/-> *(ebp+0x14) 0/r32/eax -23484 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -23485 (register-conflict? %ebx %eax *(ebp+0xc)) # => eax -23486 eb/jump $register-within-list-with-conflict?:end/disp8 -23487 } -23488 $register-within-list-with-conflict?:continue: -23489 # curr = curr->next -23490 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -23491 89/<- %ecx 0/r32/eax -23492 e9/jump loop/disp32 -23493 } -23494 # return false -23495 b8/copy-to-eax 0/imm32/false -23496 $register-within-list-with-conflict?:end: -23497 # . restore registers -23498 5f/pop-to-edi -23499 5e/pop-to-esi -23500 5b/pop-to-ebx -23501 5a/pop-to-edx -23502 59/pop-to-ecx -23503 # . epilogue -23504 89/<- %esp 5/r32/ebp -23505 5d/pop-to-ebp -23506 c3/return -23507 -23508 # At the first occurrence of register 'reg' in fn-outputs, -23509 # check if the corresponding element of return-inouts has a different register. -23510 # This hacky helper is intended to be called in one specific place. Don't -23511 # reuse it as is. -23512 register-conflict?: # reg: (addr array byte), return-inouts: (addr stmt-var), fn-outputs: (addr list var) => result/eax: boolean -23513 # . prologue -23514 55/push-ebp -23515 89/<- %ebp 4/r32/esp -23516 # . save registers -23517 51/push-ecx -23518 52/push-edx -23519 53/push-ebx -23520 56/push-esi -23521 57/push-edi -23522 #? (write-buffered Stderr "BB: ") -23523 #? (write-buffered Stderr *(ebp+8)) -23524 #? (write-buffered Stderr Newline) -23525 #? (flush Stderr) -23526 # var curr-output/edi: (addr list var) = fn-outputs -23527 8b/-> *(ebp+0x10) 7/r32/edi -23528 # var curr-inout/esi: (addr stmt-var) = return-inouts -23529 8b/-> *(ebp+0xc) 6/r32/esi -23530 { -23531 # if (curr-output == 0) abort -23532 81 7/subop/compare %edi 0/imm32 -23533 0f 84/jump-if-= break/disp32 -23534 # if (curr-output->value->register != reg) continue -23535 (lookup *edi *(edi+4)) # List-value List-value => eax -23536 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -23537 (string-equal? %eax *(ebp+8)) # => eax -23538 3d/compare-eax-and 0/imm32/false -23539 0f 84/jump-if= $register-conflict?:continue/disp32 -23540 #? (write-buffered Stderr "rescan\n") -23541 #? (flush Stderr) -23542 # var curr-reg/eax: (addr array byte) = curr-inout->value->register -23543 (lookup *esi *(esi+4)) # List-value List-value => eax -23544 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -23545 # if (curr-reg == 0) return true -23546 3d/compare-eax-and 0/imm32 -23547 { -23548 75/jump-if-!= break/disp8 -23549 #? (write-buffered Stderr "no register\n") -23550 #? (flush Stderr) -23551 b8/copy-to-eax 1/imm32/true -23552 e9/jump $register-conflict?:end/disp32 -23553 } -23554 # return (curr-reg != reg) -23555 (string-equal? %eax *(ebp+8)) # => eax -23556 3d/compare-eax-and 0/imm32/false -23557 0f 94/set-if-= %al -23558 #? (write-buffered Stderr "final: ") -23559 #? (write-int32-hex-buffered Stderr %eax) -23560 #? (write-buffered Stderr Newline) -23561 #? (flush Stderr) -23562 eb/jump $register-conflict?:end/disp8 -23563 $register-conflict?:continue: -23564 # curr-output = curr-output->next -23565 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -23566 89/<- %edi 0/r32/eax -23567 # curr-inout = curr-inout->next -23568 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -23569 89/<- %esi 0/r32/eax -23570 e9/jump loop/disp32 -23571 } -23572 # should never get here -23573 (write-buffered Stderr "register-conflict? misused\n") -23574 (flush Stderr) -23575 e8/call syscall_exit/disp32 -23576 $register-conflict?:end: -23577 # . restore registers -23578 5f/pop-to-edi -23579 5e/pop-to-esi -23580 5b/pop-to-ebx -23581 5a/pop-to-edx -23582 59/pop-to-ecx -23583 # . epilogue -23584 89/<- %esp 5/r32/ebp -23585 5d/pop-to-ebp -23586 c3/return -23587 -23588 check-final-stmt-is-return: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -23589 # . prologue -23590 55/push-ebp -23591 89/<- %ebp 4/r32/esp -23592 # . save registers -23593 50/push-eax -23594 51/push-ecx -23595 # var curr/ecx: (addr list stmt) = block->stmts -23596 8b/-> *(ebp+8) 0/r32/eax -23597 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax -23598 3d/compare-eax-and 0/imm32 -23599 74/jump-if-= $check-final-stmt-is-return:error/disp8 -23600 89/<- %ecx 0/r32/eax -23601 { -23602 # if curr->next == 0, break -23603 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -23604 3d/compare-eax-and 0/imm32 -23605 74/jump-if-= break/disp8 -23606 # curr = curr->next -23607 89/<- %ecx 0/r32/eax -23608 e9/jump loop/disp32 -23609 } -23610 $check-final-stmt-is-return:check-tag: -23611 # if curr->value->tag != Stmt1, abort -23612 (lookup *ecx *(ecx+4)) # List-value List-value => eax -23613 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag -23614 75/jump-if-!= $check-final-stmt-is-return:error/disp8 -23615 $check-final-stmt-is-return:check-operation: -23616 # if curr->operation != "return", abort -23617 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -23618 (string-equal? %eax "return") -23619 3d/compare-eax-and 0/imm32/false -23620 74/jump-if-= $check-final-stmt-is-return:error/disp8 -23621 $check-final-stmt-is-return:end: -23622 # . restore registers -23623 59/pop-to-ecx -23624 58/pop-to-eax -23625 # . epilogue -23626 89/<- %esp 5/r32/ebp -23627 5d/pop-to-ebp -23628 c3/return -23629 -23630 $check-final-stmt-is-return:error: -23631 (write-buffered *(ebp+0x10) "fn ") -23632 8b/-> *(ebp+0xc) 0/r32/eax -23633 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23634 (write-buffered *(ebp+0x10) %eax) -23635 (write-buffered *(ebp+0x10) ": final statement should be a 'return'\n") -23636 (flush *(ebp+0x10)) -23637 (stop *(ebp+0x14) 1) -23638 # never gets here -23639 -23640 check-no-breaks: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -23641 # . prologue -23642 55/push-ebp -23643 89/<- %ebp 4/r32/esp -23644 # . save registers -23645 50/push-eax -23646 51/push-ecx -23647 # var curr/ecx: (addr list stmt) = block->stmts -23648 8b/-> *(ebp+8) 0/r32/eax -23649 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax -23650 3d/compare-eax-and 0/imm32 -23651 0f 84/jump-if-= $check-no-breaks:end/disp32 -23652 89/<- %ecx 0/r32/eax -23653 { -23654 # if curr->next == 0, break -23655 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -23656 3d/compare-eax-and 0/imm32 -23657 74/jump-if-= break/disp8 -23658 # if curr->value->tag != Stmt1, continue -23659 (lookup *ecx *(ecx+4)) # List-value List-value => eax -23660 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag -23661 75/jump-if-!= $check-no-breaks:continue/disp8 -23662 # if curr->value->operation starts with "break", abort -23663 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -23664 (string-starts-with? %eax "break") # => eax -23665 3d/compare-eax-and 0/imm32/false -23666 75/jump-if-!= $check-no-breaks:error/disp8 -23667 $check-no-breaks:continue: -23668 # curr = curr->next -23669 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -23670 89/<- %ecx 0/r32/eax -23671 e9/jump loop/disp32 -23672 } -23673 $check-no-breaks:end: -23674 # . restore registers -23675 59/pop-to-ecx -23676 58/pop-to-eax -23677 # . epilogue -23678 89/<- %esp 5/r32/ebp -23679 5d/pop-to-ebp -23680 c3/return -23681 -23682 $check-no-breaks:error: -23683 (write-buffered *(ebp+0x10) "fn ") -23684 8b/-> *(ebp+0xc) 0/r32/eax -23685 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23686 (write-buffered *(ebp+0x10) %eax) -23687 (write-buffered *(ebp+0x10) " has outputs, so you cannot 'break' out of the outermost block. Use 'return'.\n") -23688 (flush *(ebp+0x10)) -23689 (stop *(ebp+0x14) 1) -23690 # never gets here -23691 -23692 check-mu-get-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -23693 # . prologue -23694 55/push-ebp -23695 89/<- %ebp 4/r32/esp -23696 # . save registers -23697 50/push-eax -23698 51/push-ecx -23699 52/push-edx -23700 53/push-ebx -23701 56/push-esi -23702 57/push-edi -23703 # esi = stmt -23704 8b/-> *(ebp+8) 6/r32/esi -23705 # - check for 0 inouts -23706 # var base/ecx: (addr var) = stmt->inouts->value -23707 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -23708 3d/compare-eax-and 0/imm32/false -23709 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 -23710 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -23711 89/<- %ecx 0/r32/eax -23712 $check-mu-get-stmt:check-base: -23713 # - check base type -23714 # if it's an 'addr', check that it's in a register -23715 # var base-type/ebx: (addr type-tree) = lookup(base->type) -23716 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -23717 89/<- %ebx 0/r32/eax -23718 { -23719 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -23720 0f 85/jump-if-!= break/disp32 -23721 $check-mu-get-stmt:base-is-compound: -23722 # if (type->left != addr) break -23723 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -23724 (simple-mu-type? %eax 2) # addr => eax -23725 3d/compare-eax-and 0/imm32/false -23726 74/jump-if-= break/disp8 -23727 $check-mu-get-stmt:base-is-addr: -23728 # now check for register -23729 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -23730 0f 84/jump-if-= $check-mu-get-stmt:error-base-type-addr-but-not-register/disp32 -23731 $check-mu-get-stmt:base-is-addr-in-register: -23732 # type->left is now an addr; skip it -23733 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -23734 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -23735 0f 85/jump-if-!= $check-mu-get-stmt:error-bad-base/disp32 -23736 $check-mu-get-stmt:base-is-addr-to-atom-in-register: -23737 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23738 89/<- %ebx 0/r32/eax -23739 } -23740 $check-mu-get-stmt:check-base-typeinfo: -23741 # ensure type is a container -23742 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -23743 { -23744 75/jump-if-!= break/disp8 -23745 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -23746 89/<- %ebx 0/r32/eax -23747 } -23748 # var base-type-id/ebx: type-id = base-type->value -23749 8b/-> *(ebx+4) 3/r32/ebx # Type-tree-value -23750 (container? %ebx) # => eax -23751 3d/compare-eax-and 0/imm32/false -23752 0f 84/jump-if-= $check-mu-get-stmt:error-bad-base/disp32 -23753 # var base-typeinfo/edx: (addr typeinfo) = find-typeinfo(base-type-id) -23754 # . var container/ecx: (handle typeinfo) -23755 68/push 0/imm32 -23756 68/push 0/imm32 -23757 89/<- %ecx 4/r32/esp -23758 # . -23759 (find-typeinfo %ebx %ecx) -23760 (lookup *ecx *(ecx+4)) # => eax -23761 # . reclaim container -23762 81 0/subop/add %esp 8/imm32 -23763 # . -23764 89/<- %edx 0/r32/eax -23765 # var offset/ecx: (addr stmt-var) = stmt->inouts->next -23766 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -23767 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -23768 89/<- %ecx 0/r32/eax -23769 # - check for 1 inout -23770 3d/compare-eax-and 0/imm32/false -23771 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 -23772 # var offset/ecx: (addr var) = lookup(offset->value) -23773 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -23774 89/<- %ecx 0/r32/eax -23775 # - check for valid field -23776 81 7/subop/compare *(ecx+0x14) -1/imm32/uninitialized # Var-offset -23777 0f 84/jump-if-= $check-mu-get-stmt:error-bad-field/disp32 -23778 # - check for too many inouts -23779 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -23780 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -23781 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -23782 3d/compare-eax-and 0/imm32/false -23783 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-inouts/disp32 -23784 # var output/edi: (addr var) = stmt->outputs->value -23785 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -23786 # - check for 0 outputs -23787 3d/compare-eax-and 0/imm32/false -23788 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-outputs/disp32 -23789 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -23790 89/<- %edi 0/r32/eax -23791 $check-mu-get-stmt:check-output-type: -23792 # - check output type -23793 # must be in register -23794 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -23795 3d/compare-eax-and 0/imm32 -23796 0f 84/jump-if-= $check-mu-get-stmt:error-output-not-in-register/disp32 -23797 # must have a non-atomic type -23798 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -23799 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -23800 0f 85/jump-if-!= $check-mu-get-stmt:error-output-type-not-address/disp32 -23801 # type must start with (addr ...) -23802 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23803 (simple-mu-type? %eax 2) # => eax -23804 3d/compare-eax-and 0/imm32/false -23805 0f 84/jump-if-= $check-mu-get-stmt:error-output-type-not-address/disp32 -23806 $check-mu-get-stmt:check-output-type-match: -23807 # payload of addr type must match 'type' definition -23808 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -23809 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -23810 # if (payload->right == null) payload = payload->left -23811 81 7/subop/compare *(eax+0xc) 0/imm32/null # Type-tree-right -23812 { -23813 75/jump-if-!= break/disp8 -23814 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -23815 } -23816 89/<- %edi 0/r32/eax -23817 # . var output-name/ecx: (addr array byte) -23818 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -23819 89/<- %ecx 0/r32/eax -23820 # . var base-typeinfo-entry/eax: (addr handle typeinfo-entry) -23821 (lookup *(edx+4) *(edx+8)) # Typeinfo-fields Typeinfo-fields => eax -23822 (get %eax %ecx 0x10) # => eax -23823 # . -23824 (lookup *eax *(eax+4)) # => eax -23825 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -23826 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -23827 # . -23828 (type-equal? %edi %eax) # => eax -23829 3d/compare-eax-and 0/imm32/false -23830 0f 84/jump-if-= $check-mu-get-stmt:error-bad-output-type/disp32 -23831 # - check for too many outputs -23832 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -23833 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -23834 3d/compare-eax-and 0/imm32/false -23835 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-outputs/disp32 -23836 $check-mu-get-stmt:end: -23837 # . restore registers -23838 5f/pop-to-edi -23839 5e/pop-to-esi -23840 5b/pop-to-ebx -23841 5a/pop-to-edx -23842 59/pop-to-ecx -23843 58/pop-to-eax -23844 # . epilogue -23845 89/<- %esp 5/r32/ebp -23846 5d/pop-to-ebp -23847 c3/return -23848 -23849 $check-mu-get-stmt:error-too-few-inouts: -23850 (write-buffered *(ebp+0x10) "fn ") -23851 8b/-> *(ebp+0xc) 0/r32/eax -23852 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23853 (write-buffered *(ebp+0x10) %eax) -23854 (write-buffered *(ebp+0x10) ": stmt get: too few inouts (2 required)\n") -23855 (flush *(ebp+0x10)) -23856 (stop *(ebp+0x14) 1) -23857 # never gets here -23858 -23859 $check-mu-get-stmt:error-too-many-inouts: -23860 (write-buffered *(ebp+0x10) "fn ") -23861 8b/-> *(ebp+0xc) 0/r32/eax -23862 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23863 (write-buffered *(ebp+0x10) %eax) -23864 (write-buffered *(ebp+0x10) ": stmt get: too many inouts (2 required)\n") -23865 (flush *(ebp+0x10)) -23866 (stop *(ebp+0x14) 1) -23867 # never gets here -23868 -23869 $check-mu-get-stmt:error-too-few-outputs: -23870 (write-buffered *(ebp+0x10) "fn ") -23871 8b/-> *(ebp+0xc) 0/r32/eax -23872 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23873 (write-buffered *(ebp+0x10) %eax) -23874 (write-buffered *(ebp+0x10) ": stmt get: must have an output\n") -23875 (flush *(ebp+0x10)) -23876 (stop *(ebp+0x14) 1) -23877 # never gets here -23878 -23879 $check-mu-get-stmt:error-too-many-outputs: -23880 (write-buffered *(ebp+0x10) "fn ") -23881 8b/-> *(ebp+0xc) 0/r32/eax -23882 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23883 (write-buffered *(ebp+0x10) %eax) -23884 (write-buffered *(ebp+0x10) ": stmt get: too many outputs (1 required)\n") -23885 (flush *(ebp+0x10)) -23886 (stop *(ebp+0x14) 1) -23887 # never gets here -23888 -23889 $check-mu-get-stmt:error-bad-base: -23890 # error("fn " fn ": stmt get: var '" base->name "' must have a 'type' definition\n") -23891 (write-buffered *(ebp+0x10) "fn ") -23892 8b/-> *(ebp+0xc) 0/r32/eax -23893 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23894 (write-buffered *(ebp+0x10) %eax) -23895 (write-buffered *(ebp+0x10) ": stmt get: var '") -23896 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -23897 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -23898 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23899 (write-buffered *(ebp+0x10) %eax) -23900 (write-buffered *(ebp+0x10) "' must have a 'type' definition\n") -23901 (flush *(ebp+0x10)) -23902 (stop *(ebp+0x14) 1) -23903 # never gets here -23904 -23905 $check-mu-get-stmt:error-base-type-addr-but-not-register: -23906 (write-buffered *(ebp+0x10) "fn ") -23907 8b/-> *(ebp+0xc) 0/r32/eax -23908 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23909 (write-buffered *(ebp+0x10) %eax) -23910 (write-buffered *(ebp+0x10) ": stmt get: var '") -23911 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -23912 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -23913 (lookup *eax *(eax+4)) # Var-name Var-name => eax -23914 (write-buffered *(ebp+0x10) %eax) -23915 (write-buffered *(ebp+0x10) "' is an 'addr' type, and so must live in a register\n") -23916 (flush *(ebp+0x10)) -23917 (stop *(ebp+0x14) 1) -23918 # never gets here -23919 -23920 $check-mu-get-stmt:error-bad-field: -23921 # error("fn " fn ": stmt get: type " type " has no member called '" curr->name "'\n") -23922 (write-buffered *(ebp+0x10) "fn ") -23923 8b/-> *(ebp+0xc) 0/r32/eax -23924 (lookup *eax *(eax+4)) # Function-name Function-name => eax -23925 (write-buffered *(ebp+0x10) %eax) -23926 (write-buffered *(ebp+0x10) ": stmt get: type '") -23927 # . write(Type-id->data[tmp]) -23928 bf/copy-to-edi Type-id/imm32 -23929 8b/-> *(edi+ebx<<2+0xc) 6/r32/esi -23930 { -23931 81 7/subop/compare %esi 0/imm32 -23932 74/jump-if-= break/disp8 -23933 (write-buffered *(ebp+0x10) %esi) -23934 } -23935 # . -23936 (write-buffered *(ebp+0x10) "' has no member called '") -23937 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -23938 (write-buffered *(ebp+0x10) %eax) -23939 (write-buffered *(ebp+0x10) "'\n") -23940 (flush *(ebp+0x10)) -23941 (stop *(ebp+0x14) 1) -23942 # never gets here -23943 -23944 $check-mu-get-stmt:error-output-not-in-register: +22078 89/<- %ecx 0/r32/eax +22079 # if (inout->is-deref?) inout-type = inout-type->payload +22080 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref +22081 3d/compare-eax-and 0/imm32/false +22082 { +22083 74/jump-if-= break/disp8 +22084 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +22085 # if inout-type->right is null, t = inout-type->left +22086 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +22087 { +22088 75/jump-if-!= break/disp8 +22089 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +22090 } +22091 89/<- %ecx 0/r32/eax +22092 } +22093 # if output not in register, abort +22094 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22095 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +22096 3d/compare-eax-and 0/imm32 +22097 0f 84/jump-if-= $check-mu-copy-stmt:error-output-not-in-register/disp32 +22098 # var output-type/eax: (addr type-tree) = output->value->type +22099 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22100 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22101 # if (inout-type == output-type) return +22102 (type-match? %eax %ecx %edx) # => eax +22103 3d/compare-eax-and 0/imm32 +22104 0f 85/jump-if-!= $check-mu-copy-stmt:end/disp32 +22105 # if output is an addr and inout is 0, return +22106 { +22107 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22108 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22109 (mu-addr-type? %eax) # => eax +22110 3d/compare-eax-and 0/imm32/false +22111 74/jump-if-= break/disp8 +22112 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22113 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22114 (string-equal? %eax "0") # => eax +22115 3d/compare-eax-and 0/imm32/false +22116 74/jump-if-= break/disp8 +22117 e9/jump $check-mu-copy-stmt:end/disp32 +22118 } +22119 # if output is an offset and inout is 0, return +22120 { +22121 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22122 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22123 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +22124 75/jump-if-!= break/disp8 +22125 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +22126 (simple-mu-type? %eax 7) # offset => eax +22127 3d/compare-eax-and 0/imm32/false +22128 74/jump-if-= break/disp8 +22129 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22130 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22131 (string-equal? %eax "0") # => eax +22132 3d/compare-eax-and 0/imm32/false +22133 74/jump-if-= break/disp8 +22134 e9/jump $check-mu-copy-stmt:end/disp32 +22135 } +22136 # if output is a byte, abort if inout is not a literal. Otherwise return. +22137 { +22138 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22139 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22140 (simple-mu-type? %eax 8) # byte => eax +22141 3d/compare-eax-and 0/imm32/false +22142 74/jump-if-= break/disp8 +22143 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22144 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22145 (simple-mu-type? %eax 0) # literal => eax +22146 3d/compare-eax-and 0/imm32/false +22147 0f 84/jump-if-= $check-mu-copy-stmt:error-non-literal-to-byte/disp32 +22148 eb/jump $check-mu-copy-stmt:end/disp8 +22149 } +22150 # if output is not number-like, abort +22151 (check-mu-numberlike-output %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +22152 $check-mu-copy-stmt:end: +22153 # . reclaim locals +22154 81 0/subop/add %esp 0x6c/imm32 +22155 # . restore registers +22156 5f/pop-to-edi +22157 5e/pop-to-esi +22158 5a/pop-to-edx +22159 59/pop-to-ecx +22160 58/pop-to-eax +22161 # . epilogue +22162 89/<- %esp 5/r32/ebp +22163 5d/pop-to-ebp +22164 c3/return +22165 +22166 $check-mu-copy-stmt:error-no-inout: +22167 (write-buffered *(ebp+0x10) "fn ") +22168 8b/-> *(ebp+0xc) 0/r32/eax +22169 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22170 (write-buffered *(ebp+0x10) %eax) +22171 (write-buffered *(ebp+0x10) ": stmt 'copy' expects an inout\n") +22172 (flush *(ebp+0x10)) +22173 (stop *(ebp+0x14) 1) +22174 # never gets here +22175 +22176 $check-mu-copy-stmt:error-too-many-inouts: +22177 (write-buffered *(ebp+0x10) "fn ") +22178 8b/-> *(ebp+0xc) 0/r32/eax +22179 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22180 (write-buffered *(ebp+0x10) %eax) +22181 (write-buffered *(ebp+0x10) ": stmt 'copy' must have just one inout\n") +22182 (flush *(ebp+0x10)) +22183 (stop *(ebp+0x14) 1) +22184 # never gets here +22185 +22186 $check-mu-copy-stmt:error-no-output: +22187 (write-buffered *(ebp+0x10) "fn ") +22188 8b/-> *(ebp+0xc) 0/r32/eax +22189 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22190 (write-buffered *(ebp+0x10) %eax) +22191 (write-buffered *(ebp+0x10) ": stmt 'copy' expects an output\n") +22192 (flush *(ebp+0x10)) +22193 (stop *(ebp+0x14) 1) +22194 # never gets here +22195 +22196 $check-mu-copy-stmt:error-output-not-in-register: +22197 (write-buffered *(ebp+0x10) "fn ") +22198 8b/-> *(ebp+0xc) 0/r32/eax +22199 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22200 (write-buffered *(ebp+0x10) %eax) +22201 (write-buffered *(ebp+0x10) ": stmt copy: output '") +22202 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22203 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22204 (write-buffered *(ebp+0x10) %eax) +22205 (write-buffered *(ebp+0x10) "' not in a register\n") +22206 (flush *(ebp+0x10)) +22207 (stop *(ebp+0x14) 1) +22208 # never gets here +22209 +22210 $check-mu-copy-stmt:error-too-many-outputs: +22211 (write-buffered *(ebp+0x10) "fn ") +22212 8b/-> *(ebp+0xc) 0/r32/eax +22213 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22214 (write-buffered *(ebp+0x10) %eax) +22215 (write-buffered *(ebp+0x10) ": stmt 'copy' must have just one output\n") +22216 (flush *(ebp+0x10)) +22217 (stop *(ebp+0x14) 1) +22218 # never gets here +22219 +22220 $check-mu-copy-stmt:error-inout-too-large: +22221 (write-buffered *(ebp+0x10) "fn ") +22222 8b/-> *(ebp+0xc) 0/r32/eax +22223 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22224 (write-buffered *(ebp+0x10) %eax) +22225 (write-buffered *(ebp+0x10) ": stmt copy: '") +22226 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22227 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22228 (write-buffered *(ebp+0x10) %eax) +22229 (write-buffered *(ebp+0x10) "' is too large to fit in a register\n") +22230 (flush *(ebp+0x10)) +22231 (stop *(ebp+0x14) 1) +22232 # never gets here +22233 +22234 $check-mu-copy-stmt:error-non-literal-to-byte: +22235 (write-buffered *(ebp+0x10) "fn ") +22236 8b/-> *(ebp+0xc) 0/r32/eax +22237 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22238 (write-buffered *(ebp+0x10) %eax) +22239 (write-buffered *(ebp+0x10) ": stmt copy: cannot copy non-literal to '") +22240 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22241 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22242 (write-buffered *(ebp+0x10) %eax) +22243 (write-buffered *(ebp+0x10) "' of type byte; use copy-byte\n") +22244 (flush *(ebp+0x10)) +22245 (stop *(ebp+0x14) 1) +22246 # never gets here +22247 +22248 check-mu-copy-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +22249 # . prologue +22250 55/push-ebp +22251 89/<- %ebp 4/r32/esp +22252 # . save registers +22253 50/push-eax +22254 51/push-ecx +22255 52/push-edx +22256 53/push-ebx +22257 56/push-esi +22258 57/push-edi +22259 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) +22260 81 5/subop/subtract %esp 0x60/imm32 +22261 68/push 0x60/imm32/size +22262 68/push 0/imm32/read +22263 68/push 0/imm32/write +22264 89/<- %edx 4/r32/esp +22265 # esi = stmt +22266 8b/-> *(ebp+8) 6/r32/esi +22267 $check-mu-copy-to-stmt:check-for-output: +22268 # if stmt->outputs abort +22269 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +22270 3d/compare-eax-and 0/imm32 +22271 0f 85/jump-if-!= $check-mu-copy-to-stmt:error-too-many-outputs/disp32 +22272 $check-mu-copy-to-stmt:get-dest: +22273 # var dest/edi: (addr stmt-var) = stmt->inouts +22274 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +22275 89/<- %edi 0/r32/eax +22276 # zero inouts +22277 3d/compare-eax-and 0/imm32 +22278 0f 84/jump-if-= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32 +22279 $check-mu-copy-to-stmt:get-src: +22280 # var src/esi: (addr stmt-var) = dest->next +22281 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +22282 89/<- %esi 0/r32/eax +22283 # 1 inout +22284 3d/compare-eax-and 0/imm32 +22285 0f 84/jump-if-= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32 +22286 # > 2 inouts +22287 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +22288 3d/compare-eax-and 0/imm32 +22289 0f 85/jump-if-!= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32 +22290 $check-mu-copy-to-stmt:types: +22291 # if src is not a scalar, abort +22292 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22293 (size-of %eax) # => eax +22294 3d/compare-eax-and 4/imm32 +22295 0f 8f/jump-if-> $check-mu-copy-to-stmt:error-src-too-large/disp32 +22296 # var src-type/ecx: (addr type-tree) = src->value->type +22297 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22298 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22299 89/<- %ecx 0/r32/eax +22300 # if src not in register or literal, abort +22301 # (we can't use stack-offset because it hasn't been computed yet) +22302 { +22303 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22304 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax +22305 (simple-mu-type? %eax 0) # => eax +22306 3d/compare-eax-and 0/imm32 +22307 75/jump-if-!= break/disp8 +22308 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22309 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +22310 3d/compare-eax-and 0/imm32 +22311 75/jump-if-!= break/disp8 +22312 e9/jump $check-mu-copy-to-stmt:error-src-not-literal-or-in-register/disp32 +22313 } +22314 # var dest-type/ebx: (addr type-tree) = dest->value->type +22315 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22316 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22317 89/<- %ebx 0/r32/eax +22318 # if (dest->is-deref?) dest-type = dest-type->payload +22319 $check-mu-copy-to-stmt:check-dest-deref: +22320 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref +22321 3d/compare-eax-and 0/imm32/false +22322 { +22323 74/jump-if-= break/disp8 +22324 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +22325 $check-mu-copy-to-stmt:dest-is-deref: +22326 # if dest-type->right is null, dest-type = dest-type->left +22327 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +22328 { +22329 75/jump-if-!= break/disp8 +22330 $check-mu-copy-to-stmt:dest-is-deref2: +22331 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +22332 } +22333 89/<- %ebx 0/r32/eax +22334 } +22335 # if dest is a byte and src is not a literal, abort +22336 { +22337 $check-mu-copy-to-stmt:final-check-byte: +22338 (simple-mu-type? %ebx 8) # byte => eax +22339 3d/compare-eax-and 0/imm32/false +22340 74/jump-if-= break/disp8 +22341 (simple-mu-type? %ecx 0) # literal => eax +22342 3d/compare-eax-and 0/imm32/false +22343 0f 84/jump-if-= $check-mu-copy-to-stmt:error-non-literal-to-byte/disp32 +22344 } +22345 # if (src-type == dest-type) return +22346 (type-match? %ebx %ecx %edx) # => eax +22347 3d/compare-eax-and 0/imm32 +22348 0f 85/jump-if-!= $check-mu-copy-to-stmt:end/disp32 +22349 # if dest is an addr and src is 0, return +22350 { +22351 $check-mu-copy-to-stmt:final-check-addr: +22352 (mu-addr-type? %ebx) # => eax +22353 3d/compare-eax-and 0/imm32/false +22354 74/jump-if-= break/disp8 +22355 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22356 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22357 (string-equal? %eax "0") # => eax +22358 3d/compare-eax-and 0/imm32/false +22359 74/jump-if-= break/disp8 +22360 e9/jump $check-mu-copy-to-stmt:end/disp32 +22361 } +22362 # if dest is an offset and src is 0, return +22363 { +22364 $check-mu-copy-to-stmt:final-check-offset: +22365 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +22366 75/jump-if-!= break/disp8 +22367 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +22368 (simple-mu-type? %eax 7) # offset => eax +22369 3d/compare-eax-and 0/imm32/false +22370 74/jump-if-= break/disp8 +22371 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22372 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22373 (string-equal? %eax "0") # => eax +22374 3d/compare-eax-and 0/imm32/false +22375 74/jump-if-= break/disp8 +22376 e9/jump $check-mu-copy-to-stmt:end/disp32 +22377 } +22378 # if dest is not number-like, abort +22379 (check-mu-numberlike-arg %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +22380 $check-mu-copy-to-stmt:end: +22381 # . reclaim locals +22382 81 0/subop/add %esp 0x6c/imm32 +22383 # . restore registers +22384 5f/pop-to-edi +22385 5e/pop-to-esi +22386 5b/pop-to-ebx +22387 5a/pop-to-edx +22388 59/pop-to-ecx +22389 58/pop-to-eax +22390 # . epilogue +22391 89/<- %esp 5/r32/ebp +22392 5d/pop-to-ebp +22393 c3/return +22394 +22395 $check-mu-copy-to-stmt:error-incorrect-inouts: +22396 (write-buffered *(ebp+0x10) "fn ") +22397 8b/-> *(ebp+0xc) 0/r32/eax +22398 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22399 (write-buffered *(ebp+0x10) %eax) +22400 (write-buffered *(ebp+0x10) ": stmt 'copy-to' must have two inouts\n") +22401 (flush *(ebp+0x10)) +22402 (stop *(ebp+0x14) 1) +22403 # never gets here +22404 +22405 $check-mu-copy-to-stmt:error-too-many-outputs: +22406 (write-buffered *(ebp+0x10) "fn ") +22407 8b/-> *(ebp+0xc) 0/r32/eax +22408 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22409 (write-buffered *(ebp+0x10) %eax) +22410 (write-buffered *(ebp+0x10) ": stmt 'copy-to' must not have any outputs\n") +22411 (flush *(ebp+0x10)) +22412 (stop *(ebp+0x14) 1) +22413 # never gets here +22414 +22415 $check-mu-copy-to-stmt:error-src-not-literal-or-in-register: +22416 (write-buffered *(ebp+0x10) "fn ") +22417 8b/-> *(ebp+0xc) 0/r32/eax +22418 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22419 (write-buffered *(ebp+0x10) %eax) +22420 (write-buffered *(ebp+0x10) ": stmt copy-to: source (second inout) is in memory\n") +22421 (flush *(ebp+0x10)) +22422 (stop *(ebp+0x14) 1) +22423 # never gets here +22424 +22425 $check-mu-copy-to-stmt:error-src-too-large: +22426 (write-buffered *(ebp+0x10) "fn ") +22427 8b/-> *(ebp+0xc) 0/r32/eax +22428 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22429 (write-buffered *(ebp+0x10) %eax) +22430 (write-buffered *(ebp+0x10) ": stmt copy-to: '") +22431 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22432 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22433 (write-buffered *(ebp+0x10) %eax) +22434 (write-buffered *(ebp+0x10) "' is too large to copy\n") +22435 (flush *(ebp+0x10)) +22436 (stop *(ebp+0x14) 1) +22437 # never gets here +22438 +22439 $check-mu-copy-to-stmt:error-non-literal-to-byte: +22440 (write-buffered *(ebp+0x10) "fn ") +22441 8b/-> *(ebp+0xc) 0/r32/eax +22442 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22443 (write-buffered *(ebp+0x10) %eax) +22444 (write-buffered *(ebp+0x10) ": stmt copy-to: cannot copy non-literal to type byte; use copy-byte-to\n") +22445 (flush *(ebp+0x10)) +22446 (stop *(ebp+0x14) 1) +22447 # never gets here +22448 +22449 check-mu-copy-byte-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +22450 # . prologue +22451 55/push-ebp +22452 89/<- %ebp 4/r32/esp +22453 # . save registers +22454 50/push-eax +22455 51/push-ecx +22456 52/push-edx +22457 56/push-esi +22458 57/push-edi +22459 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) +22460 81 5/subop/subtract %esp 0x60/imm32 +22461 68/push 0x60/imm32/size +22462 68/push 0/imm32/read +22463 68/push 0/imm32/write +22464 89/<- %edx 4/r32/esp +22465 $check-mu-copy-byte-stmt:get-output: +22466 # esi = stmt +22467 8b/-> *(ebp+8) 6/r32/esi +22468 # var output/edi: (addr stmt-var) = stmt->outputs +22469 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +22470 89/<- %edi 0/r32/eax +22471 # zero outputs +22472 3d/compare-eax-and 0/imm32 +22473 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-no-output/disp32 +22474 # > 1 output +22475 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +22476 3d/compare-eax-and 0/imm32 +22477 0f 85/jump-if-!= $check-mu-copy-byte-stmt:error-too-many-outputs/disp32 +22478 $check-mu-copy-byte-stmt:get-inout: +22479 # var inout/esi: (addr stmt-var) = stmt->inouts +22480 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +22481 89/<- %esi 0/r32/eax +22482 # zero inouts +22483 3d/compare-eax-and 0/imm32 +22484 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-no-inout/disp32 +22485 # > 1 inout +22486 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +22487 3d/compare-eax-and 0/imm32 +22488 0f 85/jump-if-!= $check-mu-copy-byte-stmt:error-too-many-inouts/disp32 +22489 $check-mu-copy-byte-stmt:types: +22490 # if inout is not a scalar, abort +22491 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22492 (size-of %eax) # => eax +22493 3d/compare-eax-and 4/imm32 +22494 0f 8f/jump-if-> $check-mu-copy-byte-stmt:error-inout-too-large/disp32 +22495 # var inout-type/ecx: (addr type-tree) = inout->value->type +22496 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22497 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22498 89/<- %ecx 0/r32/eax +22499 $check-mu-copy-byte-stmt:check-inout-deref: +22500 # if (inout->is-deref?) inout-type = inout-type->payload +22501 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref +22502 3d/compare-eax-and 0/imm32/false +22503 { +22504 74/jump-if-= break/disp8 +22505 $check-mu-copy-byte-stmt:inout-is-deref: +22506 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +22507 # if inout-type->right is null, t = inout-type->left +22508 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +22509 { +22510 75/jump-if-!= break/disp8 +22511 $check-mu-copy-byte-stmt:inout-is-deref2: +22512 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +22513 } +22514 89/<- %ecx 0/r32/eax +22515 } +22516 # if output not in register, abort +22517 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22518 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +22519 3d/compare-eax-and 0/imm32 +22520 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-output-not-in-register/disp32 +22521 # var output-type/eax: (addr type-tree) = output->value->type +22522 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22523 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22524 # if output is not of type byte, abort +22525 (simple-mu-type? %eax 8) # byte => eax +22526 3d/compare-eax-and 0/imm32 +22527 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-invalid-output-type/disp32 +22528 $check-mu-copy-byte-stmt:end: +22529 # . reclaim locals +22530 81 0/subop/add %esp 0x6c/imm32 +22531 # . restore registers +22532 5f/pop-to-edi +22533 5e/pop-to-esi +22534 5a/pop-to-edx +22535 59/pop-to-ecx +22536 58/pop-to-eax +22537 # . epilogue +22538 89/<- %esp 5/r32/ebp +22539 5d/pop-to-ebp +22540 c3/return +22541 +22542 $check-mu-copy-byte-stmt:error-no-inout: +22543 (write-buffered *(ebp+0x10) "fn ") +22544 8b/-> *(ebp+0xc) 0/r32/eax +22545 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22546 (write-buffered *(ebp+0x10) %eax) +22547 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' expects an inout\n") +22548 (flush *(ebp+0x10)) +22549 (stop *(ebp+0x14) 1) +22550 # never gets here +22551 +22552 $check-mu-copy-byte-stmt:error-too-many-inouts: +22553 (write-buffered *(ebp+0x10) "fn ") +22554 8b/-> *(ebp+0xc) 0/r32/eax +22555 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22556 (write-buffered *(ebp+0x10) %eax) +22557 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must have just one inout\n") +22558 (flush *(ebp+0x10)) +22559 (stop *(ebp+0x14) 1) +22560 # never gets here +22561 +22562 $check-mu-copy-byte-stmt:error-no-output: +22563 (write-buffered *(ebp+0x10) "fn ") +22564 8b/-> *(ebp+0xc) 0/r32/eax +22565 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22566 (write-buffered *(ebp+0x10) %eax) +22567 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' expects an output\n") +22568 (flush *(ebp+0x10)) +22569 (stop *(ebp+0x14) 1) +22570 # never gets here +22571 +22572 $check-mu-copy-byte-stmt:error-output-not-in-register: +22573 (write-buffered *(ebp+0x10) "fn ") +22574 8b/-> *(ebp+0xc) 0/r32/eax +22575 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22576 (write-buffered *(ebp+0x10) %eax) +22577 (write-buffered *(ebp+0x10) ": stmt copy-byte: output '") +22578 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22579 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22580 (write-buffered *(ebp+0x10) %eax) +22581 (write-buffered *(ebp+0x10) "' not in a register\n") +22582 (flush *(ebp+0x10)) +22583 (stop *(ebp+0x14) 1) +22584 # never gets here +22585 +22586 $check-mu-copy-byte-stmt:error-too-many-outputs: +22587 (write-buffered *(ebp+0x10) "fn ") +22588 8b/-> *(ebp+0xc) 0/r32/eax +22589 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22590 (write-buffered *(ebp+0x10) %eax) +22591 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must have just one output\n") +22592 (flush *(ebp+0x10)) +22593 (stop *(ebp+0x14) 1) +22594 # never gets here +22595 +22596 $check-mu-copy-byte-stmt:error-invalid-output-type: +22597 (write-buffered *(ebp+0x10) "fn ") +22598 8b/-> *(ebp+0xc) 0/r32/eax +22599 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22600 (write-buffered *(ebp+0x10) %eax) +22601 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must write to output of type byte\n") +22602 (flush *(ebp+0x10)) +22603 (stop *(ebp+0x14) 1) +22604 # never gets here +22605 +22606 $check-mu-copy-byte-stmt:error-inout-too-large: +22607 (write-buffered *(ebp+0x10) "fn ") +22608 8b/-> *(ebp+0xc) 0/r32/eax +22609 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22610 (write-buffered *(ebp+0x10) %eax) +22611 (write-buffered *(ebp+0x10) ": stmt copy-byte: '") +22612 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22613 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22614 (write-buffered *(ebp+0x10) %eax) +22615 (write-buffered *(ebp+0x10) "' is too large to fit in a register\n") +22616 (flush *(ebp+0x10)) +22617 (stop *(ebp+0x14) 1) +22618 # never gets here +22619 +22620 check-mu-copy-byte-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +22621 # . prologue +22622 55/push-ebp +22623 89/<- %ebp 4/r32/esp +22624 # . save registers +22625 50/push-eax +22626 52/push-edx +22627 53/push-ebx +22628 56/push-esi +22629 57/push-edi +22630 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) +22631 81 5/subop/subtract %esp 0x60/imm32 +22632 68/push 0x60/imm32/size +22633 68/push 0/imm32/read +22634 68/push 0/imm32/write +22635 89/<- %edx 4/r32/esp +22636 # esi = stmt +22637 8b/-> *(ebp+8) 6/r32/esi +22638 $check-mu-copy-byte-to-stmt:check-for-output: +22639 # if stmt->outputs abort +22640 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +22641 3d/compare-eax-and 0/imm32 +22642 0f 85/jump-if-!= $check-mu-copy-byte-to-stmt:error-too-many-outputs/disp32 +22643 $check-mu-copy-byte-to-stmt:get-dest: +22644 # var dest/edi: (addr stmt-var) = stmt->inouts +22645 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +22646 89/<- %edi 0/r32/eax +22647 # zero inouts +22648 3d/compare-eax-and 0/imm32 +22649 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32 +22650 $check-mu-copy-byte-to-stmt:get-src: +22651 # var src/esi: (addr stmt-var) = dest->next +22652 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +22653 89/<- %esi 0/r32/eax +22654 # 1 inout +22655 3d/compare-eax-and 0/imm32 +22656 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32 +22657 # > 2 inouts +22658 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +22659 3d/compare-eax-and 0/imm32 +22660 0f 85/jump-if-!= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32 +22661 $check-mu-copy-byte-to-stmt:types: +22662 # if src is not a scalar, abort +22663 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22664 (size-of %eax) # => eax +22665 3d/compare-eax-and 4/imm32 +22666 0f 8f/jump-if-> $check-mu-copy-byte-to-stmt:error-src-too-large/disp32 +22667 # if src not in register, abort +22668 { +22669 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22670 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +22671 3d/compare-eax-and 0/imm32 +22672 75/jump-if-!= break/disp8 +22673 e9/jump $check-mu-copy-byte-to-stmt:error-src-not-in-register/disp32 +22674 } +22675 # var dest-type/ebx: (addr type-tree) = dest->value->type +22676 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22677 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22678 89/<- %ebx 0/r32/eax +22679 # if (dest->is-deref?) dest-type = dest-type->payload +22680 $check-mu-copy-byte-to-stmt:check-dest-deref: +22681 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref +22682 3d/compare-eax-and 0/imm32/false +22683 { +22684 74/jump-if-= break/disp8 +22685 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +22686 $check-mu-copy-byte-to-stmt:dest-is-deref: +22687 # if dest-type->right is null, dest-type = dest-type->left +22688 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +22689 { +22690 75/jump-if-!= break/disp8 +22691 $check-mu-copy-byte-to-stmt:dest-is-deref2: +22692 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +22693 } +22694 89/<- %ebx 0/r32/eax +22695 } +22696 # if dest is not a byte, abort +22697 (simple-mu-type? %ebx 8) # byte => eax +22698 3d/compare-eax-and 0/imm32/false +22699 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-invalid-dest-type/disp32 +22700 $check-mu-copy-byte-to-stmt:end: +22701 # . reclaim locals +22702 81 0/subop/add %esp 0x6c/imm32 +22703 # . restore registers +22704 5f/pop-to-edi +22705 5e/pop-to-esi +22706 5b/pop-to-ebx +22707 5a/pop-to-edx +22708 58/pop-to-eax +22709 # . epilogue +22710 89/<- %esp 5/r32/ebp +22711 5d/pop-to-ebp +22712 c3/return +22713 +22714 $check-mu-copy-byte-to-stmt:error-incorrect-inouts: +22715 (write-buffered *(ebp+0x10) "fn ") +22716 8b/-> *(ebp+0xc) 0/r32/eax +22717 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22718 (write-buffered *(ebp+0x10) %eax) +22719 (write-buffered *(ebp+0x10) ": stmt 'copy-byte-to' must have two inouts\n") +22720 (flush *(ebp+0x10)) +22721 (stop *(ebp+0x14) 1) +22722 # never gets here +22723 +22724 $check-mu-copy-byte-to-stmt:error-too-many-outputs: +22725 (write-buffered *(ebp+0x10) "fn ") +22726 8b/-> *(ebp+0xc) 0/r32/eax +22727 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22728 (write-buffered *(ebp+0x10) %eax) +22729 (write-buffered *(ebp+0x10) ": stmt 'copy-byte-to' must not have any outputs\n") +22730 (flush *(ebp+0x10)) +22731 (stop *(ebp+0x14) 1) +22732 # never gets here +22733 +22734 $check-mu-copy-byte-to-stmt:error-src-not-in-register: +22735 (write-buffered *(ebp+0x10) "fn ") +22736 8b/-> *(ebp+0xc) 0/r32/eax +22737 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22738 (write-buffered *(ebp+0x10) %eax) +22739 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: source (second inout) must be in a register\n") +22740 (flush *(ebp+0x10)) +22741 (stop *(ebp+0x14) 1) +22742 # never gets here +22743 +22744 $check-mu-copy-byte-to-stmt:error-invalid-dest-type: +22745 (write-buffered *(ebp+0x10) "fn ") +22746 8b/-> *(ebp+0xc) 0/r32/eax +22747 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22748 (write-buffered *(ebp+0x10) %eax) +22749 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: '") +22750 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22751 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22752 (write-buffered *(ebp+0x10) %eax) +22753 (write-buffered *(ebp+0x10) "' must be a byte\n") +22754 (flush *(ebp+0x10)) +22755 (stop *(ebp+0x14) 1) +22756 # never gets here +22757 +22758 $check-mu-copy-byte-to-stmt:error-src-too-large: +22759 (write-buffered *(ebp+0x10) "fn ") +22760 8b/-> *(ebp+0xc) 0/r32/eax +22761 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22762 (write-buffered *(ebp+0x10) %eax) +22763 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: '") +22764 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22765 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22766 (write-buffered *(ebp+0x10) %eax) +22767 (write-buffered *(ebp+0x10) "' is too large to copy\n") +22768 (flush *(ebp+0x10)) +22769 (stop *(ebp+0x14) 1) +22770 # never gets here +22771 +22772 check-mu-compare-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +22773 # . prologue +22774 55/push-ebp +22775 89/<- %ebp 4/r32/esp +22776 # . save registers +22777 50/push-eax +22778 51/push-ecx +22779 52/push-edx +22780 53/push-ebx +22781 56/push-esi +22782 57/push-edi +22783 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) +22784 81 5/subop/subtract %esp 0x60/imm32 +22785 68/push 0x60/imm32/size +22786 68/push 0/imm32/read +22787 68/push 0/imm32/write +22788 89/<- %edx 4/r32/esp +22789 # esi = stmt +22790 8b/-> *(ebp+8) 6/r32/esi +22791 $check-mu-compare-stmt:check-for-output: +22792 # if stmt->outputs abort +22793 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +22794 3d/compare-eax-and 0/imm32 +22795 0f 85/jump-if-!= $check-mu-compare-stmt:error-too-many-outputs/disp32 +22796 $check-mu-compare-stmt:get-left: +22797 # var left/edi: (addr stmt-var) = stmt->inouts +22798 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +22799 89/<- %edi 0/r32/eax +22800 # zero inouts +22801 3d/compare-eax-and 0/imm32 +22802 0f 84/jump-if-= $check-mu-compare-stmt:error-incorrect-inouts/disp32 +22803 $check-mu-compare-stmt:get-right: +22804 # var right/esi: (addr stmt-var) = left->next +22805 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +22806 89/<- %esi 0/r32/eax +22807 # 1 inout +22808 3d/compare-eax-and 0/imm32 +22809 0f 84/jump-if-= $check-mu-compare-stmt:error-incorrect-inouts/disp32 +22810 # > 2 inouts +22811 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +22812 3d/compare-eax-and 0/imm32 +22813 0f 85/jump-if-!= $check-mu-compare-stmt:error-incorrect-inouts/disp32 +22814 # if both inouts are in memory, abort +22815 { +22816 $check-mu-compare-stmt:both-in-mem: +22817 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22818 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax +22819 (simple-mu-type? %eax 0) # => eax +22820 3d/compare-eax-and 0/imm32 +22821 0f 85/jump-if-!= break/disp32 +22822 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22823 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +22824 3d/compare-eax-and 0/imm32 +22825 75/jump-if-!= break/disp8 +22826 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22827 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax +22828 (simple-mu-type? %eax 0) # => eax +22829 3d/compare-eax-and 0/imm32 +22830 75/jump-if-!= break/disp8 +22831 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22832 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +22833 3d/compare-eax-and 0/imm32 +22834 75/jump-if-!= break/disp8 +22835 e9/jump $check-mu-compare-stmt:error-both-in-memory/disp32 +22836 } +22837 $check-mu-compare-stmt:types: +22838 # var right-type/ecx: (addr type-tree) = right->value->type +22839 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22840 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22841 89/<- %ecx 0/r32/eax +22842 # if (right->is-deref?) right-type = right-type->payload +22843 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref +22844 3d/compare-eax-and 0/imm32/false +22845 { +22846 74/jump-if-= break/disp8 +22847 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +22848 # if right-type->right is null, right-type = right-type->left +22849 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +22850 { +22851 75/jump-if-!= break/disp8 +22852 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +22853 } +22854 89/<- %ecx 0/r32/eax +22855 } +22856 # if right-type is a literal string, abort +22857 (simple-mu-type? %ecx 0x10) # string-literal => eax +22858 3d/compare-eax-and 0/imm32/false +22859 0f 85/jump-if-!= $check-mu-compare-stmt:error-right-string-literal/disp32 +22860 # if right is not a scalar, abort +22861 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22862 (size-of %eax) # => eax +22863 3d/compare-eax-and 4/imm32 +22864 0f 8f/jump-if-> $check-mu-compare-stmt:error-right-too-large/disp32 +22865 # if left is not a scalar, abort +22866 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22867 (size-of %eax) # => eax +22868 3d/compare-eax-and 4/imm32 +22869 0f 8f/jump-if-> $check-mu-compare-stmt:error-left-too-large/disp32 +22870 # var left-type/ebx: (addr type-tree) = left->value->type +22871 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22872 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22873 89/<- %ebx 0/r32/eax +22874 # if (left->is-deref?) left-type = left-type->payload +22875 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref +22876 3d/compare-eax-and 0/imm32/false +22877 { +22878 74/jump-if-= break/disp8 +22879 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +22880 # if left-type->right is null, left-type = left-type->left +22881 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +22882 { +22883 75/jump-if-!= break/disp8 +22884 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +22885 } +22886 89/<- %ebx 0/r32/eax +22887 } +22888 # if (left-type == right-type) return +22889 (type-match? %ebx %ecx %edx) # => eax +22890 3d/compare-eax-and 0/imm32 +22891 0f 85/jump-if-!= $check-mu-compare-stmt:end/disp32 +22892 # if left is an addr and right is 0, return +22893 { +22894 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22895 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +22896 (mu-addr-type? %eax) # => eax +22897 3d/compare-eax-and 0/imm32/false +22898 74/jump-if-= break/disp8 +22899 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22900 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22901 (string-equal? %eax "0") # => eax +22902 3d/compare-eax-and 0/imm32/false +22903 74/jump-if-= break/disp8 +22904 eb/jump $check-mu-compare-stmt:end/disp8 +22905 } +22906 # if left is not number-like, abort +22907 (check-mu-numberlike-arg %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +22908 $check-mu-compare-stmt:end: +22909 # . reclaim locals +22910 81 0/subop/add %esp 0x6c/imm32 +22911 # . restore registers +22912 5f/pop-to-edi +22913 5e/pop-to-esi +22914 5b/pop-to-ebx +22915 5a/pop-to-edx +22916 59/pop-to-ecx +22917 58/pop-to-eax +22918 # . epilogue +22919 89/<- %esp 5/r32/ebp +22920 5d/pop-to-ebp +22921 c3/return +22922 +22923 $check-mu-compare-stmt:error-incorrect-inouts: +22924 (write-buffered *(ebp+0x10) "fn ") +22925 8b/-> *(ebp+0xc) 0/r32/eax +22926 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22927 (write-buffered *(ebp+0x10) %eax) +22928 (write-buffered *(ebp+0x10) ": stmt 'compare' must have two inouts\n") +22929 (flush *(ebp+0x10)) +22930 (stop *(ebp+0x14) 1) +22931 # never gets here +22932 +22933 $check-mu-compare-stmt:error-too-many-outputs: +22934 (write-buffered *(ebp+0x10) "fn ") +22935 8b/-> *(ebp+0xc) 0/r32/eax +22936 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22937 (write-buffered *(ebp+0x10) %eax) +22938 (write-buffered *(ebp+0x10) ": stmt 'compare' must not have any outputs\n") +22939 (flush *(ebp+0x10)) +22940 (stop *(ebp+0x14) 1) +22941 # never gets here +22942 +22943 $check-mu-compare-stmt:error-both-in-memory: +22944 (write-buffered *(ebp+0x10) "fn ") +22945 8b/-> *(ebp+0xc) 0/r32/eax +22946 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22947 (write-buffered *(ebp+0x10) %eax) +22948 (write-buffered *(ebp+0x10) ": stmt compare: both inouts are in memory\n") +22949 (flush *(ebp+0x10)) +22950 (stop *(ebp+0x14) 1) +22951 # never gets here +22952 +22953 $check-mu-compare-stmt:error-left-too-large: +22954 (write-buffered *(ebp+0x10) "fn ") +22955 8b/-> *(ebp+0xc) 0/r32/eax +22956 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22957 (write-buffered *(ebp+0x10) %eax) +22958 (write-buffered *(ebp+0x10) ": stmt compare: '") +22959 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +22960 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22961 (write-buffered *(ebp+0x10) %eax) +22962 (write-buffered *(ebp+0x10) "' is too large to compare\n") +22963 (flush *(ebp+0x10)) +22964 (stop *(ebp+0x14) 1) +22965 # never gets here +22966 +22967 $check-mu-compare-stmt:error-right-too-large: +22968 (write-buffered *(ebp+0x10) "fn ") +22969 8b/-> *(ebp+0xc) 0/r32/eax +22970 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22971 (write-buffered *(ebp+0x10) %eax) +22972 (write-buffered *(ebp+0x10) ": stmt compare: '") +22973 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22974 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22975 (write-buffered *(ebp+0x10) %eax) +22976 (write-buffered *(ebp+0x10) "' is too large to compare\n") +22977 (flush *(ebp+0x10)) +22978 (stop *(ebp+0x14) 1) +22979 # never gets here +22980 +22981 $check-mu-compare-stmt:error-right-string-literal: +22982 (write-buffered *(ebp+0x10) "fn ") +22983 8b/-> *(ebp+0xc) 0/r32/eax +22984 (lookup *eax *(eax+4)) # Function-name Function-name => eax +22985 (write-buffered *(ebp+0x10) %eax) +22986 (write-buffered *(ebp+0x10) ": stmt compare: string literal ") +22987 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +22988 (lookup *eax *(eax+4)) # Var-name Var-name => eax +22989 (write-buffered *(ebp+0x10) %eax) +22990 (write-buffered *(ebp+0x10) " is not supported; use the string-equal? function\n") +22991 (flush *(ebp+0x10)) +22992 (stop *(ebp+0x14) 1) +22993 # never gets here +22994 +22995 check-mu-address-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +22996 # . prologue +22997 55/push-ebp +22998 89/<- %ebp 4/r32/esp +22999 # . save registers +23000 50/push-eax +23001 51/push-ecx +23002 52/push-edx +23003 56/push-esi +23004 57/push-edi +23005 $check-mu-address-stmt:get-output: +23006 # esi = stmt +23007 8b/-> *(ebp+8) 6/r32/esi +23008 # var output/edi: (addr stmt-var) = stmt->outputs +23009 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +23010 89/<- %edi 0/r32/eax +23011 # zero outputs +23012 3d/compare-eax-and 0/imm32 +23013 0f 84/jump-if-= $check-mu-address-stmt:error-no-output/disp32 +23014 # > 1 output +23015 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +23016 3d/compare-eax-and 0/imm32 +23017 0f 85/jump-if-!= $check-mu-address-stmt:error-too-many-outputs/disp32 +23018 $check-mu-address-stmt:get-inout: +23019 # var inout/esi: (addr stmt-var) = stmt->inouts +23020 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +23021 89/<- %esi 0/r32/eax +23022 # zero inouts +23023 3d/compare-eax-and 0/imm32 +23024 0f 84/jump-if-= $check-mu-address-stmt:error-no-inout/disp32 +23025 # > 1 inout +23026 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +23027 3d/compare-eax-and 0/imm32 +23028 0f 85/jump-if-!= $check-mu-address-stmt:error-too-many-inouts/disp32 +23029 $check-mu-address-stmt:types: +23030 # if output not in register, abort +23031 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23032 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +23033 3d/compare-eax-and 0/imm32 +23034 0f 84/jump-if-= $check-mu-address-stmt:error-output-not-in-register/disp32 +23035 # var output-type/edx: (addr type-tree) = output->value->type +23036 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23037 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +23038 89/<- %edx 0/r32/eax +23039 # if output-type not an addr, abort +23040 (mu-addr-type? %edx) # => eax +23041 3d/compare-eax-and 0/imm32/false +23042 0f 84/jump-if-= $check-mu-address-stmt:error-output-not-address/disp32 +23043 # output-type = output-type->right +23044 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax +23045 # if output-type->right is null, output-type = output-type->left +23046 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +23047 { +23048 75/jump-if-!= break/disp8 +23049 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23050 } +23051 89/<- %edx 0/r32/eax +23052 # var inout-type/ecx: (addr type-tree) = inout->value->type +23053 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +23054 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +23055 89/<- %ecx 0/r32/eax +23056 # if (inout->is-deref?) inout-type = inout-type->payload +23057 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref +23058 3d/compare-eax-and 0/imm32/false +23059 { +23060 74/jump-if-= break/disp8 +23061 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +23062 # if inout-type->right is null, t = inout-type->left +23063 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +23064 { +23065 75/jump-if-!= break/disp8 +23066 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23067 } +23068 89/<- %ecx 0/r32/eax +23069 } +23070 # if (inout-type != output-type) abort +23071 (type-equal-ignoring-capacity? %edx %ecx) # => eax +23072 3d/compare-eax-and 0/imm32 +23073 0f 84/jump-if-= $check-mu-address-stmt:error-type-mismatch/disp32 +23074 $check-mu-address-stmt:end: +23075 # . restore registers +23076 5f/pop-to-edi +23077 5e/pop-to-esi +23078 5a/pop-to-edx +23079 59/pop-to-ecx +23080 58/pop-to-eax +23081 # . epilogue +23082 89/<- %esp 5/r32/ebp +23083 5d/pop-to-ebp +23084 c3/return +23085 +23086 $check-mu-address-stmt:error-no-inout: +23087 (write-buffered *(ebp+0x10) "fn ") +23088 8b/-> *(ebp+0xc) 0/r32/eax +23089 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23090 (write-buffered *(ebp+0x10) %eax) +23091 (write-buffered *(ebp+0x10) ": stmt 'address' expects an inout\n") +23092 (flush *(ebp+0x10)) +23093 (stop *(ebp+0x14) 1) +23094 # never gets here +23095 +23096 $check-mu-address-stmt:error-too-many-inouts: +23097 (write-buffered *(ebp+0x10) "fn ") +23098 8b/-> *(ebp+0xc) 0/r32/eax +23099 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23100 (write-buffered *(ebp+0x10) %eax) +23101 (write-buffered *(ebp+0x10) ": stmt 'address' must have just one inout\n") +23102 (flush *(ebp+0x10)) +23103 (stop *(ebp+0x14) 1) +23104 # never gets here +23105 +23106 $check-mu-address-stmt:error-no-output: +23107 (write-buffered *(ebp+0x10) "fn ") +23108 8b/-> *(ebp+0xc) 0/r32/eax +23109 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23110 (write-buffered *(ebp+0x10) %eax) +23111 (write-buffered *(ebp+0x10) ": stmt 'address' expects an output\n") +23112 (flush *(ebp+0x10)) +23113 (stop *(ebp+0x14) 1) +23114 # never gets here +23115 +23116 $check-mu-address-stmt:error-output-not-in-register: +23117 (write-buffered *(ebp+0x10) "fn ") +23118 8b/-> *(ebp+0xc) 0/r32/eax +23119 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23120 (write-buffered *(ebp+0x10) %eax) +23121 (write-buffered *(ebp+0x10) ": stmt address: output '") +23122 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23123 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23124 (write-buffered *(ebp+0x10) %eax) +23125 (write-buffered *(ebp+0x10) "' not in a register\n") +23126 (flush *(ebp+0x10)) +23127 (stop *(ebp+0x14) 1) +23128 # never gets here +23129 +23130 $check-mu-address-stmt:error-too-many-outputs: +23131 (write-buffered *(ebp+0x10) "fn ") +23132 8b/-> *(ebp+0xc) 0/r32/eax +23133 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23134 (write-buffered *(ebp+0x10) %eax) +23135 (write-buffered *(ebp+0x10) ": stmt 'address' must have just one output\n") +23136 (flush *(ebp+0x10)) +23137 (stop *(ebp+0x14) 1) +23138 # never gets here +23139 +23140 $check-mu-address-stmt:error-output-not-address: +23141 (write-buffered *(ebp+0x10) "fn ") +23142 8b/-> *(ebp+0xc) 0/r32/eax +23143 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23144 (write-buffered *(ebp+0x10) %eax) +23145 (write-buffered *(ebp+0x10) ": stmt address: output '") +23146 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23147 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23148 (write-buffered *(ebp+0x10) %eax) +23149 (write-buffered *(ebp+0x10) "' is not an addr\n") +23150 (flush *(ebp+0x10)) +23151 (stop *(ebp+0x14) 1) +23152 # never gets here +23153 +23154 $check-mu-address-stmt:error-type-mismatch: +23155 (write-buffered *(ebp+0x10) "fn ") +23156 8b/-> *(ebp+0xc) 0/r32/eax +23157 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23158 (write-buffered *(ebp+0x10) %eax) +23159 (write-buffered *(ebp+0x10) ": stmt address: output '") +23160 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23161 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23162 (write-buffered *(ebp+0x10) %eax) +23163 (write-buffered *(ebp+0x10) "' cannot hold address of '") +23164 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +23165 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23166 (write-buffered *(ebp+0x10) %eax) +23167 (write-buffered *(ebp+0x10) "'\n") +23168 (flush *(ebp+0x10)) +23169 (stop *(ebp+0x14) 1) +23170 # never gets here +23171 +23172 type-equal-ignoring-capacity?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean +23173 # . prologue +23174 55/push-ebp +23175 89/<- %ebp 4/r32/esp +23176 # . save registers +23177 51/push-ecx +23178 52/push-edx +23179 53/push-ebx +23180 # var curr-a/ecx: (addr type-tree) = a +23181 8b/-> *(ebp+8) 1/r32/ecx +23182 # var curr-b/ebx: (addr type-tree) = b +23183 8b/-> *(ebp+0xc) 3/r32/ebx +23184 # if (curr-a->is-atom?) fall back to regular equality +23185 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +23186 0f 85/jump-if-!= $type-equal-ignoring-capacity?:base-case/disp32 +23187 # if (curr-a->left != curr-b->left) return false +23188 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +23189 89/<- %edx 0/r32/eax +23190 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +23191 (type-equal? %edx %eax) # => eax +23192 3d/compare-eax-and 0/imm32/false +23193 0f 84/jump-if-= $type-equal-ignoring-capacity?:end/disp32 # eax switches meaning +23194 # if (curr-a->left == "array") curr-a = curr-a->element-type +23195 { +23196 (mu-array? %edx) # => eax +23197 3d/compare-eax-and 0/imm32/false +23198 75/jump-if-!= break/disp8 +23199 $type-equal-ignoring-capacity?:array: +23200 # curr-a = curr-a->right->left +23201 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +23202 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23203 89/<- %ecx 0/r32/eax +23204 # curr-b = curr-b->right->left +23205 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +23206 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23207 89/<- %ebx 0/r32/eax +23208 eb/jump $type-equal-ignoring-capacity?:base-case/disp8 +23209 } +23210 # if (curr-a->left == "stream") curr-a = curr-a->element-type +23211 { +23212 (mu-stream? %edx) # => eax +23213 3d/compare-eax-and 0/imm32/false +23214 75/jump-if-!= break/disp8 +23215 $type-equal-ignoring-capacity?:stream: +23216 # curr-a = curr-a->right->left +23217 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +23218 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23219 89/<- %ecx 0/r32/eax +23220 # curr-b = curr-b->right->left +23221 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +23222 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23223 89/<- %ebx 0/r32/eax +23224 eb/jump $type-equal-ignoring-capacity?:base-case/disp8 +23225 } +23226 $type-equal-ignoring-capacity?:base-case: +23227 # return type-equal?(curr-a, curr-b) +23228 (type-equal? %ecx %ebx) # => eax +23229 $type-equal-ignoring-capacity?:end: +23230 # . restore registers +23231 5b/pop-to-ebx +23232 5a/pop-to-edx +23233 59/pop-to-ecx +23234 # . epilogue +23235 89/<- %esp 5/r32/ebp +23236 5d/pop-to-ebp +23237 c3/return +23238 +23239 check-mu-return-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +23240 # . prologue +23241 55/push-ebp +23242 89/<- %ebp 4/r32/esp +23243 # . save registers +23244 50/push-eax +23245 51/push-ecx +23246 52/push-edx +23247 53/push-ebx +23248 56/push-esi +23249 57/push-edi +23250 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8) +23251 81 5/subop/subtract %esp 0x60/imm32 +23252 68/push 0x60/imm32/size +23253 68/push 0/imm32/read +23254 68/push 0/imm32/write +23255 89/<- %edx 4/r32/esp +23256 # var template/esi: (addr list var) = fn->outputs +23257 8b/-> *(ebp+0xc) 0/r32/eax +23258 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax +23259 89/<- %esi 0/r32/eax +23260 # var curr-template/ebx: (addr list var) = fn->outputs +23261 89/<- %ebx 0/r32/eax +23262 # var curr/edi: (addr stmt-var) = stmt->inouts +23263 8b/-> *(ebp+8) 0/r32/eax +23264 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +23265 89/<- %edi 0/r32/eax +23266 { +23267 # if template is null, break +23268 81 7/subop/compare %ebx 0/imm32 +23269 0f 84/jump-if-= break/disp32 +23270 # if curr is null, abort +23271 81 7/subop/compare %edi 0/imm32 +23272 0f 84/jump-if-= $check-mu-return-stmt:error-too-few-inouts/disp32 +23273 # var template-type/ecx: (addr type-tree) = template->value->type +23274 (lookup *ebx *(ebx+4)) # List-value List-value => eax +23275 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +23276 89/<- %ecx 0/r32/eax +23277 # var curr-type/eax: (addr type-tree) = curr->value->type +23278 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23279 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +23280 # if (curr->is-deref?) curr-type = payload of curr-type +23281 81 7/subop/compare *(edi+0x10) 0/imm32/false # Stmt-var-is-deref +23282 { +23283 74/jump-if-= break/disp8 +23284 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +23285 # if t->right is null, t = t->left +23286 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +23287 75/jump-if-!= break/disp8 +23288 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23289 } +23290 # if curr-type is literal and template-type is float, abort +23291 50/push-eax +23292 { +23293 (simple-mu-type? %eax 0) # literal => eax +23294 3d/compare-eax-and 0/imm32/false +23295 74/jump-if-= break/disp8 +23296 (simple-mu-type? %ecx 0xf) # float => eax +23297 3d/compare-eax-and 0/imm32/false +23298 0f 85/jump-if-!= $check-mu-return-stmt:error-literal-to-float/disp32 +23299 } +23300 58/pop-to-eax +23301 # if (curr-type != template-type) abort +23302 (type-match? %ecx %eax %edx) # => eax +23303 3d/compare-eax-and 0/imm32/false +23304 0f 84/jump-if-= $check-mu-return-stmt:error1/disp32 +23305 # if register-within-list-with-conflict?(curr, original template, curr-template, stmt) abort +23306 (register-within-list-with-conflict? %edi %esi %ebx *(ebp+8)) # => eax +23307 3d/compare-eax-and 0/imm32/false +23308 0f 85/jump-if-!= $check-mu-return-stmt:error2/disp32 +23309 # template = template->next +23310 (lookup *(ebx+8) *(ebx+0xc)) # List-next List-next => eax +23311 89/<- %ebx 0/r32/eax +23312 # curr = curr->next +23313 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +23314 89/<- %edi 0/r32/eax +23315 # +23316 e9/jump loop/disp32 +23317 } +23318 # if curr is not null, abort +23319 81 7/subop/compare %edi 0/imm32 +23320 0f 85/jump-if-!= $check-mu-return-stmt:error-too-many-inouts/disp32 +23321 $check-mu-return-stmt:end: +23322 # . reclaim locals +23323 81 0/subop/add %esp 0x6c/imm32 +23324 # . restore registers +23325 5f/pop-to-edi +23326 5e/pop-to-esi +23327 5b/pop-to-ebx +23328 5a/pop-to-edx +23329 59/pop-to-ecx +23330 58/pop-to-eax +23331 # . epilogue +23332 89/<- %esp 5/r32/ebp +23333 5d/pop-to-ebp +23334 c3/return +23335 +23336 $check-mu-return-stmt:error1: +23337 (write-buffered *(ebp+0x10) "fn ") +23338 8b/-> *(ebp+0xc) 0/r32/eax +23339 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23340 (write-buffered *(ebp+0x10) %eax) +23341 (write-buffered *(ebp+0x10) ": return: '") +23342 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23343 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23344 (write-buffered *(ebp+0x10) %eax) +23345 (write-buffered *(ebp+0x10) "' has the wrong type\n") +23346 (flush *(ebp+0x10)) +23347 (stop *(ebp+0x14) 1) +23348 # never gets here +23349 +23350 $check-mu-return-stmt:error2: +23351 (write-buffered *(ebp+0x10) "fn ") +23352 8b/-> *(ebp+0xc) 0/r32/eax +23353 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23354 (write-buffered *(ebp+0x10) %eax) +23355 (write-buffered *(ebp+0x10) ": return: '") +23356 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23357 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23358 (write-buffered *(ebp+0x10) %eax) +23359 (write-buffered *(ebp+0x10) "' is no longer available\n") +23360 (flush *(ebp+0x10)) +23361 (stop *(ebp+0x14) 1) +23362 # never gets here +23363 +23364 $check-mu-return-stmt:error-literal-to-float: +23365 (write-buffered *(ebp+0x10) "fn ") +23366 8b/-> *(ebp+0xc) 0/r32/eax +23367 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23368 (write-buffered *(ebp+0x10) %eax) +23369 (write-buffered *(ebp+0x10) ": return: cannot copy literal '") +23370 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +23371 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23372 (write-buffered *(ebp+0x10) %eax) +23373 (write-buffered *(ebp+0x10) "' to float\n") +23374 (flush *(ebp+0x10)) +23375 (stop *(ebp+0x14) 1) +23376 # never gets here +23377 +23378 $check-mu-return-stmt:error-too-few-inouts: +23379 (write-buffered *(ebp+0x10) "fn ") +23380 8b/-> *(ebp+0xc) 0/r32/eax +23381 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23382 (write-buffered *(ebp+0x10) %eax) +23383 (write-buffered *(ebp+0x10) ": return: too few inouts\n") +23384 (flush *(ebp+0x10)) +23385 (stop *(ebp+0x14) 1) +23386 # never gets here +23387 +23388 $check-mu-return-stmt:error-too-many-inouts: +23389 (write-buffered *(ebp+0x10) "fn ") +23390 8b/-> *(ebp+0xc) 0/r32/eax +23391 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23392 (write-buffered *(ebp+0x10) %eax) +23393 (write-buffered *(ebp+0x10) ": return: too many inouts\n") +23394 (flush *(ebp+0x10)) +23395 (stop *(ebp+0x14) 1) +23396 # never gets here +23397 +23398 check-all-unique-registers: # outputs: (addr list var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +23399 # . prologue +23400 55/push-ebp +23401 89/<- %ebp 4/r32/esp +23402 # . save registers +23403 50/push-eax +23404 51/push-ecx +23405 56/push-esi +23406 # var table/esi: (addr table (handle array byte) int 8) +23407 81 5/subop/subtract %esp 0x60/imm32 +23408 68/push 0x60/imm32/size +23409 68/push 0/imm32/read +23410 68/push 0/imm32/write +23411 89/<- %esi 4/r32/esp +23412 # var curr/ecx: (addr list var) = outputs +23413 8b/-> *(ebp+8) 1/r32/ecx +23414 { +23415 # if (curr == 0) break +23416 81 7/subop/compare %ecx 0/imm32 +23417 0f 84/jump-if-= break/disp32 +23418 # var reg/eax: (addr array byte) = curr->value->register # guaranteed to exist +23419 (lookup *ecx *(ecx+4)) # List-value List-value => eax +23420 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +23421 # if reg exists in table, abort +23422 (maybe-get %esi %eax 0xc) # => eax +23423 3d/compare-eax-and 0/imm32 +23424 0f 85/jump-if-!= $check-all-unique-registers:abort/disp32 +23425 # insert reg in table +23426 (lookup *ecx *(ecx+4)) # List-value List-value => eax +23427 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +23428 (get-or-insert %esi %eax 0xc Heap) +23429 # curr = curr->next +23430 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +23431 89/<- %ecx 0/r32/eax +23432 e9/jump loop/disp32 +23433 } +23434 $check-all-unique-registers:end: +23435 # . reclaim locals +23436 81 0/subop/add %esp 0x6c/imm32 +23437 # . restore registers +23438 5e/pop-to-esi +23439 59/pop-to-ecx +23440 58/pop-to-eax +23441 # . epilogue +23442 89/<- %esp 5/r32/ebp +23443 5d/pop-to-ebp +23444 c3/return +23445 +23446 $check-all-unique-registers:abort: +23447 (write-buffered *(ebp+0x10) "fn ") +23448 8b/-> *(ebp+0xc) 0/r32/eax +23449 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23450 (write-buffered *(ebp+0x10) %eax) +23451 (write-buffered *(ebp+0x10) ": outputs must be in unique registers\n") +23452 (flush *(ebp+0x10)) +23453 (stop *(ebp+0x14) 1) +23454 # never gets here +23455 +23456 # return false if s's register is not between start (inclusive) and end (exclusive) +23457 # return false if the positionally corresponding register in stmt->inouts (where s comes from) is also s's register +23458 # otherwise return true +23459 register-within-list-with-conflict?: # s: (addr stmt-var), start: (addr list var), end: (addr list var), stmt: (addr stmt) -> result/eax: boolean +23460 # . prologue +23461 55/push-ebp +23462 89/<- %ebp 4/r32/esp +23463 # . save registers +23464 51/push-ecx +23465 52/push-edx +23466 53/push-ebx +23467 56/push-esi +23468 57/push-edi +23469 # var target/ebx: (addr array byte) = s->value->register +23470 8b/-> *(ebp+8) 0/r32/eax +23471 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +23472 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +23473 #? (write-buffered Stderr "AA: ") +23474 #? (write-buffered Stderr %eax) +23475 #? (write-buffered Stderr Newline) +23476 #? (flush Stderr) +23477 # if (var->register == 0) return false +23478 3d/compare-eax-and 0/imm32 +23479 0f 84/jump-if-= $register-within-list-with-conflict?:end/disp32 # eax turns into result +23480 89/<- %ebx 0/r32/eax +23481 # var curr/ecx: (addr list var) = start +23482 8b/-> *(ebp+0xc) 1/r32/ecx +23483 # edx = end +23484 8b/-> *(ebp+0x10) 2/r32/edx +23485 { +23486 # if (curr == 0) break +23487 81 7/subop/compare %edi 0/imm32 +23488 0f 84/jump-if-= break/disp32 +23489 # if (curr == end) break +23490 39/compare %ecx 2/r32/edx +23491 0f 84/jump-if-= break/disp32 +23492 # var curr-reg/eax: (addr array byte) = curr->value->register +23493 (lookup *ecx *(ecx+4)) # List-value List-value => eax +23494 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +23495 # if (curr-reg == 0) continue +23496 3d/compare-eax-and 0/imm32 +23497 74/jump-if-= $register-within-list-with-conflict?:continue/disp8 +23498 # if (curr-reg == target) check for conflict +23499 (string-equal? %eax %ebx) # => eax +23500 3d/compare-eax-and 0/imm32/false +23501 { +23502 74/jump-if-= break/disp8 +23503 #? (write-buffered Stderr "conflict?\n") +23504 #? (flush Stderr) +23505 # var return-inouts/eax: (addr stmt-var) = stmt->inouts +23506 8b/-> *(ebp+0x14) 0/r32/eax +23507 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +23508 (register-conflict? %ebx %eax *(ebp+0xc)) # => eax +23509 eb/jump $register-within-list-with-conflict?:end/disp8 +23510 } +23511 $register-within-list-with-conflict?:continue: +23512 # curr = curr->next +23513 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +23514 89/<- %ecx 0/r32/eax +23515 e9/jump loop/disp32 +23516 } +23517 # return false +23518 b8/copy-to-eax 0/imm32/false +23519 $register-within-list-with-conflict?:end: +23520 # . restore registers +23521 5f/pop-to-edi +23522 5e/pop-to-esi +23523 5b/pop-to-ebx +23524 5a/pop-to-edx +23525 59/pop-to-ecx +23526 # . epilogue +23527 89/<- %esp 5/r32/ebp +23528 5d/pop-to-ebp +23529 c3/return +23530 +23531 # At the first occurrence of register 'reg' in fn-outputs, +23532 # check if the corresponding element of return-inouts has a different register. +23533 # This hacky helper is intended to be called in one specific place. Don't +23534 # reuse it as is. +23535 register-conflict?: # reg: (addr array byte), return-inouts: (addr stmt-var), fn-outputs: (addr list var) => result/eax: boolean +23536 # . prologue +23537 55/push-ebp +23538 89/<- %ebp 4/r32/esp +23539 # . save registers +23540 51/push-ecx +23541 52/push-edx +23542 53/push-ebx +23543 56/push-esi +23544 57/push-edi +23545 #? (write-buffered Stderr "BB: ") +23546 #? (write-buffered Stderr *(ebp+8)) +23547 #? (write-buffered Stderr Newline) +23548 #? (flush Stderr) +23549 # var curr-output/edi: (addr list var) = fn-outputs +23550 8b/-> *(ebp+0x10) 7/r32/edi +23551 # var curr-inout/esi: (addr stmt-var) = return-inouts +23552 8b/-> *(ebp+0xc) 6/r32/esi +23553 { +23554 # if (curr-output == 0) abort +23555 81 7/subop/compare %edi 0/imm32 +23556 0f 84/jump-if-= break/disp32 +23557 # if (curr-output->value->register != reg) continue +23558 (lookup *edi *(edi+4)) # List-value List-value => eax +23559 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +23560 (string-equal? %eax *(ebp+8)) # => eax +23561 3d/compare-eax-and 0/imm32/false +23562 0f 84/jump-if= $register-conflict?:continue/disp32 +23563 #? (write-buffered Stderr "rescan\n") +23564 #? (flush Stderr) +23565 # var curr-reg/eax: (addr array byte) = curr-inout->value->register +23566 (lookup *esi *(esi+4)) # List-value List-value => eax +23567 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +23568 # if (curr-reg == 0) return true +23569 3d/compare-eax-and 0/imm32 +23570 { +23571 75/jump-if-!= break/disp8 +23572 #? (write-buffered Stderr "no register\n") +23573 #? (flush Stderr) +23574 b8/copy-to-eax 1/imm32/true +23575 e9/jump $register-conflict?:end/disp32 +23576 } +23577 # return (curr-reg != reg) +23578 (string-equal? %eax *(ebp+8)) # => eax +23579 3d/compare-eax-and 0/imm32/false +23580 0f 94/set-if-= %al +23581 #? (write-buffered Stderr "final: ") +23582 #? (write-int32-hex-buffered Stderr %eax) +23583 #? (write-buffered Stderr Newline) +23584 #? (flush Stderr) +23585 eb/jump $register-conflict?:end/disp8 +23586 $register-conflict?:continue: +23587 # curr-output = curr-output->next +23588 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +23589 89/<- %edi 0/r32/eax +23590 # curr-inout = curr-inout->next +23591 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +23592 89/<- %esi 0/r32/eax +23593 e9/jump loop/disp32 +23594 } +23595 # should never get here +23596 (write-buffered Stderr "register-conflict? misused\n") +23597 (flush Stderr) +23598 e8/call syscall_exit/disp32 +23599 $register-conflict?:end: +23600 # . restore registers +23601 5f/pop-to-edi +23602 5e/pop-to-esi +23603 5b/pop-to-ebx +23604 5a/pop-to-edx +23605 59/pop-to-ecx +23606 # . epilogue +23607 89/<- %esp 5/r32/ebp +23608 5d/pop-to-ebp +23609 c3/return +23610 +23611 check-final-stmt-is-return: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +23612 # . prologue +23613 55/push-ebp +23614 89/<- %ebp 4/r32/esp +23615 # . save registers +23616 50/push-eax +23617 51/push-ecx +23618 # var curr/ecx: (addr list stmt) = block->stmts +23619 8b/-> *(ebp+8) 0/r32/eax +23620 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax +23621 3d/compare-eax-and 0/imm32 +23622 74/jump-if-= $check-final-stmt-is-return:error/disp8 +23623 89/<- %ecx 0/r32/eax +23624 { +23625 # if curr->next == 0, break +23626 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +23627 3d/compare-eax-and 0/imm32 +23628 74/jump-if-= break/disp8 +23629 # curr = curr->next +23630 89/<- %ecx 0/r32/eax +23631 e9/jump loop/disp32 +23632 } +23633 $check-final-stmt-is-return:check-tag: +23634 # if curr->value->tag != Stmt1, abort +23635 (lookup *ecx *(ecx+4)) # List-value List-value => eax +23636 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag +23637 75/jump-if-!= $check-final-stmt-is-return:error/disp8 +23638 $check-final-stmt-is-return:check-operation: +23639 # if curr->operation != "return", abort +23640 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +23641 (string-equal? %eax "return") +23642 3d/compare-eax-and 0/imm32/false +23643 74/jump-if-= $check-final-stmt-is-return:error/disp8 +23644 $check-final-stmt-is-return:end: +23645 # . restore registers +23646 59/pop-to-ecx +23647 58/pop-to-eax +23648 # . epilogue +23649 89/<- %esp 5/r32/ebp +23650 5d/pop-to-ebp +23651 c3/return +23652 +23653 $check-final-stmt-is-return:error: +23654 (write-buffered *(ebp+0x10) "fn ") +23655 8b/-> *(ebp+0xc) 0/r32/eax +23656 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23657 (write-buffered *(ebp+0x10) %eax) +23658 (write-buffered *(ebp+0x10) ": final statement should be a 'return'\n") +23659 (flush *(ebp+0x10)) +23660 (stop *(ebp+0x14) 1) +23661 # never gets here +23662 +23663 check-no-breaks: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +23664 # . prologue +23665 55/push-ebp +23666 89/<- %ebp 4/r32/esp +23667 # . save registers +23668 50/push-eax +23669 51/push-ecx +23670 # var curr/ecx: (addr list stmt) = block->stmts +23671 8b/-> *(ebp+8) 0/r32/eax +23672 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax +23673 3d/compare-eax-and 0/imm32 +23674 0f 84/jump-if-= $check-no-breaks:end/disp32 +23675 89/<- %ecx 0/r32/eax +23676 { +23677 # if curr->next == 0, break +23678 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +23679 3d/compare-eax-and 0/imm32 +23680 74/jump-if-= break/disp8 +23681 # if curr->value->tag != Stmt1, continue +23682 (lookup *ecx *(ecx+4)) # List-value List-value => eax +23683 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag +23684 75/jump-if-!= $check-no-breaks:continue/disp8 +23685 # if curr->value->operation starts with "break", abort +23686 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +23687 (string-starts-with? %eax "break") # => eax +23688 3d/compare-eax-and 0/imm32/false +23689 75/jump-if-!= $check-no-breaks:error/disp8 +23690 $check-no-breaks:continue: +23691 # curr = curr->next +23692 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +23693 89/<- %ecx 0/r32/eax +23694 e9/jump loop/disp32 +23695 } +23696 $check-no-breaks:end: +23697 # . restore registers +23698 59/pop-to-ecx +23699 58/pop-to-eax +23700 # . epilogue +23701 89/<- %esp 5/r32/ebp +23702 5d/pop-to-ebp +23703 c3/return +23704 +23705 $check-no-breaks:error: +23706 (write-buffered *(ebp+0x10) "fn ") +23707 8b/-> *(ebp+0xc) 0/r32/eax +23708 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23709 (write-buffered *(ebp+0x10) %eax) +23710 (write-buffered *(ebp+0x10) " has outputs, so you cannot 'break' out of the outermost block. Use 'return'.\n") +23711 (flush *(ebp+0x10)) +23712 (stop *(ebp+0x14) 1) +23713 # never gets here +23714 +23715 check-mu-get-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +23716 # . prologue +23717 55/push-ebp +23718 89/<- %ebp 4/r32/esp +23719 # . save registers +23720 50/push-eax +23721 51/push-ecx +23722 52/push-edx +23723 53/push-ebx +23724 56/push-esi +23725 57/push-edi +23726 # esi = stmt +23727 8b/-> *(ebp+8) 6/r32/esi +23728 # - check for 0 inouts +23729 # var base/ecx: (addr var) = stmt->inouts->value +23730 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +23731 3d/compare-eax-and 0/imm32/false +23732 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 +23733 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +23734 89/<- %ecx 0/r32/eax +23735 $check-mu-get-stmt:check-base: +23736 # - check base type +23737 # if it's an 'addr', check that it's in a register +23738 # var base-type/ebx: (addr type-tree) = lookup(base->type) +23739 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +23740 89/<- %ebx 0/r32/eax +23741 { +23742 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +23743 0f 85/jump-if-!= break/disp32 +23744 $check-mu-get-stmt:base-is-compound: +23745 # if (type->left != addr) break +23746 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +23747 (simple-mu-type? %eax 2) # addr => eax +23748 3d/compare-eax-and 0/imm32/false +23749 74/jump-if-= break/disp8 +23750 $check-mu-get-stmt:base-is-addr: +23751 # now check for register +23752 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +23753 0f 84/jump-if-= $check-mu-get-stmt:error-base-type-addr-but-not-register/disp32 +23754 $check-mu-get-stmt:base-is-addr-in-register: +23755 # type->left is now an addr; skip it +23756 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +23757 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +23758 0f 85/jump-if-!= $check-mu-get-stmt:error-bad-base/disp32 +23759 $check-mu-get-stmt:base-is-addr-to-atom-in-register: +23760 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23761 89/<- %ebx 0/r32/eax +23762 } +23763 $check-mu-get-stmt:check-base-typeinfo: +23764 # ensure type is a container +23765 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +23766 { +23767 75/jump-if-!= break/disp8 +23768 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +23769 89/<- %ebx 0/r32/eax +23770 } +23771 # var base-type-id/ebx: type-id = base-type->value +23772 8b/-> *(ebx+4) 3/r32/ebx # Type-tree-value +23773 (container? %ebx) # => eax +23774 3d/compare-eax-and 0/imm32/false +23775 0f 84/jump-if-= $check-mu-get-stmt:error-bad-base/disp32 +23776 # var base-typeinfo/edx: (addr typeinfo) = find-typeinfo(base-type-id) +23777 # . var container/ecx: (handle typeinfo) +23778 68/push 0/imm32 +23779 68/push 0/imm32 +23780 89/<- %ecx 4/r32/esp +23781 # . +23782 (find-typeinfo %ebx %ecx) +23783 (lookup *ecx *(ecx+4)) # => eax +23784 # . reclaim container +23785 81 0/subop/add %esp 8/imm32 +23786 # . +23787 89/<- %edx 0/r32/eax +23788 # var offset/ecx: (addr stmt-var) = stmt->inouts->next +23789 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +23790 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +23791 89/<- %ecx 0/r32/eax +23792 # - check for 1 inout +23793 3d/compare-eax-and 0/imm32/false +23794 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 +23795 # var offset/ecx: (addr var) = lookup(offset->value) +23796 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +23797 89/<- %ecx 0/r32/eax +23798 # - check for valid field +23799 81 7/subop/compare *(ecx+0x14) -1/imm32/uninitialized # Var-offset +23800 0f 84/jump-if-= $check-mu-get-stmt:error-bad-field/disp32 +23801 # - check for too many inouts +23802 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +23803 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +23804 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +23805 3d/compare-eax-and 0/imm32/false +23806 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-inouts/disp32 +23807 # var output/edi: (addr var) = stmt->outputs->value +23808 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +23809 # - check for 0 outputs +23810 3d/compare-eax-and 0/imm32/false +23811 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-outputs/disp32 +23812 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +23813 89/<- %edi 0/r32/eax +23814 $check-mu-get-stmt:check-output-type: +23815 # - check output type +23816 # must be in register +23817 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +23818 3d/compare-eax-and 0/imm32 +23819 0f 84/jump-if-= $check-mu-get-stmt:error-output-not-in-register/disp32 +23820 # must have a non-atomic type +23821 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +23822 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +23823 0f 85/jump-if-!= $check-mu-get-stmt:error-output-type-not-address/disp32 +23824 # type must start with (addr ...) +23825 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23826 (simple-mu-type? %eax 2) # => eax +23827 3d/compare-eax-and 0/imm32/false +23828 0f 84/jump-if-= $check-mu-get-stmt:error-output-type-not-address/disp32 +23829 $check-mu-get-stmt:check-output-type-match: +23830 # payload of addr type must match 'type' definition +23831 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +23832 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +23833 # if (payload->right == null) payload = payload->left +23834 81 7/subop/compare *(eax+0xc) 0/imm32/null # Type-tree-right +23835 { +23836 75/jump-if-!= break/disp8 +23837 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +23838 } +23839 89/<- %edi 0/r32/eax +23840 # . var output-name/ecx: (addr array byte) +23841 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +23842 89/<- %ecx 0/r32/eax +23843 # . var base-typeinfo-entry/eax: (addr handle typeinfo-entry) +23844 (lookup *(edx+4) *(edx+8)) # Typeinfo-fields Typeinfo-fields => eax +23845 (get %eax %ecx 0x10) # => eax +23846 # . +23847 (lookup *eax *(eax+4)) # => eax +23848 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +23849 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +23850 # . +23851 (type-equal? %edi %eax) # => eax +23852 3d/compare-eax-and 0/imm32/false +23853 0f 84/jump-if-= $check-mu-get-stmt:error-bad-output-type/disp32 +23854 # - check for too many outputs +23855 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +23856 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +23857 3d/compare-eax-and 0/imm32/false +23858 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-outputs/disp32 +23859 $check-mu-get-stmt:end: +23860 # . restore registers +23861 5f/pop-to-edi +23862 5e/pop-to-esi +23863 5b/pop-to-ebx +23864 5a/pop-to-edx +23865 59/pop-to-ecx +23866 58/pop-to-eax +23867 # . epilogue +23868 89/<- %esp 5/r32/ebp +23869 5d/pop-to-ebp +23870 c3/return +23871 +23872 $check-mu-get-stmt:error-too-few-inouts: +23873 (write-buffered *(ebp+0x10) "fn ") +23874 8b/-> *(ebp+0xc) 0/r32/eax +23875 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23876 (write-buffered *(ebp+0x10) %eax) +23877 (write-buffered *(ebp+0x10) ": stmt get: too few inouts (2 required)\n") +23878 (flush *(ebp+0x10)) +23879 (stop *(ebp+0x14) 1) +23880 # never gets here +23881 +23882 $check-mu-get-stmt:error-too-many-inouts: +23883 (write-buffered *(ebp+0x10) "fn ") +23884 8b/-> *(ebp+0xc) 0/r32/eax +23885 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23886 (write-buffered *(ebp+0x10) %eax) +23887 (write-buffered *(ebp+0x10) ": stmt get: too many inouts (2 required)\n") +23888 (flush *(ebp+0x10)) +23889 (stop *(ebp+0x14) 1) +23890 # never gets here +23891 +23892 $check-mu-get-stmt:error-too-few-outputs: +23893 (write-buffered *(ebp+0x10) "fn ") +23894 8b/-> *(ebp+0xc) 0/r32/eax +23895 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23896 (write-buffered *(ebp+0x10) %eax) +23897 (write-buffered *(ebp+0x10) ": stmt get: must have an output\n") +23898 (flush *(ebp+0x10)) +23899 (stop *(ebp+0x14) 1) +23900 # never gets here +23901 +23902 $check-mu-get-stmt:error-too-many-outputs: +23903 (write-buffered *(ebp+0x10) "fn ") +23904 8b/-> *(ebp+0xc) 0/r32/eax +23905 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23906 (write-buffered *(ebp+0x10) %eax) +23907 (write-buffered *(ebp+0x10) ": stmt get: too many outputs (1 required)\n") +23908 (flush *(ebp+0x10)) +23909 (stop *(ebp+0x14) 1) +23910 # never gets here +23911 +23912 $check-mu-get-stmt:error-bad-base: +23913 # error("fn " fn ": stmt get: var '" base->name "' must have a 'type' definition\n") +23914 (write-buffered *(ebp+0x10) "fn ") +23915 8b/-> *(ebp+0xc) 0/r32/eax +23916 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23917 (write-buffered *(ebp+0x10) %eax) +23918 (write-buffered *(ebp+0x10) ": stmt get: var '") +23919 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +23920 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +23921 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23922 (write-buffered *(ebp+0x10) %eax) +23923 (write-buffered *(ebp+0x10) "' must have a 'type' definition\n") +23924 (flush *(ebp+0x10)) +23925 (stop *(ebp+0x14) 1) +23926 # never gets here +23927 +23928 $check-mu-get-stmt:error-base-type-addr-but-not-register: +23929 (write-buffered *(ebp+0x10) "fn ") +23930 8b/-> *(ebp+0xc) 0/r32/eax +23931 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23932 (write-buffered *(ebp+0x10) %eax) +23933 (write-buffered *(ebp+0x10) ": stmt get: var '") +23934 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +23935 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +23936 (lookup *eax *(eax+4)) # Var-name Var-name => eax +23937 (write-buffered *(ebp+0x10) %eax) +23938 (write-buffered *(ebp+0x10) "' is an 'addr' type, and so must live in a register\n") +23939 (flush *(ebp+0x10)) +23940 (stop *(ebp+0x14) 1) +23941 # never gets here +23942 +23943 $check-mu-get-stmt:error-bad-field: +23944 # error("fn " fn ": stmt get: type " type " has no member called '" curr->name "'\n") 23945 (write-buffered *(ebp+0x10) "fn ") 23946 8b/-> *(ebp+0xc) 0/r32/eax 23947 (lookup *eax *(eax+4)) # Function-name Function-name => eax 23948 (write-buffered *(ebp+0x10) %eax) -23949 (write-buffered *(ebp+0x10) ": stmt get: output '") -23950 (lookup *edi *(edi+4)) # Var-name Var-name => eax -23951 (write-buffered *(ebp+0x10) %eax) -23952 (write-buffered *(ebp+0x10) "' is not in a register\n") -23953 (flush *(ebp+0x10)) -23954 (stop *(ebp+0x14) 1) -23955 # never gets here -23956 -23957 $check-mu-get-stmt:error-output-type-not-address: -23958 (write-buffered *(ebp+0x10) "fn ") -23959 8b/-> *(ebp+0xc) 0/r32/eax -23960 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23949 (write-buffered *(ebp+0x10) ": stmt get: type '") +23950 # . write(Type-id->data[tmp]) +23951 bf/copy-to-edi Type-id/imm32 +23952 8b/-> *(edi+ebx<<2+0xc) 6/r32/esi +23953 { +23954 81 7/subop/compare %esi 0/imm32 +23955 74/jump-if-= break/disp8 +23956 (write-buffered *(ebp+0x10) %esi) +23957 } +23958 # . +23959 (write-buffered *(ebp+0x10) "' has no member called '") +23960 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 23961 (write-buffered *(ebp+0x10) %eax) -23962 (write-buffered *(ebp+0x10) ": stmt get: output must be an addr\n") +23962 (write-buffered *(ebp+0x10) "'\n") 23963 (flush *(ebp+0x10)) 23964 (stop *(ebp+0x14) 1) 23965 # never gets here 23966 -23967 $check-mu-get-stmt:error-bad-output-type: +23967 $check-mu-get-stmt:error-output-not-in-register: 23968 (write-buffered *(ebp+0x10) "fn ") 23969 8b/-> *(ebp+0xc) 0/r32/eax 23970 (lookup *eax *(eax+4)) # Function-name Function-name => eax 23971 (write-buffered *(ebp+0x10) %eax) -23972 (write-buffered *(ebp+0x10) ": stmt get: wrong output type for member '") -23973 (write-buffered *(ebp+0x10) %ecx) -23974 (write-buffered *(ebp+0x10) "' of type '") -23975 bf/copy-to-edi Type-id/imm32 -23976 8b/-> *(edi+ebx<<2+0xc) 6/r32/esi -23977 { -23978 81 7/subop/compare %esi 0/imm32 -23979 74/jump-if-= break/disp8 -23980 (write-buffered *(ebp+0x10) %esi) -23981 } -23982 (write-buffered *(ebp+0x10) "'\n") -23983 (flush *(ebp+0x10)) -23984 (stop *(ebp+0x14) 1) -23985 # never gets here -23986 -23987 check-mu-index-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -23988 # . prologue -23989 55/push-ebp -23990 89/<- %ebp 4/r32/esp -23991 # . save registers -23992 50/push-eax -23993 51/push-ecx -23994 52/push-edx -23995 53/push-ebx -23996 56/push-esi -23997 57/push-edi -23998 # esi = stmt -23999 8b/-> *(ebp+8) 6/r32/esi -24000 # - check for 0 inouts -24001 # var base/ecx: (addr var) = stmt->inouts->value -24002 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24003 $check-mu-index-stmt:check-no-inouts: -24004 3d/compare-eax-and 0/imm32 -24005 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-inouts/disp32 -24006 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24007 89/<- %ecx 0/r32/eax -24008 # - check base type is either (addr array ...) in register or (array ...) on stack -24009 # var base-type/ebx: (addr type-tree) = lookup(base->type) -24010 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -24011 89/<- %ebx 0/r32/eax -24012 # if base-type is an atom, abort with a precise error -24013 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -24014 { -24015 74/jump-if-= break/disp8 -24016 (simple-mu-type? %ebx 3) # array => eax -24017 3d/compare-eax-and 0/imm32/false -24018 0f 85/jump-if-!= $check-mu-index-stmt:error-base-array-atom-type/disp32 -24019 0f 84/jump-if-= $check-mu-index-stmt:error-base-non-array-type/disp32 -24020 } -24021 $check-mu-index-stmt:base-is-compound: -24022 # if type->left not addr or array, abort -24023 { -24024 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24025 (simple-mu-type? %eax 2) # addr => eax -24026 3d/compare-eax-and 0/imm32/false -24027 75/jump-if-!= break/disp8 -24028 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24029 (simple-mu-type? %eax 3) # array => eax -24030 3d/compare-eax-and 0/imm32/false -24031 75/jump-if-!= break/disp8 -24032 e9/jump $check-mu-index-stmt:error-base-non-array-type/disp32 -24033 } -24034 # if (type->left == addr) ensure type->right->left == array and type->register exists -24035 { -24036 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24037 (simple-mu-type? %eax 2) # addr => eax -24038 3d/compare-eax-and 0/imm32/false -24039 74/jump-if-= break/disp8 -24040 $check-mu-index-stmt:base-is-addr: -24041 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -24042 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -24043 (simple-mu-type? %eax 3) # array => eax -24044 3d/compare-eax-and 0/imm32/false -24045 0f 84/jump-if-= $check-mu-index-stmt:error-base-non-array-type/disp32 -24046 $check-mu-index-stmt:check-base-addr-is-register: -24047 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -24048 0f 84/jump-if-= $check-mu-index-stmt:error-base-address-array-type-on-stack/disp32 -24049 } -24050 # if (type->left == array) ensure type->register doesn't exist -24051 { -24052 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24053 (simple-mu-type? %eax 3) # array => eax -24054 3d/compare-eax-and 0/imm32/false -24055 74/jump-if-= break/disp8 -24056 $check-mu-index-stmt:base-is-array: -24057 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -24058 0f 85/jump-if-!= $check-mu-index-stmt:error-base-array-type-in-register/disp32 -24059 } -24060 # if (base-type->left == addr) base-type = base-type->right -24061 { -24062 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24063 (simple-mu-type? %eax 2) # addr => eax -24064 3d/compare-eax-and 0/imm32/false -24065 74/jump-if-= break/disp8 -24066 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -24067 89/<- %ebx 0/r32/eax -24068 } -24069 # - check for 1 inout -24070 # var index/ecx: (addr stmt-var) = stmt->inouts->next->value -24071 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24072 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24073 $check-mu-index-stmt:check-single-inout: -24074 3d/compare-eax-and 0/imm32 -24075 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-inouts/disp32 -24076 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24077 89/<- %ecx 0/r32/eax -24078 # - check index is either a literal or register -24079 # var index-type/edx: (addr type-tree) -24080 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -24081 89/<- %edx 0/r32/eax -24082 # if index type is an atom, it must be a literal or int -24083 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +23972 (write-buffered *(ebp+0x10) ": stmt get: output '") +23973 (lookup *edi *(edi+4)) # Var-name Var-name => eax +23974 (write-buffered *(ebp+0x10) %eax) +23975 (write-buffered *(ebp+0x10) "' is not in a register\n") +23976 (flush *(ebp+0x10)) +23977 (stop *(ebp+0x14) 1) +23978 # never gets here +23979 +23980 $check-mu-get-stmt:error-output-type-not-address: +23981 (write-buffered *(ebp+0x10) "fn ") +23982 8b/-> *(ebp+0xc) 0/r32/eax +23983 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23984 (write-buffered *(ebp+0x10) %eax) +23985 (write-buffered *(ebp+0x10) ": stmt get: output must be an addr\n") +23986 (flush *(ebp+0x10)) +23987 (stop *(ebp+0x14) 1) +23988 # never gets here +23989 +23990 $check-mu-get-stmt:error-bad-output-type: +23991 (write-buffered *(ebp+0x10) "fn ") +23992 8b/-> *(ebp+0xc) 0/r32/eax +23993 (lookup *eax *(eax+4)) # Function-name Function-name => eax +23994 (write-buffered *(ebp+0x10) %eax) +23995 (write-buffered *(ebp+0x10) ": stmt get: wrong output type for member '") +23996 (write-buffered *(ebp+0x10) %ecx) +23997 (write-buffered *(ebp+0x10) "' of type '") +23998 bf/copy-to-edi Type-id/imm32 +23999 8b/-> *(edi+ebx<<2+0xc) 6/r32/esi +24000 { +24001 81 7/subop/compare %esi 0/imm32 +24002 74/jump-if-= break/disp8 +24003 (write-buffered *(ebp+0x10) %esi) +24004 } +24005 (write-buffered *(ebp+0x10) "'\n") +24006 (flush *(ebp+0x10)) +24007 (stop *(ebp+0x14) 1) +24008 # never gets here +24009 +24010 check-mu-index-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +24011 # . prologue +24012 55/push-ebp +24013 89/<- %ebp 4/r32/esp +24014 # . save registers +24015 50/push-eax +24016 51/push-ecx +24017 52/push-edx +24018 53/push-ebx +24019 56/push-esi +24020 57/push-edi +24021 # esi = stmt +24022 8b/-> *(ebp+8) 6/r32/esi +24023 # - check for 0 inouts +24024 # var base/ecx: (addr var) = stmt->inouts->value +24025 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24026 $check-mu-index-stmt:check-no-inouts: +24027 3d/compare-eax-and 0/imm32 +24028 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-inouts/disp32 +24029 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24030 89/<- %ecx 0/r32/eax +24031 # - check base type is either (addr array ...) in register or (array ...) on stack +24032 # var base-type/ebx: (addr type-tree) = lookup(base->type) +24033 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +24034 89/<- %ebx 0/r32/eax +24035 # if base-type is an atom, abort with a precise error +24036 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +24037 { +24038 74/jump-if-= break/disp8 +24039 (simple-mu-type? %ebx 3) # array => eax +24040 3d/compare-eax-and 0/imm32/false +24041 0f 85/jump-if-!= $check-mu-index-stmt:error-base-array-atom-type/disp32 +24042 0f 84/jump-if-= $check-mu-index-stmt:error-base-non-array-type/disp32 +24043 } +24044 $check-mu-index-stmt:base-is-compound: +24045 # if type->left not addr or array, abort +24046 { +24047 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24048 (simple-mu-type? %eax 2) # addr => eax +24049 3d/compare-eax-and 0/imm32/false +24050 75/jump-if-!= break/disp8 +24051 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24052 (simple-mu-type? %eax 3) # array => eax +24053 3d/compare-eax-and 0/imm32/false +24054 75/jump-if-!= break/disp8 +24055 e9/jump $check-mu-index-stmt:error-base-non-array-type/disp32 +24056 } +24057 # if (type->left == addr) ensure type->right->left == array and type->register exists +24058 { +24059 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24060 (simple-mu-type? %eax 2) # addr => eax +24061 3d/compare-eax-and 0/imm32/false +24062 74/jump-if-= break/disp8 +24063 $check-mu-index-stmt:base-is-addr: +24064 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +24065 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +24066 (simple-mu-type? %eax 3) # array => eax +24067 3d/compare-eax-and 0/imm32/false +24068 0f 84/jump-if-= $check-mu-index-stmt:error-base-non-array-type/disp32 +24069 $check-mu-index-stmt:check-base-addr-is-register: +24070 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +24071 0f 84/jump-if-= $check-mu-index-stmt:error-base-address-array-type-on-stack/disp32 +24072 } +24073 # if (type->left == array) ensure type->register doesn't exist +24074 { +24075 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24076 (simple-mu-type? %eax 3) # array => eax +24077 3d/compare-eax-and 0/imm32/false +24078 74/jump-if-= break/disp8 +24079 $check-mu-index-stmt:base-is-array: +24080 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +24081 0f 85/jump-if-!= $check-mu-index-stmt:error-base-array-type-in-register/disp32 +24082 } +24083 # if (base-type->left == addr) base-type = base-type->right 24084 { -24085 74/jump-if-= break/disp8 -24086 $check-mu-index-stmt:index-type-is-atom: -24087 (simple-mu-type? %edx 0) # literal => eax -24088 3d/compare-eax-and 0/imm32/false -24089 75/jump-if-!= $check-mu-index-stmt:index-type-done/disp8 -24090 (simple-mu-type? %edx 1) # int => eax -24091 3d/compare-eax-and 0/imm32/false -24092 75/jump-if-!= $check-mu-index-stmt:index-type-done/disp8 -24093 (simple-mu-type? %edx 7) # offset => eax -24094 3d/compare-eax-and 0/imm32/false -24095 0f 85/jump-if-!= $check-mu-index-stmt:error-index-offset-atom-type/disp32 -24096 e9/jump $check-mu-index-stmt:error-invalid-index-type/disp32 -24097 } -24098 # if index type is a non-atom: it must be an offset -24099 { -24100 75/jump-if-!= break/disp8 -24101 $check-mu-index-stmt:index-type-is-non-atom: -24102 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -24103 (simple-mu-type? %eax 7) # offset => eax -24104 3d/compare-eax-and 0/imm32/false -24105 0f 84/jump-if-= $check-mu-index-stmt:error-invalid-index-type/disp32 -24106 } -24107 $check-mu-index-stmt:index-type-done: -24108 # check index is either a literal or in a register -24109 { -24110 (simple-mu-type? %edx 0) # literal => eax +24085 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24086 (simple-mu-type? %eax 2) # addr => eax +24087 3d/compare-eax-and 0/imm32/false +24088 74/jump-if-= break/disp8 +24089 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +24090 89/<- %ebx 0/r32/eax +24091 } +24092 # - check for 1 inout +24093 # var index/ecx: (addr stmt-var) = stmt->inouts->next->value +24094 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24095 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24096 $check-mu-index-stmt:check-single-inout: +24097 3d/compare-eax-and 0/imm32 +24098 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-inouts/disp32 +24099 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24100 89/<- %ecx 0/r32/eax +24101 # - check index is either a literal or register +24102 # var index-type/edx: (addr type-tree) +24103 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +24104 89/<- %edx 0/r32/eax +24105 # if index type is an atom, it must be a literal or int +24106 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +24107 { +24108 74/jump-if-= break/disp8 +24109 $check-mu-index-stmt:index-type-is-atom: +24110 (simple-mu-type? %edx 0) # literal => eax 24111 3d/compare-eax-and 0/imm32/false -24112 75/jump-if-!= break/disp8 -24113 $check-mu-index-stmt:check-index-in-register: -24114 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -24115 0f 84/jump-if-= $check-mu-index-stmt:error-index-on-stack/disp32 -24116 } -24117 # - if index is an 'int', check that element type of base has size 1, 2, 4 or 8 bytes. -24118 { -24119 (simple-mu-type? %edx 1) # int => eax -24120 3d/compare-eax-and 0/imm32/false -24121 74/jump-if-= break/disp8 -24122 $check-mu-index-stmt:check-index-can-be-int: -24123 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24124 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24125 (array-element-size %eax) # => eax -24126 3d/compare-eax-and 1/imm32 -24127 74/jump-if-= break/disp8 -24128 3d/compare-eax-and 2/imm32 -24129 74/jump-if-= break/disp8 -24130 3d/compare-eax-and 4/imm32 -24131 74/jump-if-= break/disp8 -24132 3d/compare-eax-and 8/imm32 -24133 74/jump-if-= break/disp8 -24134 e9/jump $check-mu-index-stmt:error-index-needs-offset/disp32 -24135 } -24136 # - check for too many inouts -24137 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24138 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24139 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24140 3d/compare-eax-and 0/imm32/false -24141 0f 85/jump-if-!= $check-mu-index-stmt:error-too-many-inouts/disp32 -24142 # - check for 0 outputs -24143 # var output/edi: (addr var) = stmt->outputs->value -24144 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -24145 3d/compare-eax-and 0/imm32/false -24146 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-outputs/disp32 -24147 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24148 89/<- %edi 0/r32/eax -24149 # - check output type -24150 # must have a non-atomic type -24151 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -24152 89/<- %edx 0/r32/eax -24153 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom -24154 0f 85/jump-if-!= $check-mu-index-stmt:error-output-type-not-address/disp32 -24155 # type must start with (addr ...) -24156 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -24157 (simple-mu-type? %eax 2) # addr => eax -24158 3d/compare-eax-and 0/imm32/false -24159 0f 84/jump-if-= $check-mu-index-stmt:error-output-type-not-address/disp32 -24160 # if tail(base-type) != tail(output-type) abort -24161 (type-tail %ebx) # => eax -24162 89/<- %ebx 0/r32/eax -24163 (type-tail %edx) # => eax -24164 (type-equal? %ebx %eax) # => eax -24165 3d/compare-eax-and 0/imm32/false -24166 0f 84/jump-if-= $check-mu-index-stmt:error-bad-output-type/disp32 -24167 # - check for too many outputs -24168 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -24169 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24170 3d/compare-eax-and 0/imm32/false -24171 0f 85/jump-if-!= $check-mu-index-stmt:error-too-many-outputs/disp32 -24172 $check-mu-index-stmt:end: -24173 # . restore registers -24174 5f/pop-to-edi -24175 5e/pop-to-esi -24176 5b/pop-to-ebx -24177 5a/pop-to-edx -24178 59/pop-to-ecx -24179 58/pop-to-eax -24180 # . epilogue -24181 89/<- %esp 5/r32/ebp -24182 5d/pop-to-ebp -24183 c3/return -24184 -24185 $check-mu-index-stmt:error-base-non-array-type: -24186 (write-buffered *(ebp+0x10) "fn ") -24187 8b/-> *(ebp+0xc) 0/r32/eax -24188 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24189 (write-buffered *(ebp+0x10) %eax) -24190 (write-buffered *(ebp+0x10) ": stmt index: var '") -24191 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24192 (write-buffered *(ebp+0x10) %eax) -24193 (write-buffered *(ebp+0x10) "' is not an array\n") -24194 (flush *(ebp+0x10)) -24195 (stop *(ebp+0x14) 1) -24196 # never gets here -24197 -24198 $check-mu-index-stmt:error-base-array-atom-type: -24199 (write-buffered *(ebp+0x10) "fn ") -24200 8b/-> *(ebp+0xc) 0/r32/eax -24201 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24202 (write-buffered *(ebp+0x10) %eax) -24203 (write-buffered *(ebp+0x10) ": stmt index: array '") -24204 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24205 (write-buffered *(ebp+0x10) %eax) -24206 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n") -24207 (flush *(ebp+0x10)) -24208 (stop *(ebp+0x14) 1) -24209 # never gets here -24210 -24211 $check-mu-index-stmt:error-base-address-array-type-on-stack: -24212 (write-buffered *(ebp+0x10) "fn ") -24213 8b/-> *(ebp+0xc) 0/r32/eax -24214 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24112 75/jump-if-!= $check-mu-index-stmt:index-type-done/disp8 +24113 (simple-mu-type? %edx 1) # int => eax +24114 3d/compare-eax-and 0/imm32/false +24115 75/jump-if-!= $check-mu-index-stmt:index-type-done/disp8 +24116 (simple-mu-type? %edx 7) # offset => eax +24117 3d/compare-eax-and 0/imm32/false +24118 0f 85/jump-if-!= $check-mu-index-stmt:error-index-offset-atom-type/disp32 +24119 e9/jump $check-mu-index-stmt:error-invalid-index-type/disp32 +24120 } +24121 # if index type is a non-atom: it must be an offset +24122 { +24123 75/jump-if-!= break/disp8 +24124 $check-mu-index-stmt:index-type-is-non-atom: +24125 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +24126 (simple-mu-type? %eax 7) # offset => eax +24127 3d/compare-eax-and 0/imm32/false +24128 0f 84/jump-if-= $check-mu-index-stmt:error-invalid-index-type/disp32 +24129 } +24130 $check-mu-index-stmt:index-type-done: +24131 # check index is either a literal or in a register +24132 { +24133 (simple-mu-type? %edx 0) # literal => eax +24134 3d/compare-eax-and 0/imm32/false +24135 75/jump-if-!= break/disp8 +24136 $check-mu-index-stmt:check-index-in-register: +24137 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +24138 0f 84/jump-if-= $check-mu-index-stmt:error-index-on-stack/disp32 +24139 } +24140 # - if index is an 'int', check that element type of base has size 1, 2, 4 or 8 bytes. +24141 { +24142 (simple-mu-type? %edx 1) # int => eax +24143 3d/compare-eax-and 0/imm32/false +24144 74/jump-if-= break/disp8 +24145 $check-mu-index-stmt:check-index-can-be-int: +24146 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24147 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24148 (array-element-size %eax) # => eax +24149 3d/compare-eax-and 1/imm32 +24150 74/jump-if-= break/disp8 +24151 3d/compare-eax-and 2/imm32 +24152 74/jump-if-= break/disp8 +24153 3d/compare-eax-and 4/imm32 +24154 74/jump-if-= break/disp8 +24155 3d/compare-eax-and 8/imm32 +24156 74/jump-if-= break/disp8 +24157 e9/jump $check-mu-index-stmt:error-index-needs-offset/disp32 +24158 } +24159 # - check for too many inouts +24160 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24161 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24162 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24163 3d/compare-eax-and 0/imm32/false +24164 0f 85/jump-if-!= $check-mu-index-stmt:error-too-many-inouts/disp32 +24165 # - check for 0 outputs +24166 # var output/edi: (addr var) = stmt->outputs->value +24167 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +24168 3d/compare-eax-and 0/imm32/false +24169 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-outputs/disp32 +24170 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24171 89/<- %edi 0/r32/eax +24172 # - check output type +24173 # must have a non-atomic type +24174 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +24175 89/<- %edx 0/r32/eax +24176 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +24177 0f 85/jump-if-!= $check-mu-index-stmt:error-output-type-not-address/disp32 +24178 # type must start with (addr ...) +24179 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +24180 (simple-mu-type? %eax 2) # addr => eax +24181 3d/compare-eax-and 0/imm32/false +24182 0f 84/jump-if-= $check-mu-index-stmt:error-output-type-not-address/disp32 +24183 # if tail(base-type) != tail(output-type) abort +24184 (type-tail %ebx) # => eax +24185 89/<- %ebx 0/r32/eax +24186 (type-tail %edx) # => eax +24187 (type-equal? %ebx %eax) # => eax +24188 3d/compare-eax-and 0/imm32/false +24189 0f 84/jump-if-= $check-mu-index-stmt:error-bad-output-type/disp32 +24190 # - check for too many outputs +24191 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +24192 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24193 3d/compare-eax-and 0/imm32/false +24194 0f 85/jump-if-!= $check-mu-index-stmt:error-too-many-outputs/disp32 +24195 $check-mu-index-stmt:end: +24196 # . restore registers +24197 5f/pop-to-edi +24198 5e/pop-to-esi +24199 5b/pop-to-ebx +24200 5a/pop-to-edx +24201 59/pop-to-ecx +24202 58/pop-to-eax +24203 # . epilogue +24204 89/<- %esp 5/r32/ebp +24205 5d/pop-to-ebp +24206 c3/return +24207 +24208 $check-mu-index-stmt:error-base-non-array-type: +24209 (write-buffered *(ebp+0x10) "fn ") +24210 8b/-> *(ebp+0xc) 0/r32/eax +24211 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24212 (write-buffered *(ebp+0x10) %eax) +24213 (write-buffered *(ebp+0x10) ": stmt index: var '") +24214 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24215 (write-buffered *(ebp+0x10) %eax) -24216 (write-buffered *(ebp+0x10) ": stmt index: var '") -24217 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24218 (write-buffered *(ebp+0x10) %eax) -24219 (write-buffered *(ebp+0x10) "' is an addr to an array, and so must live in a register\n") -24220 (flush *(ebp+0x10)) -24221 (stop *(ebp+0x14) 1) -24222 # never gets here -24223 -24224 $check-mu-index-stmt:error-base-array-type-in-register: -24225 (write-buffered *(ebp+0x10) "fn ") -24226 8b/-> *(ebp+0xc) 0/r32/eax -24227 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24216 (write-buffered *(ebp+0x10) "' is not an array\n") +24217 (flush *(ebp+0x10)) +24218 (stop *(ebp+0x14) 1) +24219 # never gets here +24220 +24221 $check-mu-index-stmt:error-base-array-atom-type: +24222 (write-buffered *(ebp+0x10) "fn ") +24223 8b/-> *(ebp+0xc) 0/r32/eax +24224 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24225 (write-buffered *(ebp+0x10) %eax) +24226 (write-buffered *(ebp+0x10) ": stmt index: array '") +24227 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24228 (write-buffered *(ebp+0x10) %eax) -24229 (write-buffered *(ebp+0x10) ": stmt index: var '") -24230 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24231 (write-buffered *(ebp+0x10) %eax) -24232 (write-buffered *(ebp+0x10) "' is an array, and so must live on the stack\n") -24233 (flush *(ebp+0x10)) -24234 (stop *(ebp+0x14) 1) -24235 # never gets here -24236 -24237 $check-mu-index-stmt:error-too-few-inouts: -24238 (write-buffered *(ebp+0x10) "fn ") -24239 8b/-> *(ebp+0xc) 0/r32/eax -24240 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24229 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n") +24230 (flush *(ebp+0x10)) +24231 (stop *(ebp+0x14) 1) +24232 # never gets here +24233 +24234 $check-mu-index-stmt:error-base-address-array-type-on-stack: +24235 (write-buffered *(ebp+0x10) "fn ") +24236 8b/-> *(ebp+0xc) 0/r32/eax +24237 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24238 (write-buffered *(ebp+0x10) %eax) +24239 (write-buffered *(ebp+0x10) ": stmt index: var '") +24240 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24241 (write-buffered *(ebp+0x10) %eax) -24242 (write-buffered *(ebp+0x10) ": stmt index: too few inouts (2 required)\n") +24242 (write-buffered *(ebp+0x10) "' is an addr to an array, and so must live in a register\n") 24243 (flush *(ebp+0x10)) 24244 (stop *(ebp+0x14) 1) 24245 # never gets here 24246 -24247 $check-mu-index-stmt:error-invalid-index-type: +24247 $check-mu-index-stmt:error-base-array-type-in-register: 24248 (write-buffered *(ebp+0x10) "fn ") 24249 8b/-> *(ebp+0xc) 0/r32/eax 24250 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24251 (write-buffered *(ebp+0x10) %eax) -24252 (write-buffered *(ebp+0x10) ": stmt index: second argument '") +24252 (write-buffered *(ebp+0x10) ": stmt index: var '") 24253 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24254 (write-buffered *(ebp+0x10) %eax) -24255 (write-buffered *(ebp+0x10) "' must be an int or offset\n") +24255 (write-buffered *(ebp+0x10) "' is an array, and so must live on the stack\n") 24256 (flush *(ebp+0x10)) 24257 (stop *(ebp+0x14) 1) 24258 # never gets here 24259 -24260 $check-mu-index-stmt:error-index-offset-atom-type: +24260 $check-mu-index-stmt:error-too-few-inouts: 24261 (write-buffered *(ebp+0x10) "fn ") 24262 8b/-> *(ebp+0xc) 0/r32/eax 24263 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24264 (write-buffered *(ebp+0x10) %eax) -24265 (write-buffered *(ebp+0x10) ": stmt index: offset '") -24266 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24267 (write-buffered *(ebp+0x10) %eax) -24268 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n") -24269 (flush *(ebp+0x10)) -24270 (stop *(ebp+0x14) 1) -24271 # never gets here -24272 -24273 $check-mu-index-stmt:error-index-on-stack: -24274 (write-buffered *(ebp+0x10) "fn ") -24275 8b/-> *(ebp+0xc) 0/r32/eax -24276 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24265 (write-buffered *(ebp+0x10) ": stmt index: too few inouts (2 required)\n") +24266 (flush *(ebp+0x10)) +24267 (stop *(ebp+0x14) 1) +24268 # never gets here +24269 +24270 $check-mu-index-stmt:error-invalid-index-type: +24271 (write-buffered *(ebp+0x10) "fn ") +24272 8b/-> *(ebp+0xc) 0/r32/eax +24273 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24274 (write-buffered *(ebp+0x10) %eax) +24275 (write-buffered *(ebp+0x10) ": stmt index: second argument '") +24276 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24277 (write-buffered *(ebp+0x10) %eax) -24278 (write-buffered *(ebp+0x10) ": stmt index: second argument '") -24279 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24280 (write-buffered *(ebp+0x10) %eax) -24281 (write-buffered *(ebp+0x10) "' must be in a register\n") -24282 (flush *(ebp+0x10)) -24283 (stop *(ebp+0x14) 1) -24284 # never gets here -24285 -24286 $check-mu-index-stmt:error-index-needs-offset: -24287 (write-buffered *(ebp+0x10) "fn ") -24288 8b/-> *(ebp+0xc) 0/r32/eax -24289 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24278 (write-buffered *(ebp+0x10) "' must be an int or offset\n") +24279 (flush *(ebp+0x10)) +24280 (stop *(ebp+0x14) 1) +24281 # never gets here +24282 +24283 $check-mu-index-stmt:error-index-offset-atom-type: +24284 (write-buffered *(ebp+0x10) "fn ") +24285 8b/-> *(ebp+0xc) 0/r32/eax +24286 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24287 (write-buffered *(ebp+0x10) %eax) +24288 (write-buffered *(ebp+0x10) ": stmt index: offset '") +24289 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24290 (write-buffered *(ebp+0x10) %eax) -24291 (write-buffered *(ebp+0x10) ": stmt index: cannot take an int for array '") -24292 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24293 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24294 (lookup *eax *(eax+4)) # Var-name Var-name => eax -24295 (write-buffered *(ebp+0x10) %eax) -24296 (write-buffered *(ebp+0x10) "'; create an offset instead. See mu.md for details.\n") -24297 (flush *(ebp+0x10)) -24298 (stop *(ebp+0x14) 1) -24299 # never gets here -24300 -24301 $check-mu-index-stmt:error-too-many-inouts: -24302 (write-buffered *(ebp+0x10) "fn ") -24303 8b/-> *(ebp+0xc) 0/r32/eax -24304 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24305 (write-buffered *(ebp+0x10) %eax) -24306 (write-buffered *(ebp+0x10) ": stmt index: too many inouts (2 required)\n") -24307 (flush *(ebp+0x10)) -24308 (stop *(ebp+0x14) 1) -24309 # never gets here -24310 -24311 $check-mu-index-stmt:error-too-few-outputs: -24312 (write-buffered *(ebp+0x10) "fn ") -24313 8b/-> *(ebp+0xc) 0/r32/eax -24314 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24315 (write-buffered *(ebp+0x10) %eax) -24316 (write-buffered *(ebp+0x10) ": stmt index: must have an output\n") -24317 (flush *(ebp+0x10)) -24318 (stop *(ebp+0x14) 1) -24319 # never gets here -24320 -24321 $check-mu-index-stmt:error-too-many-outputs: -24322 (write-buffered *(ebp+0x10) "fn ") -24323 8b/-> *(ebp+0xc) 0/r32/eax -24324 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24325 (write-buffered *(ebp+0x10) %eax) -24326 (write-buffered *(ebp+0x10) ": stmt index: too many outputs (1 required)\n") -24327 (flush *(ebp+0x10)) -24328 (stop *(ebp+0x14) 1) -24329 # never gets here -24330 -24331 $check-mu-index-stmt:error-output-not-in-register: -24332 (write-buffered *(ebp+0x10) "fn ") -24333 8b/-> *(ebp+0xc) 0/r32/eax -24334 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24335 (write-buffered *(ebp+0x10) %eax) -24336 (write-buffered *(ebp+0x10) ": stmt index: output '") -24337 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24291 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n") +24292 (flush *(ebp+0x10)) +24293 (stop *(ebp+0x14) 1) +24294 # never gets here +24295 +24296 $check-mu-index-stmt:error-index-on-stack: +24297 (write-buffered *(ebp+0x10) "fn ") +24298 8b/-> *(ebp+0xc) 0/r32/eax +24299 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24300 (write-buffered *(ebp+0x10) %eax) +24301 (write-buffered *(ebp+0x10) ": stmt index: second argument '") +24302 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +24303 (write-buffered *(ebp+0x10) %eax) +24304 (write-buffered *(ebp+0x10) "' must be in a register\n") +24305 (flush *(ebp+0x10)) +24306 (stop *(ebp+0x14) 1) +24307 # never gets here +24308 +24309 $check-mu-index-stmt:error-index-needs-offset: +24310 (write-buffered *(ebp+0x10) "fn ") +24311 8b/-> *(ebp+0xc) 0/r32/eax +24312 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24313 (write-buffered *(ebp+0x10) %eax) +24314 (write-buffered *(ebp+0x10) ": stmt index: cannot take an int for array '") +24315 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24316 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24317 (lookup *eax *(eax+4)) # Var-name Var-name => eax +24318 (write-buffered *(ebp+0x10) %eax) +24319 (write-buffered *(ebp+0x10) "'; create an offset instead. See mu.md for details.\n") +24320 (flush *(ebp+0x10)) +24321 (stop *(ebp+0x14) 1) +24322 # never gets here +24323 +24324 $check-mu-index-stmt:error-too-many-inouts: +24325 (write-buffered *(ebp+0x10) "fn ") +24326 8b/-> *(ebp+0xc) 0/r32/eax +24327 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24328 (write-buffered *(ebp+0x10) %eax) +24329 (write-buffered *(ebp+0x10) ": stmt index: too many inouts (2 required)\n") +24330 (flush *(ebp+0x10)) +24331 (stop *(ebp+0x14) 1) +24332 # never gets here +24333 +24334 $check-mu-index-stmt:error-too-few-outputs: +24335 (write-buffered *(ebp+0x10) "fn ") +24336 8b/-> *(ebp+0xc) 0/r32/eax +24337 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24338 (write-buffered *(ebp+0x10) %eax) -24339 (write-buffered *(ebp+0x10) "' is not in a register\n") +24339 (write-buffered *(ebp+0x10) ": stmt index: must have an output\n") 24340 (flush *(ebp+0x10)) 24341 (stop *(ebp+0x14) 1) 24342 # never gets here 24343 -24344 $check-mu-index-stmt:error-output-type-not-address: +24344 $check-mu-index-stmt:error-too-many-outputs: 24345 (write-buffered *(ebp+0x10) "fn ") 24346 8b/-> *(ebp+0xc) 0/r32/eax 24347 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24348 (write-buffered *(ebp+0x10) %eax) -24349 (write-buffered *(ebp+0x10) ": stmt index: output '") -24350 (lookup *edi *(edi+4)) # Var-name Var-name => eax -24351 (write-buffered *(ebp+0x10) %eax) -24352 (write-buffered *(ebp+0x10) "' must be an addr\n") -24353 (flush *(ebp+0x10)) -24354 (stop *(ebp+0x14) 1) -24355 # never gets here -24356 -24357 $check-mu-index-stmt:error-bad-output-type: -24358 (write-buffered *(ebp+0x10) "fn ") -24359 8b/-> *(ebp+0xc) 0/r32/eax -24360 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24349 (write-buffered *(ebp+0x10) ": stmt index: too many outputs (1 required)\n") +24350 (flush *(ebp+0x10)) +24351 (stop *(ebp+0x14) 1) +24352 # never gets here +24353 +24354 $check-mu-index-stmt:error-output-not-in-register: +24355 (write-buffered *(ebp+0x10) "fn ") +24356 8b/-> *(ebp+0xc) 0/r32/eax +24357 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24358 (write-buffered *(ebp+0x10) %eax) +24359 (write-buffered *(ebp+0x10) ": stmt index: output '") +24360 (lookup *edi *(edi+4)) # Var-name Var-name => eax 24361 (write-buffered *(ebp+0x10) %eax) -24362 (write-buffered *(ebp+0x10) ": stmt index: output '") -24363 (lookup *edi *(edi+4)) # Var-name Var-name => eax -24364 (write-buffered *(ebp+0x10) %eax) -24365 (write-buffered *(ebp+0x10) "' does not have the right type\n") -24366 (flush *(ebp+0x10)) -24367 (stop *(ebp+0x14) 1) -24368 # never gets here -24369 -24370 check-mu-length-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -24371 # . prologue -24372 55/push-ebp -24373 89/<- %ebp 4/r32/esp -24374 # . save registers -24375 50/push-eax -24376 51/push-ecx -24377 52/push-edx -24378 53/push-ebx -24379 56/push-esi -24380 57/push-edi -24381 # esi = stmt -24382 8b/-> *(ebp+8) 6/r32/esi -24383 # - check for 0 inouts -24384 # var base/ecx: (addr var) = stmt->inouts->value -24385 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24386 $check-mu-length-stmt:check-no-inouts: -24387 3d/compare-eax-and 0/imm32 -24388 0f 84/jump-if-= $check-mu-length-stmt:error-too-few-inouts/disp32 -24389 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24390 89/<- %ecx 0/r32/eax -24391 # - check base type is either (addr array ...) in register or (array ...) on stack -24392 # var base-type/ebx: (addr type-tree) = lookup(base->type) -24393 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -24394 89/<- %ebx 0/r32/eax -24395 # if base-type is an atom, abort with a precise error -24396 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -24397 { -24398 74/jump-if-= break/disp8 -24399 (simple-mu-type? %ebx 3) # array => eax -24400 3d/compare-eax-and 0/imm32/false -24401 0f 85/jump-if-!= $check-mu-length-stmt:error-base-array-atom-type/disp32 -24402 0f 84/jump-if-= $check-mu-length-stmt:error-base-non-array-type/disp32 -24403 } -24404 $check-mu-length-stmt:base-is-compound: -24405 # if type->left not addr or array, abort -24406 { -24407 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24408 (simple-mu-type? %eax 2) # addr => eax -24409 3d/compare-eax-and 0/imm32/false -24410 75/jump-if-!= break/disp8 -24411 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24412 (simple-mu-type? %eax 3) # array => eax -24413 3d/compare-eax-and 0/imm32/false -24414 75/jump-if-!= break/disp8 -24415 e9/jump $check-mu-length-stmt:error-base-non-array-type/disp32 -24416 } -24417 # if (type->left == addr) ensure type->right->left == array and type->register exists -24418 { -24419 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24420 (simple-mu-type? %eax 2) # addr => eax -24421 3d/compare-eax-and 0/imm32/false -24422 74/jump-if-= break/disp8 -24423 $check-mu-length-stmt:base-is-addr: -24424 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -24425 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -24426 (simple-mu-type? %eax 3) # array => eax -24427 3d/compare-eax-and 0/imm32/false -24428 0f 84/jump-if-= $check-mu-length-stmt:error-base-non-array-type/disp32 -24429 $check-mu-length-stmt:check-base-addr-is-register: -24430 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -24431 0f 84/jump-if-= $check-mu-length-stmt:error-base-address-array-type-on-stack/disp32 -24432 } -24433 # if (type->left == array) ensure type->register doesn't exist -24434 { -24435 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24436 (simple-mu-type? %eax 3) # array => eax -24437 3d/compare-eax-and 0/imm32/false -24438 74/jump-if-= break/disp8 -24439 $check-mu-length-stmt:base-is-array: -24440 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -24441 0f 85/jump-if-!= $check-mu-length-stmt:error-base-array-type-in-register/disp32 -24442 } -24443 # if (base-type->left == addr) base-type = base-type->right -24444 { -24445 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24446 (simple-mu-type? %eax 2) # addr => eax -24447 3d/compare-eax-and 0/imm32/false -24448 74/jump-if-= break/disp8 -24449 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -24450 89/<- %ebx 0/r32/eax -24451 } -24452 # - check for too many inouts -24453 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24454 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24455 3d/compare-eax-and 0/imm32/false -24456 0f 85/jump-if-!= $check-mu-length-stmt:error-too-many-inouts/disp32 -24457 # - check for 0 outputs -24458 # var output/edi: (addr var) = stmt->outputs->value -24459 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -24460 3d/compare-eax-and 0/imm32/false -24461 0f 84/jump-if-= $check-mu-length-stmt:error-too-few-outputs/disp32 -24462 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24463 89/<- %edi 0/r32/eax -24464 # - check output type -24465 # must have a non-atomic type -24466 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -24467 (simple-mu-type? %eax 1) # int => eax -24468 3d/compare-eax-and 0/imm32/false -24469 0f 84/jump-if-= $check-mu-length-stmt:error-invalid-output-type/disp32 -24470 # - check for too many outputs -24471 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -24472 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24473 3d/compare-eax-and 0/imm32/false -24474 0f 85/jump-if-!= $check-mu-length-stmt:error-too-many-outputs/disp32 -24475 $check-mu-length-stmt:end: -24476 # . restore registers -24477 5f/pop-to-edi -24478 5e/pop-to-esi -24479 5b/pop-to-ebx -24480 5a/pop-to-edx -24481 59/pop-to-ecx -24482 58/pop-to-eax -24483 # . epilogue -24484 89/<- %esp 5/r32/ebp -24485 5d/pop-to-ebp -24486 c3/return -24487 -24488 $check-mu-length-stmt:error-base-non-array-type: -24489 (write-buffered *(ebp+0x10) "fn ") -24490 8b/-> *(ebp+0xc) 0/r32/eax -24491 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24492 (write-buffered *(ebp+0x10) %eax) -24493 (write-buffered *(ebp+0x10) ": stmt length: var '") -24494 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24495 (write-buffered *(ebp+0x10) %eax) -24496 (write-buffered *(ebp+0x10) "' is not an array\n") -24497 (flush *(ebp+0x10)) -24498 (stop *(ebp+0x14) 1) -24499 # never gets here -24500 -24501 $check-mu-length-stmt:error-base-array-atom-type: -24502 (write-buffered *(ebp+0x10) "fn ") -24503 8b/-> *(ebp+0xc) 0/r32/eax -24504 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24505 (write-buffered *(ebp+0x10) %eax) -24506 (write-buffered *(ebp+0x10) ": stmt length: array '") -24507 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24508 (write-buffered *(ebp+0x10) %eax) -24509 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n") -24510 (flush *(ebp+0x10)) -24511 (stop *(ebp+0x14) 1) -24512 # never gets here -24513 -24514 $check-mu-length-stmt:error-base-address-array-type-on-stack: -24515 (write-buffered *(ebp+0x10) "fn ") -24516 8b/-> *(ebp+0xc) 0/r32/eax -24517 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24362 (write-buffered *(ebp+0x10) "' is not in a register\n") +24363 (flush *(ebp+0x10)) +24364 (stop *(ebp+0x14) 1) +24365 # never gets here +24366 +24367 $check-mu-index-stmt:error-output-type-not-address: +24368 (write-buffered *(ebp+0x10) "fn ") +24369 8b/-> *(ebp+0xc) 0/r32/eax +24370 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24371 (write-buffered *(ebp+0x10) %eax) +24372 (write-buffered *(ebp+0x10) ": stmt index: output '") +24373 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24374 (write-buffered *(ebp+0x10) %eax) +24375 (write-buffered *(ebp+0x10) "' must be an addr\n") +24376 (flush *(ebp+0x10)) +24377 (stop *(ebp+0x14) 1) +24378 # never gets here +24379 +24380 $check-mu-index-stmt:error-bad-output-type: +24381 (write-buffered *(ebp+0x10) "fn ") +24382 8b/-> *(ebp+0xc) 0/r32/eax +24383 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24384 (write-buffered *(ebp+0x10) %eax) +24385 (write-buffered *(ebp+0x10) ": stmt index: output '") +24386 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24387 (write-buffered *(ebp+0x10) %eax) +24388 (write-buffered *(ebp+0x10) "' does not have the right type\n") +24389 (flush *(ebp+0x10)) +24390 (stop *(ebp+0x14) 1) +24391 # never gets here +24392 +24393 check-mu-length-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +24394 # . prologue +24395 55/push-ebp +24396 89/<- %ebp 4/r32/esp +24397 # . save registers +24398 50/push-eax +24399 51/push-ecx +24400 52/push-edx +24401 53/push-ebx +24402 56/push-esi +24403 57/push-edi +24404 # esi = stmt +24405 8b/-> *(ebp+8) 6/r32/esi +24406 # - check for 0 inouts +24407 # var base/ecx: (addr var) = stmt->inouts->value +24408 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24409 $check-mu-length-stmt:check-no-inouts: +24410 3d/compare-eax-and 0/imm32 +24411 0f 84/jump-if-= $check-mu-length-stmt:error-too-few-inouts/disp32 +24412 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24413 89/<- %ecx 0/r32/eax +24414 # - check base type is either (addr array ...) in register or (array ...) on stack +24415 # var base-type/ebx: (addr type-tree) = lookup(base->type) +24416 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +24417 89/<- %ebx 0/r32/eax +24418 # if base-type is an atom, abort with a precise error +24419 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +24420 { +24421 74/jump-if-= break/disp8 +24422 (simple-mu-type? %ebx 3) # array => eax +24423 3d/compare-eax-and 0/imm32/false +24424 0f 85/jump-if-!= $check-mu-length-stmt:error-base-array-atom-type/disp32 +24425 0f 84/jump-if-= $check-mu-length-stmt:error-base-non-array-type/disp32 +24426 } +24427 $check-mu-length-stmt:base-is-compound: +24428 # if type->left not addr or array, abort +24429 { +24430 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24431 (simple-mu-type? %eax 2) # addr => eax +24432 3d/compare-eax-and 0/imm32/false +24433 75/jump-if-!= break/disp8 +24434 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24435 (simple-mu-type? %eax 3) # array => eax +24436 3d/compare-eax-and 0/imm32/false +24437 75/jump-if-!= break/disp8 +24438 e9/jump $check-mu-length-stmt:error-base-non-array-type/disp32 +24439 } +24440 # if (type->left == addr) ensure type->right->left == array and type->register exists +24441 { +24442 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24443 (simple-mu-type? %eax 2) # addr => eax +24444 3d/compare-eax-and 0/imm32/false +24445 74/jump-if-= break/disp8 +24446 $check-mu-length-stmt:base-is-addr: +24447 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +24448 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +24449 (simple-mu-type? %eax 3) # array => eax +24450 3d/compare-eax-and 0/imm32/false +24451 0f 84/jump-if-= $check-mu-length-stmt:error-base-non-array-type/disp32 +24452 $check-mu-length-stmt:check-base-addr-is-register: +24453 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +24454 0f 84/jump-if-= $check-mu-length-stmt:error-base-address-array-type-on-stack/disp32 +24455 } +24456 # if (type->left == array) ensure type->register doesn't exist +24457 { +24458 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24459 (simple-mu-type? %eax 3) # array => eax +24460 3d/compare-eax-and 0/imm32/false +24461 74/jump-if-= break/disp8 +24462 $check-mu-length-stmt:base-is-array: +24463 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +24464 0f 85/jump-if-!= $check-mu-length-stmt:error-base-array-type-in-register/disp32 +24465 } +24466 # if (base-type->left == addr) base-type = base-type->right +24467 { +24468 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24469 (simple-mu-type? %eax 2) # addr => eax +24470 3d/compare-eax-and 0/imm32/false +24471 74/jump-if-= break/disp8 +24472 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +24473 89/<- %ebx 0/r32/eax +24474 } +24475 # - check for too many inouts +24476 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24477 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24478 3d/compare-eax-and 0/imm32/false +24479 0f 85/jump-if-!= $check-mu-length-stmt:error-too-many-inouts/disp32 +24480 # - check for 0 outputs +24481 # var output/edi: (addr var) = stmt->outputs->value +24482 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +24483 3d/compare-eax-and 0/imm32/false +24484 0f 84/jump-if-= $check-mu-length-stmt:error-too-few-outputs/disp32 +24485 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24486 89/<- %edi 0/r32/eax +24487 # - check output type +24488 # must have a non-atomic type +24489 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +24490 (simple-mu-type? %eax 1) # int => eax +24491 3d/compare-eax-and 0/imm32/false +24492 0f 84/jump-if-= $check-mu-length-stmt:error-invalid-output-type/disp32 +24493 # - check for too many outputs +24494 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +24495 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24496 3d/compare-eax-and 0/imm32/false +24497 0f 85/jump-if-!= $check-mu-length-stmt:error-too-many-outputs/disp32 +24498 $check-mu-length-stmt:end: +24499 # . restore registers +24500 5f/pop-to-edi +24501 5e/pop-to-esi +24502 5b/pop-to-ebx +24503 5a/pop-to-edx +24504 59/pop-to-ecx +24505 58/pop-to-eax +24506 # . epilogue +24507 89/<- %esp 5/r32/ebp +24508 5d/pop-to-ebp +24509 c3/return +24510 +24511 $check-mu-length-stmt:error-base-non-array-type: +24512 (write-buffered *(ebp+0x10) "fn ") +24513 8b/-> *(ebp+0xc) 0/r32/eax +24514 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24515 (write-buffered *(ebp+0x10) %eax) +24516 (write-buffered *(ebp+0x10) ": stmt length: var '") +24517 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24518 (write-buffered *(ebp+0x10) %eax) -24519 (write-buffered *(ebp+0x10) ": stmt length: var '") -24520 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24521 (write-buffered *(ebp+0x10) %eax) -24522 (write-buffered *(ebp+0x10) "' is an addr to an array, and so must live in a register\n") -24523 (flush *(ebp+0x10)) -24524 (stop *(ebp+0x14) 1) -24525 # never gets here -24526 -24527 $check-mu-length-stmt:error-base-array-type-in-register: -24528 (write-buffered *(ebp+0x10) "fn ") -24529 8b/-> *(ebp+0xc) 0/r32/eax -24530 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24519 (write-buffered *(ebp+0x10) "' is not an array\n") +24520 (flush *(ebp+0x10)) +24521 (stop *(ebp+0x14) 1) +24522 # never gets here +24523 +24524 $check-mu-length-stmt:error-base-array-atom-type: +24525 (write-buffered *(ebp+0x10) "fn ") +24526 8b/-> *(ebp+0xc) 0/r32/eax +24527 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24528 (write-buffered *(ebp+0x10) %eax) +24529 (write-buffered *(ebp+0x10) ": stmt length: array '") +24530 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24531 (write-buffered *(ebp+0x10) %eax) -24532 (write-buffered *(ebp+0x10) ": stmt length: var '") -24533 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24534 (write-buffered *(ebp+0x10) %eax) -24535 (write-buffered *(ebp+0x10) "' is an array, and so must live on the stack\n") -24536 (flush *(ebp+0x10)) -24537 (stop *(ebp+0x14) 1) -24538 # never gets here -24539 -24540 $check-mu-length-stmt:error-too-few-inouts: -24541 (write-buffered *(ebp+0x10) "fn ") -24542 8b/-> *(ebp+0xc) 0/r32/eax -24543 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24532 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n") +24533 (flush *(ebp+0x10)) +24534 (stop *(ebp+0x14) 1) +24535 # never gets here +24536 +24537 $check-mu-length-stmt:error-base-address-array-type-on-stack: +24538 (write-buffered *(ebp+0x10) "fn ") +24539 8b/-> *(ebp+0xc) 0/r32/eax +24540 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24541 (write-buffered *(ebp+0x10) %eax) +24542 (write-buffered *(ebp+0x10) ": stmt length: var '") +24543 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24544 (write-buffered *(ebp+0x10) %eax) -24545 (write-buffered *(ebp+0x10) ": stmt length: too few inouts (1 required)\n") +24545 (write-buffered *(ebp+0x10) "' is an addr to an array, and so must live in a register\n") 24546 (flush *(ebp+0x10)) 24547 (stop *(ebp+0x14) 1) 24548 # never gets here 24549 -24550 $check-mu-length-stmt:error-invalid-index-type: +24550 $check-mu-length-stmt:error-base-array-type-in-register: 24551 (write-buffered *(ebp+0x10) "fn ") 24552 8b/-> *(ebp+0xc) 0/r32/eax 24553 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24554 (write-buffered *(ebp+0x10) %eax) -24555 (write-buffered *(ebp+0x10) ": stmt length: second argument '") +24555 (write-buffered *(ebp+0x10) ": stmt length: var '") 24556 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24557 (write-buffered *(ebp+0x10) %eax) -24558 (write-buffered *(ebp+0x10) "' must be an int or offset\n") +24558 (write-buffered *(ebp+0x10) "' is an array, and so must live on the stack\n") 24559 (flush *(ebp+0x10)) 24560 (stop *(ebp+0x14) 1) 24561 # never gets here 24562 -24563 $check-mu-length-stmt:error-index-offset-atom-type: +24563 $check-mu-length-stmt:error-too-few-inouts: 24564 (write-buffered *(ebp+0x10) "fn ") 24565 8b/-> *(ebp+0xc) 0/r32/eax 24566 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24567 (write-buffered *(ebp+0x10) %eax) -24568 (write-buffered *(ebp+0x10) ": stmt length: offset '") -24569 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24570 (write-buffered *(ebp+0x10) %eax) -24571 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n") -24572 (flush *(ebp+0x10)) -24573 (stop *(ebp+0x14) 1) -24574 # never gets here -24575 -24576 $check-mu-length-stmt:error-index-on-stack: -24577 (write-buffered *(ebp+0x10) "fn ") -24578 8b/-> *(ebp+0xc) 0/r32/eax -24579 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24568 (write-buffered *(ebp+0x10) ": stmt length: too few inouts (1 required)\n") +24569 (flush *(ebp+0x10)) +24570 (stop *(ebp+0x14) 1) +24571 # never gets here +24572 +24573 $check-mu-length-stmt:error-invalid-index-type: +24574 (write-buffered *(ebp+0x10) "fn ") +24575 8b/-> *(ebp+0xc) 0/r32/eax +24576 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24577 (write-buffered *(ebp+0x10) %eax) +24578 (write-buffered *(ebp+0x10) ": stmt length: second argument '") +24579 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24580 (write-buffered *(ebp+0x10) %eax) -24581 (write-buffered *(ebp+0x10) ": stmt length: second argument '") -24582 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24583 (write-buffered *(ebp+0x10) %eax) -24584 (write-buffered *(ebp+0x10) "' must be in a register\n") -24585 (flush *(ebp+0x10)) -24586 (stop *(ebp+0x14) 1) -24587 # never gets here -24588 -24589 $check-mu-length-stmt:error-index-needs-offset: -24590 (write-buffered *(ebp+0x10) "fn ") -24591 8b/-> *(ebp+0xc) 0/r32/eax -24592 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24581 (write-buffered *(ebp+0x10) "' must be an int or offset\n") +24582 (flush *(ebp+0x10)) +24583 (stop *(ebp+0x14) 1) +24584 # never gets here +24585 +24586 $check-mu-length-stmt:error-index-offset-atom-type: +24587 (write-buffered *(ebp+0x10) "fn ") +24588 8b/-> *(ebp+0xc) 0/r32/eax +24589 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24590 (write-buffered *(ebp+0x10) %eax) +24591 (write-buffered *(ebp+0x10) ": stmt length: offset '") +24592 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24593 (write-buffered *(ebp+0x10) %eax) -24594 (write-buffered *(ebp+0x10) ": stmt length: cannot take an int for array '") -24595 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24596 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24597 (lookup *eax *(eax+4)) # Var-name Var-name => eax -24598 (write-buffered *(ebp+0x10) %eax) -24599 (write-buffered *(ebp+0x10) "'; create an offset instead. See mu.md for details.\n") -24600 (flush *(ebp+0x10)) -24601 (stop *(ebp+0x14) 1) -24602 # never gets here -24603 -24604 $check-mu-length-stmt:error-too-many-inouts: -24605 (write-buffered *(ebp+0x10) "fn ") -24606 8b/-> *(ebp+0xc) 0/r32/eax -24607 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24608 (write-buffered *(ebp+0x10) %eax) -24609 (write-buffered *(ebp+0x10) ": stmt length: too many inouts (1 required)\n") -24610 (flush *(ebp+0x10)) -24611 (stop *(ebp+0x14) 1) -24612 # never gets here -24613 -24614 $check-mu-length-stmt:error-too-few-outputs: -24615 (write-buffered *(ebp+0x10) "fn ") -24616 8b/-> *(ebp+0xc) 0/r32/eax -24617 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24618 (write-buffered *(ebp+0x10) %eax) -24619 (write-buffered *(ebp+0x10) ": stmt length: must have an output\n") -24620 (flush *(ebp+0x10)) -24621 (stop *(ebp+0x14) 1) -24622 # never gets here -24623 -24624 $check-mu-length-stmt:error-too-many-outputs: -24625 (write-buffered *(ebp+0x10) "fn ") -24626 8b/-> *(ebp+0xc) 0/r32/eax -24627 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24628 (write-buffered *(ebp+0x10) %eax) -24629 (write-buffered *(ebp+0x10) ": stmt length: too many outputs (1 required)\n") -24630 (flush *(ebp+0x10)) -24631 (stop *(ebp+0x14) 1) -24632 # never gets here -24633 -24634 $check-mu-length-stmt:error-output-not-in-register: -24635 (write-buffered *(ebp+0x10) "fn ") -24636 8b/-> *(ebp+0xc) 0/r32/eax -24637 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24638 (write-buffered *(ebp+0x10) %eax) -24639 (write-buffered *(ebp+0x10) ": stmt length: output '") -24640 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24594 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n") +24595 (flush *(ebp+0x10)) +24596 (stop *(ebp+0x14) 1) +24597 # never gets here +24598 +24599 $check-mu-length-stmt:error-index-on-stack: +24600 (write-buffered *(ebp+0x10) "fn ") +24601 8b/-> *(ebp+0xc) 0/r32/eax +24602 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24603 (write-buffered *(ebp+0x10) %eax) +24604 (write-buffered *(ebp+0x10) ": stmt length: second argument '") +24605 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +24606 (write-buffered *(ebp+0x10) %eax) +24607 (write-buffered *(ebp+0x10) "' must be in a register\n") +24608 (flush *(ebp+0x10)) +24609 (stop *(ebp+0x14) 1) +24610 # never gets here +24611 +24612 $check-mu-length-stmt:error-index-needs-offset: +24613 (write-buffered *(ebp+0x10) "fn ") +24614 8b/-> *(ebp+0xc) 0/r32/eax +24615 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24616 (write-buffered *(ebp+0x10) %eax) +24617 (write-buffered *(ebp+0x10) ": stmt length: cannot take an int for array '") +24618 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24619 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24620 (lookup *eax *(eax+4)) # Var-name Var-name => eax +24621 (write-buffered *(ebp+0x10) %eax) +24622 (write-buffered *(ebp+0x10) "'; create an offset instead. See mu.md for details.\n") +24623 (flush *(ebp+0x10)) +24624 (stop *(ebp+0x14) 1) +24625 # never gets here +24626 +24627 $check-mu-length-stmt:error-too-many-inouts: +24628 (write-buffered *(ebp+0x10) "fn ") +24629 8b/-> *(ebp+0xc) 0/r32/eax +24630 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24631 (write-buffered *(ebp+0x10) %eax) +24632 (write-buffered *(ebp+0x10) ": stmt length: too many inouts (1 required)\n") +24633 (flush *(ebp+0x10)) +24634 (stop *(ebp+0x14) 1) +24635 # never gets here +24636 +24637 $check-mu-length-stmt:error-too-few-outputs: +24638 (write-buffered *(ebp+0x10) "fn ") +24639 8b/-> *(ebp+0xc) 0/r32/eax +24640 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24641 (write-buffered *(ebp+0x10) %eax) -24642 (write-buffered *(ebp+0x10) "' is not in a register\n") +24642 (write-buffered *(ebp+0x10) ": stmt length: must have an output\n") 24643 (flush *(ebp+0x10)) 24644 (stop *(ebp+0x14) 1) 24645 # never gets here 24646 -24647 $check-mu-length-stmt:error-invalid-output-type: +24647 $check-mu-length-stmt:error-too-many-outputs: 24648 (write-buffered *(ebp+0x10) "fn ") 24649 8b/-> *(ebp+0xc) 0/r32/eax 24650 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24651 (write-buffered *(ebp+0x10) %eax) -24652 (write-buffered *(ebp+0x10) ": stmt length: output '") -24653 (lookup *edi *(edi+4)) # Var-name Var-name => eax -24654 (write-buffered *(ebp+0x10) %eax) -24655 (write-buffered *(ebp+0x10) "' does not have the right type\n") -24656 (flush *(ebp+0x10)) -24657 (stop *(ebp+0x14) 1) -24658 # never gets here -24659 -24660 check-mu-compute-offset-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -24661 # . prologue -24662 55/push-ebp -24663 89/<- %ebp 4/r32/esp -24664 # . save registers -24665 50/push-eax -24666 51/push-ecx -24667 52/push-edx -24668 53/push-ebx -24669 56/push-esi -24670 57/push-edi -24671 # esi = stmt -24672 8b/-> *(ebp+8) 6/r32/esi -24673 # - check for 0 inouts -24674 # var base/ecx: (addr var) = stmt->inouts->value -24675 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24676 $check-mu-compute-offset-stmt:check-no-inouts: -24677 3d/compare-eax-and 0/imm32 -24678 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-inouts/disp32 -24679 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24680 89/<- %ecx 0/r32/eax -24681 # - check base type is either (addr array ...) in register or (array ...) on stack -24682 # var base-type/ebx: (addr type-tree) = lookup(base->type) -24683 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -24684 89/<- %ebx 0/r32/eax -24685 # if base-type is an atom, abort with a precise error -24686 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -24687 { -24688 74/jump-if-= break/disp8 -24689 (simple-mu-type? %ebx 3) # array => eax -24690 3d/compare-eax-and 0/imm32/false -24691 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-base-array-atom-type/disp32 -24692 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-base-non-array-type/disp32 -24693 } -24694 $check-mu-compute-offset-stmt:base-is-compound: -24695 # if type->left not addr or array, abort -24696 { -24697 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24698 (simple-mu-type? %eax 2) # addr => eax -24699 3d/compare-eax-and 0/imm32/false -24700 75/jump-if-!= break/disp8 -24701 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24702 (simple-mu-type? %eax 3) # array => eax -24703 3d/compare-eax-and 0/imm32/false -24704 75/jump-if-!= break/disp8 -24705 e9/jump $check-mu-compute-offset-stmt:error-base-non-array-type/disp32 -24706 } -24707 # if (type->left == addr) ensure type->right->left == array and type->register exists -24708 { -24709 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24710 (simple-mu-type? %eax 2) # addr => eax -24711 3d/compare-eax-and 0/imm32/false -24712 74/jump-if-= break/disp8 -24713 $check-mu-compute-offset-stmt:base-is-addr: -24714 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -24715 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -24716 (simple-mu-type? %eax 3) # array => eax -24717 3d/compare-eax-and 0/imm32/false -24718 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-base-non-array-type/disp32 -24719 } -24720 # if (base-type->left == addr) base-type = base-type->right -24721 { -24722 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -24723 (simple-mu-type? %eax 2) # addr => eax -24724 3d/compare-eax-and 0/imm32/false -24725 74/jump-if-= break/disp8 -24726 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -24727 89/<- %ebx 0/r32/eax -24728 } -24729 # - check for 1 inout -24730 # var index/ecx: (addr stmt-var) = stmt->inouts->next->value -24731 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24732 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24733 $check-mu-compute-offset-stmt:check-single-inout: -24734 3d/compare-eax-and 0/imm32 -24735 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-inouts/disp32 -24736 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24737 89/<- %ecx 0/r32/eax -24738 # - check index is either a literal or register -24739 # var index-type/edx: (addr type-tree) -24740 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -24741 89/<- %edx 0/r32/eax -24742 # index type must be a literal or int -24743 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom -24744 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-invalid-index-type/disp32 -24745 { -24746 $check-mu-compute-offset-stmt:index-type-is-atom: -24747 (simple-mu-type? %edx 0) # literal => eax -24748 3d/compare-eax-and 0/imm32/false -24749 75/jump-if-!= break/disp8 -24750 (simple-mu-type? %edx 1) # int => eax -24751 3d/compare-eax-and 0/imm32/false -24752 75/jump-if-!= break/disp8 -24753 e9/jump $check-mu-compute-offset-stmt:error-invalid-index-type/disp32 -24754 } -24755 # - check for too many inouts -24756 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24757 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24758 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24759 3d/compare-eax-and 0/imm32/false -24760 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-too-many-inouts/disp32 -24761 # - check for 0 outputs -24762 # var output/edi: (addr var) = stmt->outputs->value -24763 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -24764 3d/compare-eax-and 0/imm32/false -24765 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-outputs/disp32 -24766 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -24767 89/<- %edi 0/r32/eax -24768 # - check output type -24769 # must have a non-atomic type -24770 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -24771 89/<- %edx 0/r32/eax -24772 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom -24773 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-output-type-not-offset/disp32 -24774 # type must start with (offset ...) -24775 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -24776 (simple-mu-type? %eax 7) # offset => eax -24777 3d/compare-eax-and 0/imm32/false -24778 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-output-type-not-offset/disp32 -24779 # if tail(base-type) != tail(output-type) abort -24780 (type-tail %ebx) # => eax -24781 89/<- %ebx 0/r32/eax -24782 (type-tail %edx) # => eax -24783 (type-equal? %ebx %eax) # => eax -24784 3d/compare-eax-and 0/imm32/false -24785 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-bad-output-type/disp32 -24786 # - check for too many outputs -24787 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -24788 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -24789 3d/compare-eax-and 0/imm32/false -24790 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-too-many-outputs/disp32 -24791 $check-mu-compute-offset-stmt:end: -24792 # . restore registers -24793 5f/pop-to-edi -24794 5e/pop-to-esi -24795 5b/pop-to-ebx -24796 5a/pop-to-edx -24797 59/pop-to-ecx -24798 58/pop-to-eax -24799 # . epilogue -24800 89/<- %esp 5/r32/ebp -24801 5d/pop-to-ebp -24802 c3/return -24803 -24804 $check-mu-compute-offset-stmt:error-base-non-array-type: -24805 (write-buffered *(ebp+0x10) "fn ") -24806 8b/-> *(ebp+0xc) 0/r32/eax -24807 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24808 (write-buffered *(ebp+0x10) %eax) -24809 (write-buffered *(ebp+0x10) ": stmt compute-offset: var '") -24810 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24811 (write-buffered *(ebp+0x10) %eax) -24812 (write-buffered *(ebp+0x10) "' is not an array\n") -24813 (flush *(ebp+0x10)) -24814 (stop *(ebp+0x14) 1) -24815 # never gets here -24816 -24817 $check-mu-compute-offset-stmt:error-base-array-atom-type: -24818 (write-buffered *(ebp+0x10) "fn ") -24819 8b/-> *(ebp+0xc) 0/r32/eax -24820 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24821 (write-buffered *(ebp+0x10) %eax) -24822 (write-buffered *(ebp+0x10) ": stmt compute-offset: array '") -24823 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24824 (write-buffered *(ebp+0x10) %eax) -24825 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n") -24826 (flush *(ebp+0x10)) -24827 (stop *(ebp+0x14) 1) -24828 # never gets here -24829 -24830 $check-mu-compute-offset-stmt:error-too-few-inouts: -24831 (write-buffered *(ebp+0x10) "fn ") -24832 8b/-> *(ebp+0xc) 0/r32/eax -24833 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24652 (write-buffered *(ebp+0x10) ": stmt length: too many outputs (1 required)\n") +24653 (flush *(ebp+0x10)) +24654 (stop *(ebp+0x14) 1) +24655 # never gets here +24656 +24657 $check-mu-length-stmt:error-output-not-in-register: +24658 (write-buffered *(ebp+0x10) "fn ") +24659 8b/-> *(ebp+0xc) 0/r32/eax +24660 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24661 (write-buffered *(ebp+0x10) %eax) +24662 (write-buffered *(ebp+0x10) ": stmt length: output '") +24663 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24664 (write-buffered *(ebp+0x10) %eax) +24665 (write-buffered *(ebp+0x10) "' is not in a register\n") +24666 (flush *(ebp+0x10)) +24667 (stop *(ebp+0x14) 1) +24668 # never gets here +24669 +24670 $check-mu-length-stmt:error-invalid-output-type: +24671 (write-buffered *(ebp+0x10) "fn ") +24672 8b/-> *(ebp+0xc) 0/r32/eax +24673 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24674 (write-buffered *(ebp+0x10) %eax) +24675 (write-buffered *(ebp+0x10) ": stmt length: output '") +24676 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24677 (write-buffered *(ebp+0x10) %eax) +24678 (write-buffered *(ebp+0x10) "' does not have the right type\n") +24679 (flush *(ebp+0x10)) +24680 (stop *(ebp+0x14) 1) +24681 # never gets here +24682 +24683 check-mu-compute-offset-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +24684 # . prologue +24685 55/push-ebp +24686 89/<- %ebp 4/r32/esp +24687 # . save registers +24688 50/push-eax +24689 51/push-ecx +24690 52/push-edx +24691 53/push-ebx +24692 56/push-esi +24693 57/push-edi +24694 # esi = stmt +24695 8b/-> *(ebp+8) 6/r32/esi +24696 # - check for 0 inouts +24697 # var base/ecx: (addr var) = stmt->inouts->value +24698 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24699 $check-mu-compute-offset-stmt:check-no-inouts: +24700 3d/compare-eax-and 0/imm32 +24701 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-inouts/disp32 +24702 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24703 89/<- %ecx 0/r32/eax +24704 # - check base type is either (addr array ...) in register or (array ...) on stack +24705 # var base-type/ebx: (addr type-tree) = lookup(base->type) +24706 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +24707 89/<- %ebx 0/r32/eax +24708 # if base-type is an atom, abort with a precise error +24709 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +24710 { +24711 74/jump-if-= break/disp8 +24712 (simple-mu-type? %ebx 3) # array => eax +24713 3d/compare-eax-and 0/imm32/false +24714 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-base-array-atom-type/disp32 +24715 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-base-non-array-type/disp32 +24716 } +24717 $check-mu-compute-offset-stmt:base-is-compound: +24718 # if type->left not addr or array, abort +24719 { +24720 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24721 (simple-mu-type? %eax 2) # addr => eax +24722 3d/compare-eax-and 0/imm32/false +24723 75/jump-if-!= break/disp8 +24724 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24725 (simple-mu-type? %eax 3) # array => eax +24726 3d/compare-eax-and 0/imm32/false +24727 75/jump-if-!= break/disp8 +24728 e9/jump $check-mu-compute-offset-stmt:error-base-non-array-type/disp32 +24729 } +24730 # if (type->left == addr) ensure type->right->left == array and type->register exists +24731 { +24732 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24733 (simple-mu-type? %eax 2) # addr => eax +24734 3d/compare-eax-and 0/imm32/false +24735 74/jump-if-= break/disp8 +24736 $check-mu-compute-offset-stmt:base-is-addr: +24737 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +24738 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +24739 (simple-mu-type? %eax 3) # array => eax +24740 3d/compare-eax-and 0/imm32/false +24741 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-base-non-array-type/disp32 +24742 } +24743 # if (base-type->left == addr) base-type = base-type->right +24744 { +24745 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +24746 (simple-mu-type? %eax 2) # addr => eax +24747 3d/compare-eax-and 0/imm32/false +24748 74/jump-if-= break/disp8 +24749 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +24750 89/<- %ebx 0/r32/eax +24751 } +24752 # - check for 1 inout +24753 # var index/ecx: (addr stmt-var) = stmt->inouts->next->value +24754 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24755 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24756 $check-mu-compute-offset-stmt:check-single-inout: +24757 3d/compare-eax-and 0/imm32 +24758 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-inouts/disp32 +24759 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24760 89/<- %ecx 0/r32/eax +24761 # - check index is either a literal or register +24762 # var index-type/edx: (addr type-tree) +24763 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +24764 89/<- %edx 0/r32/eax +24765 # index type must be a literal or int +24766 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +24767 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-invalid-index-type/disp32 +24768 { +24769 $check-mu-compute-offset-stmt:index-type-is-atom: +24770 (simple-mu-type? %edx 0) # literal => eax +24771 3d/compare-eax-and 0/imm32/false +24772 75/jump-if-!= break/disp8 +24773 (simple-mu-type? %edx 1) # int => eax +24774 3d/compare-eax-and 0/imm32/false +24775 75/jump-if-!= break/disp8 +24776 e9/jump $check-mu-compute-offset-stmt:error-invalid-index-type/disp32 +24777 } +24778 # - check for too many inouts +24779 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24780 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24781 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24782 3d/compare-eax-and 0/imm32/false +24783 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-too-many-inouts/disp32 +24784 # - check for 0 outputs +24785 # var output/edi: (addr var) = stmt->outputs->value +24786 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +24787 3d/compare-eax-and 0/imm32/false +24788 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-outputs/disp32 +24789 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +24790 89/<- %edi 0/r32/eax +24791 # - check output type +24792 # must have a non-atomic type +24793 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +24794 89/<- %edx 0/r32/eax +24795 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +24796 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-output-type-not-offset/disp32 +24797 # type must start with (offset ...) +24798 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +24799 (simple-mu-type? %eax 7) # offset => eax +24800 3d/compare-eax-and 0/imm32/false +24801 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-output-type-not-offset/disp32 +24802 # if tail(base-type) != tail(output-type) abort +24803 (type-tail %ebx) # => eax +24804 89/<- %ebx 0/r32/eax +24805 (type-tail %edx) # => eax +24806 (type-equal? %ebx %eax) # => eax +24807 3d/compare-eax-and 0/imm32/false +24808 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-bad-output-type/disp32 +24809 # - check for too many outputs +24810 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +24811 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +24812 3d/compare-eax-and 0/imm32/false +24813 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-too-many-outputs/disp32 +24814 $check-mu-compute-offset-stmt:end: +24815 # . restore registers +24816 5f/pop-to-edi +24817 5e/pop-to-esi +24818 5b/pop-to-ebx +24819 5a/pop-to-edx +24820 59/pop-to-ecx +24821 58/pop-to-eax +24822 # . epilogue +24823 89/<- %esp 5/r32/ebp +24824 5d/pop-to-ebp +24825 c3/return +24826 +24827 $check-mu-compute-offset-stmt:error-base-non-array-type: +24828 (write-buffered *(ebp+0x10) "fn ") +24829 8b/-> *(ebp+0xc) 0/r32/eax +24830 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24831 (write-buffered *(ebp+0x10) %eax) +24832 (write-buffered *(ebp+0x10) ": stmt compute-offset: var '") +24833 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24834 (write-buffered *(ebp+0x10) %eax) -24835 (write-buffered *(ebp+0x10) ": stmt compute-offset: too few inouts (2 required)\n") +24835 (write-buffered *(ebp+0x10) "' is not an array\n") 24836 (flush *(ebp+0x10)) 24837 (stop *(ebp+0x14) 1) 24838 # never gets here 24839 -24840 $check-mu-compute-offset-stmt:error-invalid-index-type: +24840 $check-mu-compute-offset-stmt:error-base-array-atom-type: 24841 (write-buffered *(ebp+0x10) "fn ") 24842 8b/-> *(ebp+0xc) 0/r32/eax 24843 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24844 (write-buffered *(ebp+0x10) %eax) -24845 (write-buffered *(ebp+0x10) ": stmt compute-offset: second argument '") +24845 (write-buffered *(ebp+0x10) ": stmt compute-offset: array '") 24846 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24847 (write-buffered *(ebp+0x10) %eax) -24848 (write-buffered *(ebp+0x10) "' must be an int\n") +24848 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n") 24849 (flush *(ebp+0x10)) 24850 (stop *(ebp+0x14) 1) 24851 # never gets here 24852 -24853 $check-mu-compute-offset-stmt:error-index-offset-atom-type: +24853 $check-mu-compute-offset-stmt:error-too-few-inouts: 24854 (write-buffered *(ebp+0x10) "fn ") 24855 8b/-> *(ebp+0xc) 0/r32/eax 24856 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24857 (write-buffered *(ebp+0x10) %eax) -24858 (write-buffered *(ebp+0x10) ": stmt compute-offset: offset '") -24859 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24860 (write-buffered *(ebp+0x10) %eax) -24861 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n") -24862 (flush *(ebp+0x10)) -24863 (stop *(ebp+0x14) 1) -24864 # never gets here -24865 -24866 $check-mu-compute-offset-stmt:error-index-on-stack: -24867 (write-buffered *(ebp+0x10) "fn ") -24868 8b/-> *(ebp+0xc) 0/r32/eax -24869 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24858 (write-buffered *(ebp+0x10) ": stmt compute-offset: too few inouts (2 required)\n") +24859 (flush *(ebp+0x10)) +24860 (stop *(ebp+0x14) 1) +24861 # never gets here +24862 +24863 $check-mu-compute-offset-stmt:error-invalid-index-type: +24864 (write-buffered *(ebp+0x10) "fn ") +24865 8b/-> *(ebp+0xc) 0/r32/eax +24866 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24867 (write-buffered *(ebp+0x10) %eax) +24868 (write-buffered *(ebp+0x10) ": stmt compute-offset: second argument '") +24869 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24870 (write-buffered *(ebp+0x10) %eax) -24871 (write-buffered *(ebp+0x10) ": stmt compute-offset: second argument '") -24872 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -24873 (write-buffered *(ebp+0x10) %eax) -24874 (write-buffered *(ebp+0x10) "' must be in a register\n") -24875 (flush *(ebp+0x10)) -24876 (stop *(ebp+0x14) 1) -24877 # never gets here -24878 -24879 $check-mu-compute-offset-stmt:error-too-many-inouts: -24880 (write-buffered *(ebp+0x10) "fn ") -24881 8b/-> *(ebp+0xc) 0/r32/eax -24882 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24871 (write-buffered *(ebp+0x10) "' must be an int\n") +24872 (flush *(ebp+0x10)) +24873 (stop *(ebp+0x14) 1) +24874 # never gets here +24875 +24876 $check-mu-compute-offset-stmt:error-index-offset-atom-type: +24877 (write-buffered *(ebp+0x10) "fn ") +24878 8b/-> *(ebp+0xc) 0/r32/eax +24879 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24880 (write-buffered *(ebp+0x10) %eax) +24881 (write-buffered *(ebp+0x10) ": stmt compute-offset: offset '") +24882 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 24883 (write-buffered *(ebp+0x10) %eax) -24884 (write-buffered *(ebp+0x10) ": stmt compute-offset: too many inouts (2 required)\n") +24884 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n") 24885 (flush *(ebp+0x10)) 24886 (stop *(ebp+0x14) 1) 24887 # never gets here 24888 -24889 $check-mu-compute-offset-stmt:error-too-few-outputs: +24889 $check-mu-compute-offset-stmt:error-index-on-stack: 24890 (write-buffered *(ebp+0x10) "fn ") 24891 8b/-> *(ebp+0xc) 0/r32/eax 24892 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24893 (write-buffered *(ebp+0x10) %eax) -24894 (write-buffered *(ebp+0x10) ": stmt compute-offset: must have an output\n") -24895 (flush *(ebp+0x10)) -24896 (stop *(ebp+0x14) 1) -24897 # never gets here -24898 -24899 $check-mu-compute-offset-stmt:error-too-many-outputs: -24900 (write-buffered *(ebp+0x10) "fn ") -24901 8b/-> *(ebp+0xc) 0/r32/eax -24902 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24903 (write-buffered *(ebp+0x10) %eax) -24904 (write-buffered *(ebp+0x10) ": stmt compute-offset: too many outputs (1 required)\n") -24905 (flush *(ebp+0x10)) -24906 (stop *(ebp+0x14) 1) -24907 # never gets here -24908 -24909 $check-mu-compute-offset-stmt:error-output-not-in-register: -24910 (write-buffered *(ebp+0x10) "fn ") -24911 8b/-> *(ebp+0xc) 0/r32/eax -24912 (lookup *eax *(eax+4)) # Function-name Function-name => eax -24913 (write-buffered *(ebp+0x10) %eax) -24914 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '") -24915 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24894 (write-buffered *(ebp+0x10) ": stmt compute-offset: second argument '") +24895 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +24896 (write-buffered *(ebp+0x10) %eax) +24897 (write-buffered *(ebp+0x10) "' must be in a register\n") +24898 (flush *(ebp+0x10)) +24899 (stop *(ebp+0x14) 1) +24900 # never gets here +24901 +24902 $check-mu-compute-offset-stmt:error-too-many-inouts: +24903 (write-buffered *(ebp+0x10) "fn ") +24904 8b/-> *(ebp+0xc) 0/r32/eax +24905 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24906 (write-buffered *(ebp+0x10) %eax) +24907 (write-buffered *(ebp+0x10) ": stmt compute-offset: too many inouts (2 required)\n") +24908 (flush *(ebp+0x10)) +24909 (stop *(ebp+0x14) 1) +24910 # never gets here +24911 +24912 $check-mu-compute-offset-stmt:error-too-few-outputs: +24913 (write-buffered *(ebp+0x10) "fn ") +24914 8b/-> *(ebp+0xc) 0/r32/eax +24915 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24916 (write-buffered *(ebp+0x10) %eax) -24917 (write-buffered *(ebp+0x10) "' is not in a register\n") +24917 (write-buffered *(ebp+0x10) ": stmt compute-offset: must have an output\n") 24918 (flush *(ebp+0x10)) 24919 (stop *(ebp+0x14) 1) 24920 # never gets here 24921 -24922 $check-mu-compute-offset-stmt:error-output-type-not-offset: +24922 $check-mu-compute-offset-stmt:error-too-many-outputs: 24923 (write-buffered *(ebp+0x10) "fn ") 24924 8b/-> *(ebp+0xc) 0/r32/eax 24925 (lookup *eax *(eax+4)) # Function-name Function-name => eax 24926 (write-buffered *(ebp+0x10) %eax) -24927 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '") -24928 (lookup *edi *(edi+4)) # Var-name Var-name => eax -24929 (write-buffered *(ebp+0x10) %eax) -24930 (write-buffered *(ebp+0x10) "' must be an offset\n") -24931 (flush *(ebp+0x10)) -24932 (stop *(ebp+0x14) 1) -24933 # never gets here -24934 -24935 $check-mu-compute-offset-stmt:error-bad-output-type: -24936 (write-buffered *(ebp+0x10) "fn ") -24937 8b/-> *(ebp+0xc) 0/r32/eax -24938 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24927 (write-buffered *(ebp+0x10) ": stmt compute-offset: too many outputs (1 required)\n") +24928 (flush *(ebp+0x10)) +24929 (stop *(ebp+0x14) 1) +24930 # never gets here +24931 +24932 $check-mu-compute-offset-stmt:error-output-not-in-register: +24933 (write-buffered *(ebp+0x10) "fn ") +24934 8b/-> *(ebp+0xc) 0/r32/eax +24935 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24936 (write-buffered *(ebp+0x10) %eax) +24937 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '") +24938 (lookup *edi *(edi+4)) # Var-name Var-name => eax 24939 (write-buffered *(ebp+0x10) %eax) -24940 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '") -24941 (lookup *edi *(edi+4)) # Var-name Var-name => eax -24942 (write-buffered *(ebp+0x10) %eax) -24943 (write-buffered *(ebp+0x10) "' does not have the right type\n") -24944 (flush *(ebp+0x10)) -24945 (stop *(ebp+0x14) 1) -24946 # never gets here -24947 -24948 check-mu-copy-object-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -24949 # . prologue -24950 55/push-ebp -24951 89/<- %ebp 4/r32/esp -24952 # . save registers -24953 50/push-eax -24954 51/push-ecx -24955 53/push-ebx -24956 56/push-esi -24957 57/push-edi -24958 # esi = stmt -24959 8b/-> *(ebp+8) 6/r32/esi -24960 $check-mu-copy-object-stmt:check-for-output: -24961 # if stmt->outputs abort -24962 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -24963 3d/compare-eax-and 0/imm32 -24964 0f 85/jump-if-!= $check-mu-copy-object-stmt:error-too-many-outputs/disp32 -24965 $check-mu-copy-object-stmt:get-left: -24966 # var dest/edi: (addr stmt-var) = stmt->inouts -24967 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -24968 89/<- %edi 0/r32/eax -24969 # zero inouts -24970 3d/compare-eax-and 0/imm32 -24971 0f 84/jump-if-= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32 -24972 $check-mu-copy-object-stmt:get-src: -24973 # var src/esi: (addr stmt-var) = dest->next -24974 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -24975 89/<- %esi 0/r32/eax -24976 # 1 inout -24977 3d/compare-eax-and 0/imm32 -24978 0f 84/jump-if-= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32 -24979 # > 2 inouts -24980 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -24981 3d/compare-eax-and 0/imm32 -24982 0f 85/jump-if-!= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32 -24983 $check-mu-copy-object-stmt:types: -24984 # var src-type/ecx: (addr type-tree) = src->value->type -24985 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -24986 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -24987 89/<- %ecx 0/r32/eax -24988 # if (src->is-deref?) src-type = src-type->payload -24989 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref -24990 3d/compare-eax-and 0/imm32/false -24991 { -24992 74/jump-if-= break/disp8 -24993 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -24994 # if src-type->right is null, src-type = src-type->left -24995 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -24996 { -24997 75/jump-if-!= break/disp8 -24998 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -24999 } -25000 89/<- %ecx 0/r32/eax -25001 } -25002 # if src-type is not addr, abort -25003 (mu-addr-type? %ecx) # => eax -25004 3d/compare-eax-and 0/imm32/false -25005 0f 84/jump-if-= $check-mu-copy-object-stmt:error-invalid-types/disp32 -25006 # var dest-type/ebx: (addr type-tree) = dest->value->type -25007 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25008 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -25009 89/<- %ebx 0/r32/eax -25010 # if (dest->is-deref?) dest-type = dest-type->payload -25011 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref -25012 3d/compare-eax-and 0/imm32/false -25013 { -25014 74/jump-if-= break/disp8 -25015 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25016 # if dest-type->right is null, dest-type = dest-type->left -25017 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -25018 { -25019 75/jump-if-!= break/disp8 -25020 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25021 } -25022 89/<- %ebx 0/r32/eax -25023 } -25024 # if (dest-type != src-type) abort -25025 (type-equal? %ecx %ebx) # => eax -25026 3d/compare-eax-and 0/imm32 -25027 0f 84/jump-if-= $check-mu-copy-object-stmt:error-invalid-types/disp32 -25028 $check-mu-copy-object-stmt:end: -25029 # . restore registers -25030 5f/pop-to-edi -25031 5e/pop-to-esi -25032 5b/pop-to-ebx -25033 59/pop-to-ecx -25034 58/pop-to-eax -25035 # . epilogue -25036 89/<- %esp 5/r32/ebp -25037 5d/pop-to-ebp -25038 c3/return -25039 -25040 $check-mu-copy-object-stmt:error-incorrect-inouts: -25041 (write-buffered *(ebp+0x10) "fn ") -25042 8b/-> *(ebp+0xc) 0/r32/eax -25043 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25044 (write-buffered *(ebp+0x10) %eax) -25045 (write-buffered *(ebp+0x10) ": stmt 'copy-object' must have two inouts\n") -25046 (flush *(ebp+0x10)) -25047 (stop *(ebp+0x14) 1) -25048 # never gets here -25049 -25050 $check-mu-copy-object-stmt:error-too-many-outputs: -25051 (write-buffered *(ebp+0x10) "fn ") -25052 8b/-> *(ebp+0xc) 0/r32/eax -25053 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25054 (write-buffered *(ebp+0x10) %eax) -25055 (write-buffered *(ebp+0x10) ": stmt 'copy-object' must not have any outputs\n") -25056 (flush *(ebp+0x10)) -25057 (stop *(ebp+0x14) 1) -25058 # never gets here -25059 -25060 $check-mu-copy-object-stmt:error-invalid-types: -25061 (write-buffered *(ebp+0x10) "fn ") -25062 8b/-> *(ebp+0xc) 0/r32/eax -25063 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25064 (write-buffered *(ebp+0x10) %eax) -25065 (write-buffered *(ebp+0x10) ": stmt copy-object: two inouts with identical addr types expected\n") -25066 (flush *(ebp+0x10)) -25067 (stop *(ebp+0x14) 1) -25068 # never gets here -25069 -25070 check-mu-clear-object-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -25071 # . prologue -25072 55/push-ebp -25073 89/<- %ebp 4/r32/esp -25074 # . save registers -25075 50/push-eax -25076 51/push-ecx -25077 53/push-ebx -25078 56/push-esi -25079 57/push-edi -25080 # esi = stmt -25081 8b/-> *(ebp+8) 6/r32/esi -25082 $check-mu-clear-object-stmt:check-for-output: -25083 # if stmt->outputs abort -25084 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -25085 3d/compare-eax-and 0/imm32 -25086 0f 85/jump-if-!= $check-mu-clear-object-stmt:error-too-many-outputs/disp32 -25087 $check-mu-clear-object-stmt:get-left: -25088 # var dest/edi: (addr stmt-var) = stmt->inouts -25089 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25090 89/<- %edi 0/r32/eax -25091 # zero inouts -25092 3d/compare-eax-and 0/imm32 -25093 0f 84/jump-if-= $check-mu-clear-object-stmt:error-incorrect-inouts/disp32 -25094 $check-mu-clear-object-stmt:get-src: -25095 # > 1 inout -25096 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -25097 3d/compare-eax-and 0/imm32 -25098 0f 85/jump-if-!= $check-mu-clear-object-stmt:error-incorrect-inouts/disp32 -25099 $check-mu-clear-object-stmt:types: -25100 # var src-type/ecx: (addr type-tree) = src->value->type -25101 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25102 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -25103 89/<- %ecx 0/r32/eax -25104 # if (src->is-deref?) src-type = src-type->payload -25105 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref -25106 3d/compare-eax-and 0/imm32/false -25107 { -25108 74/jump-if-= break/disp8 -25109 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -25110 # if src-type->right is null, src-type = src-type->left -25111 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -25112 { -25113 75/jump-if-!= break/disp8 -25114 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25115 } -25116 89/<- %ecx 0/r32/eax -25117 } -25118 # if src-type is not addr, abort -25119 (mu-addr-type? %ecx) # => eax -25120 3d/compare-eax-and 0/imm32/false -25121 0f 84/jump-if-= $check-mu-clear-object-stmt:error-invalid-type/disp32 -25122 $check-mu-clear-object-stmt:end: -25123 # . restore registers -25124 5f/pop-to-edi -25125 5e/pop-to-esi -25126 5b/pop-to-ebx -25127 59/pop-to-ecx -25128 58/pop-to-eax -25129 # . epilogue -25130 89/<- %esp 5/r32/ebp -25131 5d/pop-to-ebp -25132 c3/return -25133 -25134 $check-mu-clear-object-stmt:error-incorrect-inouts: -25135 (write-buffered *(ebp+0x10) "fn ") -25136 8b/-> *(ebp+0xc) 0/r32/eax -25137 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25138 (write-buffered *(ebp+0x10) %eax) -25139 (write-buffered *(ebp+0x10) ": stmt 'clear-object' must have a single inout\n") -25140 (flush *(ebp+0x10)) -25141 (stop *(ebp+0x14) 1) -25142 # never gets here -25143 -25144 $check-mu-clear-object-stmt:error-too-many-outputs: -25145 (write-buffered *(ebp+0x10) "fn ") -25146 8b/-> *(ebp+0xc) 0/r32/eax -25147 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25148 (write-buffered *(ebp+0x10) %eax) -25149 (write-buffered *(ebp+0x10) ": stmt 'clear-object' must not have any outputs\n") -25150 (flush *(ebp+0x10)) -25151 (stop *(ebp+0x14) 1) -25152 # never gets here -25153 -25154 $check-mu-clear-object-stmt:error-invalid-type: -25155 (write-buffered *(ebp+0x10) "fn ") -25156 8b/-> *(ebp+0xc) 0/r32/eax -25157 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25158 (write-buffered *(ebp+0x10) %eax) -25159 (write-buffered *(ebp+0x10) ": stmt clear-object: inout must have an addr type\n") -25160 (flush *(ebp+0x10)) -25161 (stop *(ebp+0x14) 1) -25162 # never gets here -25163 -25164 check-mu-allocate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -25165 # . prologue -25166 55/push-ebp -25167 89/<- %ebp 4/r32/esp -25168 # . save registers -25169 50/push-eax -25170 53/push-ebx -25171 56/push-esi -25172 57/push-edi -25173 # esi = stmt -25174 8b/-> *(ebp+8) 6/r32/esi -25175 $check-mu-allocate-stmt:check-for-output: -25176 # if stmt->outputs abort -25177 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -25178 3d/compare-eax-and 0/imm32 -25179 0f 85/jump-if-!= $check-mu-allocate-stmt:error-too-many-outputs/disp32 -25180 $check-mu-allocate-stmt:get-target: -25181 # var target/edi: (addr stmt-var) = stmt->inouts -25182 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25183 89/<- %edi 0/r32/eax -25184 # zero inouts -25185 3d/compare-eax-and 0/imm32 -25186 0f 84/jump-if-= $check-mu-allocate-stmt:error-incorrect-inouts/disp32 -25187 # > 1 inouts -25188 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -25189 3d/compare-eax-and 0/imm32 -25190 0f 85/jump-if-!= $check-mu-allocate-stmt:error-incorrect-inouts/disp32 -25191 $check-mu-allocate-stmt:check-type: -25192 # var target-type/ebx: (addr type-tree) = target->value->type -25193 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25194 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -25195 89/<- %ebx 0/r32/eax -25196 # if (target->is-deref?) target-type = target-type->payload -25197 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref -25198 3d/compare-eax-and 0/imm32/false -25199 { -25200 74/jump-if-= break/disp8 -25201 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25202 # if target-type->right is null, target-type = target-type->left -25203 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -25204 { -25205 75/jump-if-!= break/disp8 -25206 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25207 } -25208 89/<- %ebx 0/r32/eax -25209 } -25210 # if target-type is not addr, abort -25211 (mu-addr-type? %ebx) # => eax -25212 3d/compare-eax-and 0/imm32/false -25213 0f 84/jump-if-= $check-mu-allocate-stmt:error-invalid-type/disp32 -25214 # if target-type->right is an atom, abort -25215 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25216 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -25217 0f 85/jump-if-!= $check-mu-allocate-stmt:error-invalid-type/disp32 -25218 # if target-type->right->left is not handle, abort -25219 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25220 (simple-mu-type? %eax 4) # handle => eax +24940 (write-buffered *(ebp+0x10) "' is not in a register\n") +24941 (flush *(ebp+0x10)) +24942 (stop *(ebp+0x14) 1) +24943 # never gets here +24944 +24945 $check-mu-compute-offset-stmt:error-output-type-not-offset: +24946 (write-buffered *(ebp+0x10) "fn ") +24947 8b/-> *(ebp+0xc) 0/r32/eax +24948 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24949 (write-buffered *(ebp+0x10) %eax) +24950 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '") +24951 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24952 (write-buffered *(ebp+0x10) %eax) +24953 (write-buffered *(ebp+0x10) "' must be an offset\n") +24954 (flush *(ebp+0x10)) +24955 (stop *(ebp+0x14) 1) +24956 # never gets here +24957 +24958 $check-mu-compute-offset-stmt:error-bad-output-type: +24959 (write-buffered *(ebp+0x10) "fn ") +24960 8b/-> *(ebp+0xc) 0/r32/eax +24961 (lookup *eax *(eax+4)) # Function-name Function-name => eax +24962 (write-buffered *(ebp+0x10) %eax) +24963 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '") +24964 (lookup *edi *(edi+4)) # Var-name Var-name => eax +24965 (write-buffered *(ebp+0x10) %eax) +24966 (write-buffered *(ebp+0x10) "' does not have the right type\n") +24967 (flush *(ebp+0x10)) +24968 (stop *(ebp+0x14) 1) +24969 # never gets here +24970 +24971 check-mu-copy-object-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +24972 # . prologue +24973 55/push-ebp +24974 89/<- %ebp 4/r32/esp +24975 # . save registers +24976 50/push-eax +24977 51/push-ecx +24978 53/push-ebx +24979 56/push-esi +24980 57/push-edi +24981 # esi = stmt +24982 8b/-> *(ebp+8) 6/r32/esi +24983 $check-mu-copy-object-stmt:check-for-output: +24984 # if stmt->outputs abort +24985 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +24986 3d/compare-eax-and 0/imm32 +24987 0f 85/jump-if-!= $check-mu-copy-object-stmt:error-too-many-outputs/disp32 +24988 $check-mu-copy-object-stmt:get-left: +24989 # var dest/edi: (addr stmt-var) = stmt->inouts +24990 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +24991 89/<- %edi 0/r32/eax +24992 # zero inouts +24993 3d/compare-eax-and 0/imm32 +24994 0f 84/jump-if-= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32 +24995 $check-mu-copy-object-stmt:get-src: +24996 # var src/esi: (addr stmt-var) = dest->next +24997 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +24998 89/<- %esi 0/r32/eax +24999 # 1 inout +25000 3d/compare-eax-and 0/imm32 +25001 0f 84/jump-if-= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32 +25002 # > 2 inouts +25003 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +25004 3d/compare-eax-and 0/imm32 +25005 0f 85/jump-if-!= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32 +25006 $check-mu-copy-object-stmt:types: +25007 # var src-type/ecx: (addr type-tree) = src->value->type +25008 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +25009 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25010 89/<- %ecx 0/r32/eax +25011 # if (src->is-deref?) src-type = src-type->payload +25012 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref +25013 3d/compare-eax-and 0/imm32/false +25014 { +25015 74/jump-if-= break/disp8 +25016 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +25017 # if src-type->right is null, src-type = src-type->left +25018 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +25019 { +25020 75/jump-if-!= break/disp8 +25021 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25022 } +25023 89/<- %ecx 0/r32/eax +25024 } +25025 # if src-type is not addr, abort +25026 (mu-addr-type? %ecx) # => eax +25027 3d/compare-eax-and 0/imm32/false +25028 0f 84/jump-if-= $check-mu-copy-object-stmt:error-invalid-types/disp32 +25029 # var dest-type/ebx: (addr type-tree) = dest->value->type +25030 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25031 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25032 89/<- %ebx 0/r32/eax +25033 # if (dest->is-deref?) dest-type = dest-type->payload +25034 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref +25035 3d/compare-eax-and 0/imm32/false +25036 { +25037 74/jump-if-= break/disp8 +25038 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25039 # if dest-type->right is null, dest-type = dest-type->left +25040 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +25041 { +25042 75/jump-if-!= break/disp8 +25043 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25044 } +25045 89/<- %ebx 0/r32/eax +25046 } +25047 # if (dest-type != src-type) abort +25048 (type-equal? %ecx %ebx) # => eax +25049 3d/compare-eax-and 0/imm32 +25050 0f 84/jump-if-= $check-mu-copy-object-stmt:error-invalid-types/disp32 +25051 $check-mu-copy-object-stmt:end: +25052 # . restore registers +25053 5f/pop-to-edi +25054 5e/pop-to-esi +25055 5b/pop-to-ebx +25056 59/pop-to-ecx +25057 58/pop-to-eax +25058 # . epilogue +25059 89/<- %esp 5/r32/ebp +25060 5d/pop-to-ebp +25061 c3/return +25062 +25063 $check-mu-copy-object-stmt:error-incorrect-inouts: +25064 (write-buffered *(ebp+0x10) "fn ") +25065 8b/-> *(ebp+0xc) 0/r32/eax +25066 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25067 (write-buffered *(ebp+0x10) %eax) +25068 (write-buffered *(ebp+0x10) ": stmt 'copy-object' must have two inouts\n") +25069 (flush *(ebp+0x10)) +25070 (stop *(ebp+0x14) 1) +25071 # never gets here +25072 +25073 $check-mu-copy-object-stmt:error-too-many-outputs: +25074 (write-buffered *(ebp+0x10) "fn ") +25075 8b/-> *(ebp+0xc) 0/r32/eax +25076 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25077 (write-buffered *(ebp+0x10) %eax) +25078 (write-buffered *(ebp+0x10) ": stmt 'copy-object' must not have any outputs\n") +25079 (flush *(ebp+0x10)) +25080 (stop *(ebp+0x14) 1) +25081 # never gets here +25082 +25083 $check-mu-copy-object-stmt:error-invalid-types: +25084 (write-buffered *(ebp+0x10) "fn ") +25085 8b/-> *(ebp+0xc) 0/r32/eax +25086 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25087 (write-buffered *(ebp+0x10) %eax) +25088 (write-buffered *(ebp+0x10) ": stmt copy-object: two inouts with identical addr types expected\n") +25089 (flush *(ebp+0x10)) +25090 (stop *(ebp+0x14) 1) +25091 # never gets here +25092 +25093 check-mu-clear-object-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +25094 # . prologue +25095 55/push-ebp +25096 89/<- %ebp 4/r32/esp +25097 # . save registers +25098 50/push-eax +25099 51/push-ecx +25100 53/push-ebx +25101 56/push-esi +25102 57/push-edi +25103 # esi = stmt +25104 8b/-> *(ebp+8) 6/r32/esi +25105 $check-mu-clear-object-stmt:check-for-output: +25106 # if stmt->outputs abort +25107 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +25108 3d/compare-eax-and 0/imm32 +25109 0f 85/jump-if-!= $check-mu-clear-object-stmt:error-too-many-outputs/disp32 +25110 $check-mu-clear-object-stmt:get-left: +25111 # var dest/edi: (addr stmt-var) = stmt->inouts +25112 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25113 89/<- %edi 0/r32/eax +25114 # zero inouts +25115 3d/compare-eax-and 0/imm32 +25116 0f 84/jump-if-= $check-mu-clear-object-stmt:error-incorrect-inouts/disp32 +25117 $check-mu-clear-object-stmt:get-src: +25118 # > 1 inout +25119 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +25120 3d/compare-eax-and 0/imm32 +25121 0f 85/jump-if-!= $check-mu-clear-object-stmt:error-incorrect-inouts/disp32 +25122 $check-mu-clear-object-stmt:types: +25123 # var src-type/ecx: (addr type-tree) = src->value->type +25124 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25125 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25126 89/<- %ecx 0/r32/eax +25127 # if (src->is-deref?) src-type = src-type->payload +25128 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref +25129 3d/compare-eax-and 0/imm32/false +25130 { +25131 74/jump-if-= break/disp8 +25132 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +25133 # if src-type->right is null, src-type = src-type->left +25134 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +25135 { +25136 75/jump-if-!= break/disp8 +25137 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25138 } +25139 89/<- %ecx 0/r32/eax +25140 } +25141 # if src-type is not addr, abort +25142 (mu-addr-type? %ecx) # => eax +25143 3d/compare-eax-and 0/imm32/false +25144 0f 84/jump-if-= $check-mu-clear-object-stmt:error-invalid-type/disp32 +25145 $check-mu-clear-object-stmt:end: +25146 # . restore registers +25147 5f/pop-to-edi +25148 5e/pop-to-esi +25149 5b/pop-to-ebx +25150 59/pop-to-ecx +25151 58/pop-to-eax +25152 # . epilogue +25153 89/<- %esp 5/r32/ebp +25154 5d/pop-to-ebp +25155 c3/return +25156 +25157 $check-mu-clear-object-stmt:error-incorrect-inouts: +25158 (write-buffered *(ebp+0x10) "fn ") +25159 8b/-> *(ebp+0xc) 0/r32/eax +25160 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25161 (write-buffered *(ebp+0x10) %eax) +25162 (write-buffered *(ebp+0x10) ": stmt 'clear-object' must have a single inout\n") +25163 (flush *(ebp+0x10)) +25164 (stop *(ebp+0x14) 1) +25165 # never gets here +25166 +25167 $check-mu-clear-object-stmt:error-too-many-outputs: +25168 (write-buffered *(ebp+0x10) "fn ") +25169 8b/-> *(ebp+0xc) 0/r32/eax +25170 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25171 (write-buffered *(ebp+0x10) %eax) +25172 (write-buffered *(ebp+0x10) ": stmt 'clear-object' must not have any outputs\n") +25173 (flush *(ebp+0x10)) +25174 (stop *(ebp+0x14) 1) +25175 # never gets here +25176 +25177 $check-mu-clear-object-stmt:error-invalid-type: +25178 (write-buffered *(ebp+0x10) "fn ") +25179 8b/-> *(ebp+0xc) 0/r32/eax +25180 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25181 (write-buffered *(ebp+0x10) %eax) +25182 (write-buffered *(ebp+0x10) ": stmt clear-object: inout must have an addr type\n") +25183 (flush *(ebp+0x10)) +25184 (stop *(ebp+0x14) 1) +25185 # never gets here +25186 +25187 check-mu-allocate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +25188 # . prologue +25189 55/push-ebp +25190 89/<- %ebp 4/r32/esp +25191 # . save registers +25192 50/push-eax +25193 53/push-ebx +25194 56/push-esi +25195 57/push-edi +25196 # esi = stmt +25197 8b/-> *(ebp+8) 6/r32/esi +25198 $check-mu-allocate-stmt:check-for-output: +25199 # if stmt->outputs abort +25200 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +25201 3d/compare-eax-and 0/imm32 +25202 0f 85/jump-if-!= $check-mu-allocate-stmt:error-too-many-outputs/disp32 +25203 $check-mu-allocate-stmt:get-target: +25204 # var target/edi: (addr stmt-var) = stmt->inouts +25205 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25206 89/<- %edi 0/r32/eax +25207 # zero inouts +25208 3d/compare-eax-and 0/imm32 +25209 0f 84/jump-if-= $check-mu-allocate-stmt:error-incorrect-inouts/disp32 +25210 # > 1 inouts +25211 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +25212 3d/compare-eax-and 0/imm32 +25213 0f 85/jump-if-!= $check-mu-allocate-stmt:error-incorrect-inouts/disp32 +25214 $check-mu-allocate-stmt:check-type: +25215 # var target-type/ebx: (addr type-tree) = target->value->type +25216 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25217 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25218 89/<- %ebx 0/r32/eax +25219 # if (target->is-deref?) target-type = target-type->payload +25220 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref 25221 3d/compare-eax-and 0/imm32/false -25222 0f 84/jump-if-= $check-mu-allocate-stmt:error-invalid-type/disp32 -25223 $check-mu-allocate-stmt:end: -25224 # . restore registers -25225 5f/pop-to-edi -25226 5e/pop-to-esi -25227 5b/pop-to-ebx -25228 58/pop-to-eax -25229 # . epilogue -25230 89/<- %esp 5/r32/ebp -25231 5d/pop-to-ebp -25232 c3/return -25233 -25234 $check-mu-allocate-stmt:error-incorrect-inouts: -25235 (write-buffered *(ebp+0x10) "fn ") -25236 8b/-> *(ebp+0xc) 0/r32/eax -25237 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25238 (write-buffered *(ebp+0x10) %eax) -25239 (write-buffered *(ebp+0x10) ": stmt 'allocate' must have a single inout\n") -25240 (flush *(ebp+0x10)) -25241 (stop *(ebp+0x14) 1) -25242 # never gets here -25243 -25244 $check-mu-allocate-stmt:error-too-many-outputs: -25245 (write-buffered *(ebp+0x10) "fn ") -25246 8b/-> *(ebp+0xc) 0/r32/eax -25247 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25248 (write-buffered *(ebp+0x10) %eax) -25249 (write-buffered *(ebp+0x10) ": stmt 'allocate' must not have any outputs\n") -25250 (flush *(ebp+0x10)) -25251 (stop *(ebp+0x14) 1) -25252 # never gets here -25253 -25254 $check-mu-allocate-stmt:error-invalid-type: -25255 (write-buffered *(ebp+0x10) "fn ") -25256 8b/-> *(ebp+0xc) 0/r32/eax -25257 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25258 (write-buffered *(ebp+0x10) %eax) -25259 (write-buffered *(ebp+0x10) ": stmt allocate: inout '") -25260 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25261 (lookup *eax *(eax+4)) # Var-name Var-name => eax -25262 (write-buffered *(ebp+0x10) %eax) -25263 (write-buffered *(ebp+0x10) "' must have type (addr handle ...)\n") -25264 (flush *(ebp+0x10)) -25265 (stop *(ebp+0x14) 1) -25266 # never gets here -25267 -25268 check-mu-populate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -25269 # . prologue -25270 55/push-ebp -25271 89/<- %ebp 4/r32/esp -25272 # . save registers -25273 50/push-eax -25274 53/push-ebx -25275 56/push-esi -25276 57/push-edi -25277 # esi = stmt -25278 8b/-> *(ebp+8) 6/r32/esi -25279 $check-mu-populate-stmt:check-for-output: -25280 # if stmt->outputs abort -25281 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -25282 3d/compare-eax-and 0/imm32 -25283 0f 85/jump-if-!= $check-mu-populate-stmt:error-too-many-outputs/disp32 -25284 $check-mu-populate-stmt:get-target: -25285 # var target/edi: (addr stmt-var) = stmt->inouts -25286 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25287 89/<- %edi 0/r32/eax -25288 # zero inouts -25289 3d/compare-eax-and 0/imm32 -25290 0f 84/jump-if-= $check-mu-populate-stmt:error-incorrect-inouts/disp32 -25291 $check-mu-populate-stmt:get-length: -25292 # var length/esi: (addr stmt-var) = dest->next -25293 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -25294 89/<- %esi 0/r32/eax -25295 # 1 inout -25296 3d/compare-eax-and 0/imm32 -25297 0f 84/jump-if-= $check-mu-populate-stmt:error-incorrect-inouts/disp32 -25298 # > 2 inouts -25299 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -25300 3d/compare-eax-and 0/imm32 -25301 0f 85/jump-if-!= $check-mu-populate-stmt:error-incorrect-inouts/disp32 -25302 $check-mu-populate-stmt:check-target-type: -25303 # var target-type/ebx: (addr type-tree) = target->value->type -25304 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25305 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -25306 89/<- %ebx 0/r32/eax -25307 $check-mu-populate-stmt:check-target-type-deref: -25308 # if (target->is-deref?) target-type = target-type->payload -25309 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref -25310 3d/compare-eax-and 0/imm32/false -25311 { -25312 74/jump-if-= break/disp8 -25313 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25314 # if target-type->right is null, target-type = target-type->left -25315 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -25316 { -25317 75/jump-if-!= break/disp8 -25318 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25319 } -25320 89/<- %ebx 0/r32/eax -25321 } -25322 $check-mu-populate-stmt:check-target-type-addr: -25323 # if target-type is not addr, abort -25324 (mu-addr-type? %ebx) # => eax -25325 3d/compare-eax-and 0/imm32/false -25326 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32 -25327 # if target-type->right is an atom, abort -25328 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25222 { +25223 74/jump-if-= break/disp8 +25224 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25225 # if target-type->right is null, target-type = target-type->left +25226 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +25227 { +25228 75/jump-if-!= break/disp8 +25229 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25230 } +25231 89/<- %ebx 0/r32/eax +25232 } +25233 # if target-type is not addr, abort +25234 (mu-addr-type? %ebx) # => eax +25235 3d/compare-eax-and 0/imm32/false +25236 0f 84/jump-if-= $check-mu-allocate-stmt:error-invalid-type/disp32 +25237 # if target-type->right is an atom, abort +25238 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25239 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +25240 0f 85/jump-if-!= $check-mu-allocate-stmt:error-invalid-type/disp32 +25241 # if target-type->right->left is not handle, abort +25242 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25243 (simple-mu-type? %eax 4) # handle => eax +25244 3d/compare-eax-and 0/imm32/false +25245 0f 84/jump-if-= $check-mu-allocate-stmt:error-invalid-type/disp32 +25246 $check-mu-allocate-stmt:end: +25247 # . restore registers +25248 5f/pop-to-edi +25249 5e/pop-to-esi +25250 5b/pop-to-ebx +25251 58/pop-to-eax +25252 # . epilogue +25253 89/<- %esp 5/r32/ebp +25254 5d/pop-to-ebp +25255 c3/return +25256 +25257 $check-mu-allocate-stmt:error-incorrect-inouts: +25258 (write-buffered *(ebp+0x10) "fn ") +25259 8b/-> *(ebp+0xc) 0/r32/eax +25260 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25261 (write-buffered *(ebp+0x10) %eax) +25262 (write-buffered *(ebp+0x10) ": stmt 'allocate' must have a single inout\n") +25263 (flush *(ebp+0x10)) +25264 (stop *(ebp+0x14) 1) +25265 # never gets here +25266 +25267 $check-mu-allocate-stmt:error-too-many-outputs: +25268 (write-buffered *(ebp+0x10) "fn ") +25269 8b/-> *(ebp+0xc) 0/r32/eax +25270 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25271 (write-buffered *(ebp+0x10) %eax) +25272 (write-buffered *(ebp+0x10) ": stmt 'allocate' must not have any outputs\n") +25273 (flush *(ebp+0x10)) +25274 (stop *(ebp+0x14) 1) +25275 # never gets here +25276 +25277 $check-mu-allocate-stmt:error-invalid-type: +25278 (write-buffered *(ebp+0x10) "fn ") +25279 8b/-> *(ebp+0xc) 0/r32/eax +25280 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25281 (write-buffered *(ebp+0x10) %eax) +25282 (write-buffered *(ebp+0x10) ": stmt allocate: inout '") +25283 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25284 (lookup *eax *(eax+4)) # Var-name Var-name => eax +25285 (write-buffered *(ebp+0x10) %eax) +25286 (write-buffered *(ebp+0x10) "' must have type (addr handle ...)\n") +25287 (flush *(ebp+0x10)) +25288 (stop *(ebp+0x14) 1) +25289 # never gets here +25290 +25291 check-mu-populate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +25292 # . prologue +25293 55/push-ebp +25294 89/<- %ebp 4/r32/esp +25295 # . save registers +25296 50/push-eax +25297 53/push-ebx +25298 56/push-esi +25299 57/push-edi +25300 # esi = stmt +25301 8b/-> *(ebp+8) 6/r32/esi +25302 $check-mu-populate-stmt:check-for-output: +25303 # if stmt->outputs abort +25304 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +25305 3d/compare-eax-and 0/imm32 +25306 0f 85/jump-if-!= $check-mu-populate-stmt:error-too-many-outputs/disp32 +25307 $check-mu-populate-stmt:get-target: +25308 # var target/edi: (addr stmt-var) = stmt->inouts +25309 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25310 89/<- %edi 0/r32/eax +25311 # zero inouts +25312 3d/compare-eax-and 0/imm32 +25313 0f 84/jump-if-= $check-mu-populate-stmt:error-incorrect-inouts/disp32 +25314 $check-mu-populate-stmt:get-length: +25315 # var length/esi: (addr stmt-var) = dest->next +25316 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +25317 89/<- %esi 0/r32/eax +25318 # 1 inout +25319 3d/compare-eax-and 0/imm32 +25320 0f 84/jump-if-= $check-mu-populate-stmt:error-incorrect-inouts/disp32 +25321 # > 2 inouts +25322 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +25323 3d/compare-eax-and 0/imm32 +25324 0f 85/jump-if-!= $check-mu-populate-stmt:error-incorrect-inouts/disp32 +25325 $check-mu-populate-stmt:check-target-type: +25326 # var target-type/ebx: (addr type-tree) = target->value->type +25327 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25328 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax 25329 89/<- %ebx 0/r32/eax -25330 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -25331 0f 85/jump-if-!= $check-mu-populate-stmt:error-invalid-target-type/disp32 -25332 $check-mu-populate-stmt:check-target-type-handle: -25333 # if target-type->right->left is not handle, abort -25334 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -25335 (simple-mu-type? %eax 4) # handle => eax -25336 3d/compare-eax-and 0/imm32/false -25337 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32 -25338 # if target-type->right->right is an atom, abort -25339 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25340 89/<- %ebx 0/r32/eax -25341 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -25342 0f 85/jump-if-!= $check-mu-populate-stmt:error-invalid-target-type/disp32 -25343 $check-mu-populate-stmt:check-target-type-array: -25344 # if target-type->right->right->left is not array, abort -25345 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -25346 (simple-mu-type? %eax 3) # array => eax -25347 3d/compare-eax-and 0/imm32/false -25348 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32 -25349 $check-mu-populate-stmt:check-length-type: -25350 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -25351 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25330 $check-mu-populate-stmt:check-target-type-deref: +25331 # if (target->is-deref?) target-type = target-type->payload +25332 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref +25333 3d/compare-eax-and 0/imm32/false +25334 { +25335 74/jump-if-= break/disp8 +25336 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25337 # if target-type->right is null, target-type = target-type->left +25338 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +25339 { +25340 75/jump-if-!= break/disp8 +25341 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25342 } +25343 89/<- %ebx 0/r32/eax +25344 } +25345 $check-mu-populate-stmt:check-target-type-addr: +25346 # if target-type is not addr, abort +25347 (mu-addr-type? %ebx) # => eax +25348 3d/compare-eax-and 0/imm32/false +25349 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32 +25350 # if target-type->right is an atom, abort +25351 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax 25352 89/<- %ebx 0/r32/eax -25353 (simple-mu-type? %ebx 0) # literal => eax -25354 3d/compare-eax-and 0/imm32/false -25355 75/jump-if-!= $check-mu-populate-stmt:end/disp8 -25356 (simple-mu-type? %ebx 1) # int => eax -25357 3d/compare-eax-and 0/imm32/false -25358 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-length-type/disp32 -25359 $check-mu-populate-stmt:end: -25360 # . restore registers -25361 5f/pop-to-edi -25362 5e/pop-to-esi -25363 5b/pop-to-ebx -25364 58/pop-to-eax -25365 # . epilogue -25366 89/<- %esp 5/r32/ebp -25367 5d/pop-to-ebp -25368 c3/return -25369 -25370 $check-mu-populate-stmt:error-incorrect-inouts: -25371 (write-buffered *(ebp+0x10) "fn ") -25372 8b/-> *(ebp+0xc) 0/r32/eax -25373 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25374 (write-buffered *(ebp+0x10) %eax) -25375 (write-buffered *(ebp+0x10) ": stmt 'populate' must have two inouts\n") -25376 (flush *(ebp+0x10)) -25377 (stop *(ebp+0x14) 1) -25378 # never gets here -25379 -25380 $check-mu-populate-stmt:error-too-many-outputs: -25381 (write-buffered *(ebp+0x10) "fn ") -25382 8b/-> *(ebp+0xc) 0/r32/eax -25383 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25384 (write-buffered *(ebp+0x10) %eax) -25385 (write-buffered *(ebp+0x10) ": stmt 'populate' must not have any outputs\n") -25386 (flush *(ebp+0x10)) -25387 (stop *(ebp+0x14) 1) -25388 # never gets here -25389 -25390 $check-mu-populate-stmt:error-invalid-target-type: -25391 (write-buffered *(ebp+0x10) "fn ") -25392 8b/-> *(ebp+0xc) 0/r32/eax -25393 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25394 (write-buffered *(ebp+0x10) %eax) -25395 (write-buffered *(ebp+0x10) ": stmt populate: first inout '") -25396 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25397 (lookup *eax *(eax+4)) # Var-name Var-name => eax -25398 (write-buffered *(ebp+0x10) %eax) -25399 (write-buffered *(ebp+0x10) "' must have type (addr handle array ...)\n") -25400 (flush *(ebp+0x10)) -25401 (stop *(ebp+0x14) 1) -25402 # never gets here -25403 -25404 $check-mu-populate-stmt:error-invalid-length-type: -25405 (write-buffered *(ebp+0x10) "fn ") -25406 8b/-> *(ebp+0xc) 0/r32/eax -25407 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25408 (write-buffered *(ebp+0x10) %eax) -25409 (write-buffered *(ebp+0x10) ": stmt populate: second inout '") -25410 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -25411 (lookup *eax *(eax+4)) # Var-name Var-name => eax -25412 (write-buffered *(ebp+0x10) %eax) -25413 (write-buffered *(ebp+0x10) "' must be an int\n") -25414 (flush *(ebp+0x10)) -25415 (stop *(ebp+0x14) 1) -25416 # never gets here -25417 -25418 check-mu-populate-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -25419 # . prologue -25420 55/push-ebp -25421 89/<- %ebp 4/r32/esp -25422 # . save registers -25423 50/push-eax -25424 53/push-ebx -25425 56/push-esi -25426 57/push-edi -25427 # esi = stmt -25428 8b/-> *(ebp+8) 6/r32/esi -25429 $check-mu-populate-stream-stmt:check-for-output: -25430 # if stmt->outputs abort -25431 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -25432 3d/compare-eax-and 0/imm32 -25433 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-too-many-outputs/disp32 -25434 $check-mu-populate-stream-stmt:get-target: -25435 # var target/edi: (addr stmt-var) = stmt->inouts -25436 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25437 89/<- %edi 0/r32/eax -25438 # zero inouts -25439 3d/compare-eax-and 0/imm32 -25440 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32 -25441 $check-mu-populate-stream-stmt:get-length: -25442 # var length/esi: (addr stmt-var) = dest->next -25443 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -25444 89/<- %esi 0/r32/eax -25445 # 1 inout -25446 3d/compare-eax-and 0/imm32 -25447 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32 -25448 # > 2 inouts -25449 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -25450 3d/compare-eax-and 0/imm32 -25451 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32 -25452 $check-mu-populate-stream-stmt:check-target-type: -25453 # var target-type/ebx: (addr type-tree) = target->value->type -25454 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25455 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -25456 89/<- %ebx 0/r32/eax -25457 $check-mu-populate-stream-stmt:check-target-type-deref: -25458 # if (target->is-deref?) target-type = target-type->payload -25459 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref -25460 3d/compare-eax-and 0/imm32/false -25461 { -25462 74/jump-if-= break/disp8 -25463 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25464 # if target-type->right is null, target-type = target-type->left -25465 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -25466 { -25467 75/jump-if-!= break/disp8 -25468 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25469 } -25470 89/<- %ebx 0/r32/eax -25471 } -25472 $check-mu-populate-stream-stmt:check-target-type-addr: -25473 # if target-type is not addr, abort -25474 (mu-addr-type? %ebx) # => eax -25475 3d/compare-eax-and 0/imm32/false -25476 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 -25477 # if target-type->right is an atom, abort -25478 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25353 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +25354 0f 85/jump-if-!= $check-mu-populate-stmt:error-invalid-target-type/disp32 +25355 $check-mu-populate-stmt:check-target-type-handle: +25356 # if target-type->right->left is not handle, abort +25357 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +25358 (simple-mu-type? %eax 4) # handle => eax +25359 3d/compare-eax-and 0/imm32/false +25360 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32 +25361 # if target-type->right->right is an atom, abort +25362 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25363 89/<- %ebx 0/r32/eax +25364 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +25365 0f 85/jump-if-!= $check-mu-populate-stmt:error-invalid-target-type/disp32 +25366 $check-mu-populate-stmt:check-target-type-array: +25367 # if target-type->right->right->left is not array, abort +25368 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +25369 (simple-mu-type? %eax 3) # array => eax +25370 3d/compare-eax-and 0/imm32/false +25371 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32 +25372 $check-mu-populate-stmt:check-length-type: +25373 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +25374 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25375 89/<- %ebx 0/r32/eax +25376 (simple-mu-type? %ebx 0) # literal => eax +25377 3d/compare-eax-and 0/imm32/false +25378 75/jump-if-!= $check-mu-populate-stmt:end/disp8 +25379 (simple-mu-type? %ebx 1) # int => eax +25380 3d/compare-eax-and 0/imm32/false +25381 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-length-type/disp32 +25382 $check-mu-populate-stmt:end: +25383 # . restore registers +25384 5f/pop-to-edi +25385 5e/pop-to-esi +25386 5b/pop-to-ebx +25387 58/pop-to-eax +25388 # . epilogue +25389 89/<- %esp 5/r32/ebp +25390 5d/pop-to-ebp +25391 c3/return +25392 +25393 $check-mu-populate-stmt:error-incorrect-inouts: +25394 (write-buffered *(ebp+0x10) "fn ") +25395 8b/-> *(ebp+0xc) 0/r32/eax +25396 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25397 (write-buffered *(ebp+0x10) %eax) +25398 (write-buffered *(ebp+0x10) ": stmt 'populate' must have two inouts\n") +25399 (flush *(ebp+0x10)) +25400 (stop *(ebp+0x14) 1) +25401 # never gets here +25402 +25403 $check-mu-populate-stmt:error-too-many-outputs: +25404 (write-buffered *(ebp+0x10) "fn ") +25405 8b/-> *(ebp+0xc) 0/r32/eax +25406 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25407 (write-buffered *(ebp+0x10) %eax) +25408 (write-buffered *(ebp+0x10) ": stmt 'populate' must not have any outputs\n") +25409 (flush *(ebp+0x10)) +25410 (stop *(ebp+0x14) 1) +25411 # never gets here +25412 +25413 $check-mu-populate-stmt:error-invalid-target-type: +25414 (write-buffered *(ebp+0x10) "fn ") +25415 8b/-> *(ebp+0xc) 0/r32/eax +25416 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25417 (write-buffered *(ebp+0x10) %eax) +25418 (write-buffered *(ebp+0x10) ": stmt populate: first inout '") +25419 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25420 (lookup *eax *(eax+4)) # Var-name Var-name => eax +25421 (write-buffered *(ebp+0x10) %eax) +25422 (write-buffered *(ebp+0x10) "' must have type (addr handle array ...)\n") +25423 (flush *(ebp+0x10)) +25424 (stop *(ebp+0x14) 1) +25425 # never gets here +25426 +25427 $check-mu-populate-stmt:error-invalid-length-type: +25428 (write-buffered *(ebp+0x10) "fn ") +25429 8b/-> *(ebp+0xc) 0/r32/eax +25430 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25431 (write-buffered *(ebp+0x10) %eax) +25432 (write-buffered *(ebp+0x10) ": stmt populate: second inout '") +25433 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +25434 (lookup *eax *(eax+4)) # Var-name Var-name => eax +25435 (write-buffered *(ebp+0x10) %eax) +25436 (write-buffered *(ebp+0x10) "' must be an int\n") +25437 (flush *(ebp+0x10)) +25438 (stop *(ebp+0x14) 1) +25439 # never gets here +25440 +25441 check-mu-populate-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +25442 # . prologue +25443 55/push-ebp +25444 89/<- %ebp 4/r32/esp +25445 # . save registers +25446 50/push-eax +25447 53/push-ebx +25448 56/push-esi +25449 57/push-edi +25450 # esi = stmt +25451 8b/-> *(ebp+8) 6/r32/esi +25452 $check-mu-populate-stream-stmt:check-for-output: +25453 # if stmt->outputs abort +25454 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +25455 3d/compare-eax-and 0/imm32 +25456 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-too-many-outputs/disp32 +25457 $check-mu-populate-stream-stmt:get-target: +25458 # var target/edi: (addr stmt-var) = stmt->inouts +25459 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25460 89/<- %edi 0/r32/eax +25461 # zero inouts +25462 3d/compare-eax-and 0/imm32 +25463 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32 +25464 $check-mu-populate-stream-stmt:get-length: +25465 # var length/esi: (addr stmt-var) = dest->next +25466 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +25467 89/<- %esi 0/r32/eax +25468 # 1 inout +25469 3d/compare-eax-and 0/imm32 +25470 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32 +25471 # > 2 inouts +25472 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +25473 3d/compare-eax-and 0/imm32 +25474 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32 +25475 $check-mu-populate-stream-stmt:check-target-type: +25476 # var target-type/ebx: (addr type-tree) = target->value->type +25477 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25478 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax 25479 89/<- %ebx 0/r32/eax -25480 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -25481 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 -25482 $check-mu-populate-stream-stmt:check-target-type-handle: -25483 # if target-type->right->left is not handle, abort -25484 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -25485 (simple-mu-type? %eax 4) # handle => eax -25486 3d/compare-eax-and 0/imm32/false -25487 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 -25488 # if target-type->right->right is an atom, abort -25489 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25490 89/<- %ebx 0/r32/eax -25491 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -25492 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 -25493 $check-mu-populate-stream-stmt:check-target-type-stream: -25494 # if target-type->right->right->left is not stream, abort -25495 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -25496 (simple-mu-type? %eax 0xb) # stream => eax -25497 3d/compare-eax-and 0/imm32/false -25498 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 -25499 $check-mu-populate-stream-stmt:check-length-type: -25500 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -25501 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25480 $check-mu-populate-stream-stmt:check-target-type-deref: +25481 # if (target->is-deref?) target-type = target-type->payload +25482 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref +25483 3d/compare-eax-and 0/imm32/false +25484 { +25485 74/jump-if-= break/disp8 +25486 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25487 # if target-type->right is null, target-type = target-type->left +25488 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +25489 { +25490 75/jump-if-!= break/disp8 +25491 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25492 } +25493 89/<- %ebx 0/r32/eax +25494 } +25495 $check-mu-populate-stream-stmt:check-target-type-addr: +25496 # if target-type is not addr, abort +25497 (mu-addr-type? %ebx) # => eax +25498 3d/compare-eax-and 0/imm32/false +25499 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 +25500 # if target-type->right is an atom, abort +25501 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax 25502 89/<- %ebx 0/r32/eax -25503 (simple-mu-type? %ebx 0) # literal => eax -25504 3d/compare-eax-and 0/imm32/false -25505 75/jump-if-!= $check-mu-populate-stream-stmt:end/disp8 -25506 (simple-mu-type? %ebx 1) # int => eax -25507 3d/compare-eax-and 0/imm32/false -25508 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-length-type/disp32 -25509 $check-mu-populate-stream-stmt:end: -25510 # . restore registers -25511 5f/pop-to-edi -25512 5e/pop-to-esi -25513 5b/pop-to-ebx -25514 58/pop-to-eax -25515 # . epilogue -25516 89/<- %esp 5/r32/ebp -25517 5d/pop-to-ebp -25518 c3/return -25519 -25520 $check-mu-populate-stream-stmt:error-incorrect-inouts: -25521 (write-buffered *(ebp+0x10) "fn ") -25522 8b/-> *(ebp+0xc) 0/r32/eax -25523 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25524 (write-buffered *(ebp+0x10) %eax) -25525 (write-buffered *(ebp+0x10) ": stmt 'populate-stream' must have two inouts\n") -25526 (flush *(ebp+0x10)) -25527 (stop *(ebp+0x14) 1) -25528 # never gets here -25529 -25530 $check-mu-populate-stream-stmt:error-too-many-outputs: -25531 (write-buffered *(ebp+0x10) "fn ") -25532 8b/-> *(ebp+0xc) 0/r32/eax -25533 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25534 (write-buffered *(ebp+0x10) %eax) -25535 (write-buffered *(ebp+0x10) ": stmt 'populate-stream' must not have any outputs\n") -25536 (flush *(ebp+0x10)) -25537 (stop *(ebp+0x14) 1) -25538 # never gets here -25539 -25540 $check-mu-populate-stream-stmt:error-invalid-target-type: -25541 (write-buffered *(ebp+0x10) "fn ") -25542 8b/-> *(ebp+0xc) 0/r32/eax -25543 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25544 (write-buffered *(ebp+0x10) %eax) -25545 (write-buffered *(ebp+0x10) ": stmt populate-stream: first inout '") -25546 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25547 (lookup *eax *(eax+4)) # Var-name Var-name => eax -25548 (write-buffered *(ebp+0x10) %eax) -25549 (write-buffered *(ebp+0x10) "' must have type (addr handle stream ...)\n") -25550 (flush *(ebp+0x10)) -25551 (stop *(ebp+0x14) 1) -25552 # never gets here -25553 -25554 $check-mu-populate-stream-stmt:error-invalid-length-type: -25555 (write-buffered *(ebp+0x10) "fn ") -25556 8b/-> *(ebp+0xc) 0/r32/eax -25557 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25558 (write-buffered *(ebp+0x10) %eax) -25559 (write-buffered *(ebp+0x10) ": stmt populate-stream: second inout '") -25560 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -25561 (lookup *eax *(eax+4)) # Var-name Var-name => eax -25562 (write-buffered *(ebp+0x10) %eax) -25563 (write-buffered *(ebp+0x10) "' must be an int\n") -25564 (flush *(ebp+0x10)) -25565 (stop *(ebp+0x14) 1) -25566 # never gets here -25567 -25568 check-mu-read-from-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -25569 # . prologue -25570 55/push-ebp -25571 89/<- %ebp 4/r32/esp -25572 # . save registers -25573 50/push-eax -25574 51/push-ecx -25575 52/push-edx -25576 53/push-ebx -25577 56/push-esi -25578 57/push-edi -25579 # esi = stmt -25580 8b/-> *(ebp+8) 6/r32/esi -25581 # - check for 0 inouts -25582 # var base/ecx: (addr var) = stmt->inouts->value -25583 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25584 $check-mu-read-from-stream-stmt:check-no-inouts: -25585 3d/compare-eax-and 0/imm32 -25586 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-too-few-inouts/disp32 -25587 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -25588 89/<- %ecx 0/r32/eax -25589 # - check base type is (addr stream T) -25590 # var base-type/ebx: (addr type-tree) = lookup(base->type) -25591 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -25592 89/<- %ebx 0/r32/eax -25593 $check-mu-read-from-stream-stmt:check-base-is-compound: -25594 # if base-type is an atom, abort -25595 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -25596 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32 -25597 $check-mu-read-from-stream-stmt:check-base-is-addr: -25598 # if type->left not addr, abort -25599 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -25600 (simple-mu-type? %eax 2) # addr => eax -25601 3d/compare-eax-and 0/imm32/false -25602 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32 -25603 $check-mu-read-from-stream-stmt:check-base-is-addr-to-stream: -25604 # base-type = base-type->right -25605 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25606 89/<- %ebx 0/r32/eax -25607 # ensure base-type->left == stream -25608 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25609 (simple-mu-type? %eax 0xb) # stream => eax -25610 3d/compare-eax-and 0/imm32/false -25611 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32 -25612 # - check target type is (addr T) -25613 # var target/ecx: (addr stmt-var) = stmt->inouts->next->value -25614 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25615 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -25616 $check-mu-read-from-stream-stmt:check-single-inout: -25617 3d/compare-eax-and 0/imm32 -25618 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-too-few-inouts/disp32 -25619 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -25620 89/<- %ecx 0/r32/eax -25621 # var target-type/edx: (addr type-tree) -25622 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -25623 89/<- %edx 0/r32/eax -25624 # if target-type is an atom, it must be a literal or int -25625 $check-mu-read-from-stream-stmt:check-target-is-compound: -25626 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom -25627 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-target-type-not-address/disp32 -25628 $check-mu-read-from-stream-stmt:check-target-type: -25629 # target type must start with (addr ...) -25630 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -25631 (simple-mu-type? %eax 2) # addr => eax -25632 3d/compare-eax-and 0/imm32/false -25633 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-target-type-not-address/disp32 -25634 # if tail(base-type) != tail(target-type) abort -25635 (type-tail %ebx) # => eax -25636 89/<- %ebx 0/r32/eax -25637 (type-tail %edx) # => eax -25638 (type-equal? %ebx %eax) # => eax -25639 3d/compare-eax-and 0/imm32/false -25640 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-target-type/disp32 -25641 $check-mu-read-from-stream-stmt:check-too-many-inouts: -25642 # - check for too many inouts -25643 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25644 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -25645 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -25646 3d/compare-eax-and 0/imm32/false -25647 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-too-many-inouts/disp32 -25648 $check-mu-read-from-stream-stmt:check-unexpected-output: -25649 # - check for any output -25650 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -25651 3d/compare-eax-and 0/imm32/false -25652 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-unexpected-output/disp32 -25653 $check-mu-read-from-stream-stmt:end: -25654 # . restore registers -25655 5f/pop-to-edi -25656 5e/pop-to-esi -25657 5b/pop-to-ebx -25658 5a/pop-to-edx -25659 59/pop-to-ecx -25660 58/pop-to-eax -25661 # . epilogue -25662 89/<- %esp 5/r32/ebp -25663 5d/pop-to-ebp -25664 c3/return -25665 -25666 $check-mu-read-from-stream-stmt:error-invalid-base-type: -25667 (write-buffered *(ebp+0x10) "fn ") -25668 8b/-> *(ebp+0xc) 0/r32/eax -25669 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25670 (write-buffered *(ebp+0x10) %eax) -25671 (write-buffered *(ebp+0x10) ": stmt read-from-stream: var '") -25672 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -25673 (write-buffered *(ebp+0x10) %eax) -25674 (write-buffered *(ebp+0x10) "' must be an addr to a stream\n") -25675 (flush *(ebp+0x10)) -25676 (stop *(ebp+0x14) 1) -25677 # never gets here -25678 -25679 $check-mu-read-from-stream-stmt:error-too-few-inouts: -25680 (write-buffered *(ebp+0x10) "fn ") -25681 8b/-> *(ebp+0xc) 0/r32/eax -25682 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25683 (write-buffered *(ebp+0x10) %eax) -25684 (write-buffered *(ebp+0x10) ": stmt read-from-stream: too few inouts (2 required)\n") -25685 (flush *(ebp+0x10)) -25686 (stop *(ebp+0x14) 1) -25687 # never gets here +25503 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +25504 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 +25505 $check-mu-populate-stream-stmt:check-target-type-handle: +25506 # if target-type->right->left is not handle, abort +25507 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +25508 (simple-mu-type? %eax 4) # handle => eax +25509 3d/compare-eax-and 0/imm32/false +25510 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 +25511 # if target-type->right->right is an atom, abort +25512 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25513 89/<- %ebx 0/r32/eax +25514 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +25515 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 +25516 $check-mu-populate-stream-stmt:check-target-type-stream: +25517 # if target-type->right->right->left is not stream, abort +25518 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +25519 (simple-mu-type? %eax 0xb) # stream => eax +25520 3d/compare-eax-and 0/imm32/false +25521 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32 +25522 $check-mu-populate-stream-stmt:check-length-type: +25523 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +25524 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25525 89/<- %ebx 0/r32/eax +25526 (simple-mu-type? %ebx 0) # literal => eax +25527 3d/compare-eax-and 0/imm32/false +25528 75/jump-if-!= $check-mu-populate-stream-stmt:end/disp8 +25529 (simple-mu-type? %ebx 1) # int => eax +25530 3d/compare-eax-and 0/imm32/false +25531 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-length-type/disp32 +25532 $check-mu-populate-stream-stmt:end: +25533 # . restore registers +25534 5f/pop-to-edi +25535 5e/pop-to-esi +25536 5b/pop-to-ebx +25537 58/pop-to-eax +25538 # . epilogue +25539 89/<- %esp 5/r32/ebp +25540 5d/pop-to-ebp +25541 c3/return +25542 +25543 $check-mu-populate-stream-stmt:error-incorrect-inouts: +25544 (write-buffered *(ebp+0x10) "fn ") +25545 8b/-> *(ebp+0xc) 0/r32/eax +25546 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25547 (write-buffered *(ebp+0x10) %eax) +25548 (write-buffered *(ebp+0x10) ": stmt 'populate-stream' must have two inouts\n") +25549 (flush *(ebp+0x10)) +25550 (stop *(ebp+0x14) 1) +25551 # never gets here +25552 +25553 $check-mu-populate-stream-stmt:error-too-many-outputs: +25554 (write-buffered *(ebp+0x10) "fn ") +25555 8b/-> *(ebp+0xc) 0/r32/eax +25556 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25557 (write-buffered *(ebp+0x10) %eax) +25558 (write-buffered *(ebp+0x10) ": stmt 'populate-stream' must not have any outputs\n") +25559 (flush *(ebp+0x10)) +25560 (stop *(ebp+0x14) 1) +25561 # never gets here +25562 +25563 $check-mu-populate-stream-stmt:error-invalid-target-type: +25564 (write-buffered *(ebp+0x10) "fn ") +25565 8b/-> *(ebp+0xc) 0/r32/eax +25566 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25567 (write-buffered *(ebp+0x10) %eax) +25568 (write-buffered *(ebp+0x10) ": stmt populate-stream: first inout '") +25569 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25570 (lookup *eax *(eax+4)) # Var-name Var-name => eax +25571 (write-buffered *(ebp+0x10) %eax) +25572 (write-buffered *(ebp+0x10) "' must have type (addr handle stream ...)\n") +25573 (flush *(ebp+0x10)) +25574 (stop *(ebp+0x14) 1) +25575 # never gets here +25576 +25577 $check-mu-populate-stream-stmt:error-invalid-length-type: +25578 (write-buffered *(ebp+0x10) "fn ") +25579 8b/-> *(ebp+0xc) 0/r32/eax +25580 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25581 (write-buffered *(ebp+0x10) %eax) +25582 (write-buffered *(ebp+0x10) ": stmt populate-stream: second inout '") +25583 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +25584 (lookup *eax *(eax+4)) # Var-name Var-name => eax +25585 (write-buffered *(ebp+0x10) %eax) +25586 (write-buffered *(ebp+0x10) "' must be an int\n") +25587 (flush *(ebp+0x10)) +25588 (stop *(ebp+0x14) 1) +25589 # never gets here +25590 +25591 check-mu-read-from-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +25592 # . prologue +25593 55/push-ebp +25594 89/<- %ebp 4/r32/esp +25595 # . save registers +25596 50/push-eax +25597 51/push-ecx +25598 52/push-edx +25599 53/push-ebx +25600 56/push-esi +25601 57/push-edi +25602 # esi = stmt +25603 8b/-> *(ebp+8) 6/r32/esi +25604 # - check for 0 inouts +25605 # var base/ecx: (addr var) = stmt->inouts->value +25606 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25607 $check-mu-read-from-stream-stmt:check-no-inouts: +25608 3d/compare-eax-and 0/imm32 +25609 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-too-few-inouts/disp32 +25610 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +25611 89/<- %ecx 0/r32/eax +25612 # - check base type is (addr stream T) +25613 # var base-type/ebx: (addr type-tree) = lookup(base->type) +25614 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +25615 89/<- %ebx 0/r32/eax +25616 $check-mu-read-from-stream-stmt:check-base-is-compound: +25617 # if base-type is an atom, abort +25618 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +25619 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32 +25620 $check-mu-read-from-stream-stmt:check-base-is-addr: +25621 # if type->left not addr, abort +25622 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +25623 (simple-mu-type? %eax 2) # addr => eax +25624 3d/compare-eax-and 0/imm32/false +25625 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32 +25626 $check-mu-read-from-stream-stmt:check-base-is-addr-to-stream: +25627 # base-type = base-type->right +25628 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25629 89/<- %ebx 0/r32/eax +25630 # ensure base-type->left == stream +25631 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25632 (simple-mu-type? %eax 0xb) # stream => eax +25633 3d/compare-eax-and 0/imm32/false +25634 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32 +25635 # - check target type is (addr T) +25636 # var target/ecx: (addr stmt-var) = stmt->inouts->next->value +25637 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25638 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +25639 $check-mu-read-from-stream-stmt:check-single-inout: +25640 3d/compare-eax-and 0/imm32 +25641 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-too-few-inouts/disp32 +25642 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +25643 89/<- %ecx 0/r32/eax +25644 # var target-type/edx: (addr type-tree) +25645 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +25646 89/<- %edx 0/r32/eax +25647 # if target-type is an atom, it must be a literal or int +25648 $check-mu-read-from-stream-stmt:check-target-is-compound: +25649 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +25650 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-target-type-not-address/disp32 +25651 $check-mu-read-from-stream-stmt:check-target-type: +25652 # target type must start with (addr ...) +25653 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +25654 (simple-mu-type? %eax 2) # addr => eax +25655 3d/compare-eax-and 0/imm32/false +25656 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-target-type-not-address/disp32 +25657 # if tail(base-type) != tail(target-type) abort +25658 (type-tail %ebx) # => eax +25659 89/<- %ebx 0/r32/eax +25660 (type-tail %edx) # => eax +25661 (type-equal? %ebx %eax) # => eax +25662 3d/compare-eax-and 0/imm32/false +25663 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-target-type/disp32 +25664 $check-mu-read-from-stream-stmt:check-too-many-inouts: +25665 # - check for too many inouts +25666 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25667 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +25668 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +25669 3d/compare-eax-and 0/imm32/false +25670 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-too-many-inouts/disp32 +25671 $check-mu-read-from-stream-stmt:check-unexpected-output: +25672 # - check for any output +25673 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +25674 3d/compare-eax-and 0/imm32/false +25675 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-unexpected-output/disp32 +25676 $check-mu-read-from-stream-stmt:end: +25677 # . restore registers +25678 5f/pop-to-edi +25679 5e/pop-to-esi +25680 5b/pop-to-ebx +25681 5a/pop-to-edx +25682 59/pop-to-ecx +25683 58/pop-to-eax +25684 # . epilogue +25685 89/<- %esp 5/r32/ebp +25686 5d/pop-to-ebp +25687 c3/return 25688 -25689 $check-mu-read-from-stream-stmt:error-target-type-not-address: +25689 $check-mu-read-from-stream-stmt:error-invalid-base-type: 25690 (write-buffered *(ebp+0x10) "fn ") 25691 8b/-> *(ebp+0xc) 0/r32/eax 25692 (lookup *eax *(eax+4)) # Function-name Function-name => eax 25693 (write-buffered *(ebp+0x10) %eax) -25694 (write-buffered *(ebp+0x10) ": stmt read-from-stream: target '") +25694 (write-buffered *(ebp+0x10) ": stmt read-from-stream: var '") 25695 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 25696 (write-buffered *(ebp+0x10) %eax) -25697 (write-buffered *(ebp+0x10) "' must be an addr\n") +25697 (write-buffered *(ebp+0x10) "' must be an addr to a stream\n") 25698 (flush *(ebp+0x10)) 25699 (stop *(ebp+0x14) 1) 25700 # never gets here 25701 -25702 $check-mu-read-from-stream-stmt:error-invalid-target-type: +25702 $check-mu-read-from-stream-stmt:error-too-few-inouts: 25703 (write-buffered *(ebp+0x10) "fn ") 25704 8b/-> *(ebp+0xc) 0/r32/eax 25705 (lookup *eax *(eax+4)) # Function-name Function-name => eax 25706 (write-buffered *(ebp+0x10) %eax) -25707 (write-buffered *(ebp+0x10) ": stmt read-from-stream: second inout '") -25708 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -25709 (write-buffered *(ebp+0x10) %eax) -25710 (write-buffered *(ebp+0x10) "' does not have the right type\n") -25711 (flush *(ebp+0x10)) -25712 (stop *(ebp+0x14) 1) -25713 # never gets here -25714 -25715 $check-mu-read-from-stream-stmt:error-too-many-inouts: -25716 (write-buffered *(ebp+0x10) "fn ") -25717 8b/-> *(ebp+0xc) 0/r32/eax -25718 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25707 (write-buffered *(ebp+0x10) ": stmt read-from-stream: too few inouts (2 required)\n") +25708 (flush *(ebp+0x10)) +25709 (stop *(ebp+0x14) 1) +25710 # never gets here +25711 +25712 $check-mu-read-from-stream-stmt:error-target-type-not-address: +25713 (write-buffered *(ebp+0x10) "fn ") +25714 8b/-> *(ebp+0xc) 0/r32/eax +25715 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25716 (write-buffered *(ebp+0x10) %eax) +25717 (write-buffered *(ebp+0x10) ": stmt read-from-stream: target '") +25718 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 25719 (write-buffered *(ebp+0x10) %eax) -25720 (write-buffered *(ebp+0x10) ": stmt read-from-stream: too many inouts (2 required)\n") +25720 (write-buffered *(ebp+0x10) "' must be an addr\n") 25721 (flush *(ebp+0x10)) 25722 (stop *(ebp+0x14) 1) 25723 # never gets here 25724 -25725 $check-mu-read-from-stream-stmt:error-unexpected-output: +25725 $check-mu-read-from-stream-stmt:error-invalid-target-type: 25726 (write-buffered *(ebp+0x10) "fn ") 25727 8b/-> *(ebp+0xc) 0/r32/eax 25728 (lookup *eax *(eax+4)) # Function-name Function-name => eax 25729 (write-buffered *(ebp+0x10) %eax) -25730 (write-buffered *(ebp+0x10) ": stmt read-from-stream: unexpected output\n") -25731 (flush *(ebp+0x10)) -25732 (stop *(ebp+0x14) 1) -25733 # never gets here -25734 -25735 check-mu-write-to-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -25736 # . prologue -25737 55/push-ebp -25738 89/<- %ebp 4/r32/esp -25739 # . save registers -25740 50/push-eax -25741 51/push-ecx -25742 52/push-edx -25743 53/push-ebx -25744 56/push-esi -25745 57/push-edi -25746 # esi = stmt -25747 8b/-> *(ebp+8) 6/r32/esi -25748 # - check for 0 inouts -25749 # var base/ecx: (addr var) = stmt->inouts->value -25750 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25751 $check-mu-write-to-stream-stmt:check-no-inouts: -25752 3d/compare-eax-and 0/imm32 -25753 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-too-few-inouts/disp32 -25754 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -25755 89/<- %ecx 0/r32/eax -25756 # - check base type is (addr stream T) -25757 # var base-type/ebx: (addr type-tree) = lookup(base->type) -25758 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -25759 89/<- %ebx 0/r32/eax -25760 $check-mu-write-to-stream-stmt:check-base-is-compound: -25761 # if base-type is an atom, abort -25762 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -25763 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32 -25764 $check-mu-write-to-stream-stmt:check-base-is-addr: -25765 # if type->left not addr, abort -25766 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -25767 (simple-mu-type? %eax 2) # addr => eax -25768 3d/compare-eax-and 0/imm32/false -25769 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32 -25770 $check-mu-write-to-stream-stmt:check-base-is-addr-to-stream: -25771 # base-type = base-type->right -25772 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -25773 89/<- %ebx 0/r32/eax -25774 # ensure base-type->left == stream -25775 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25776 (simple-mu-type? %eax 0xb) # stream => eax -25777 3d/compare-eax-and 0/imm32/false -25778 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32 -25779 # - check target type is (addr T) -25780 # var target/ecx: (addr stmt-var) = stmt->inouts->next->value -25781 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25782 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -25783 $check-mu-write-to-stream-stmt:check-single-inout: -25784 3d/compare-eax-and 0/imm32 -25785 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-too-few-inouts/disp32 -25786 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -25787 89/<- %ecx 0/r32/eax -25788 # var target-type/edx: (addr type-tree) -25789 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -25790 89/<- %edx 0/r32/eax -25791 # if target-type is an atom, it must be a literal or int -25792 $check-mu-write-to-stream-stmt:check-target-is-compound: -25793 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom -25794 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-target-type-not-address/disp32 -25795 $check-mu-write-to-stream-stmt:check-target-type: -25796 # target type must start with (addr ...) -25797 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -25798 (simple-mu-type? %eax 2) # addr => eax -25799 3d/compare-eax-and 0/imm32/false -25800 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-target-type-not-address/disp32 -25801 # if tail(base-type) != tail(target-type) abort -25802 (type-tail %ebx) # => eax -25803 89/<- %ebx 0/r32/eax -25804 (type-tail %edx) # => eax -25805 (type-equal? %ebx %eax) # => eax -25806 3d/compare-eax-and 0/imm32/false -25807 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-target-type/disp32 -25808 $check-mu-write-to-stream-stmt:check-too-many-inouts: -25809 # - check for too many inouts -25810 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25811 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -25812 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -25813 3d/compare-eax-and 0/imm32/false -25814 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-too-many-inouts/disp32 -25815 $check-mu-write-to-stream-stmt:check-unexpected-output: -25816 # - check for any output -25817 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -25818 3d/compare-eax-and 0/imm32/false -25819 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-unexpected-output/disp32 -25820 $check-mu-write-to-stream-stmt:end: -25821 # . restore registers -25822 5f/pop-to-edi -25823 5e/pop-to-esi -25824 5b/pop-to-ebx -25825 5a/pop-to-edx -25826 59/pop-to-ecx -25827 58/pop-to-eax -25828 # . epilogue -25829 89/<- %esp 5/r32/ebp -25830 5d/pop-to-ebp -25831 c3/return -25832 -25833 $check-mu-write-to-stream-stmt:error-invalid-base-type: -25834 (write-buffered *(ebp+0x10) "fn ") -25835 8b/-> *(ebp+0xc) 0/r32/eax -25836 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25837 (write-buffered *(ebp+0x10) %eax) -25838 (write-buffered *(ebp+0x10) ": stmt write-to-stream: var '") -25839 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -25840 (write-buffered *(ebp+0x10) %eax) -25841 (write-buffered *(ebp+0x10) "' must be an addr to a stream\n") -25842 (flush *(ebp+0x10)) -25843 (stop *(ebp+0x14) 1) -25844 # never gets here -25845 -25846 $check-mu-write-to-stream-stmt:error-too-few-inouts: -25847 (write-buffered *(ebp+0x10) "fn ") -25848 8b/-> *(ebp+0xc) 0/r32/eax -25849 (lookup *eax *(eax+4)) # Function-name Function-name => eax -25850 (write-buffered *(ebp+0x10) %eax) -25851 (write-buffered *(ebp+0x10) ": stmt write-to-stream: too few inouts (2 required)\n") -25852 (flush *(ebp+0x10)) -25853 (stop *(ebp+0x14) 1) -25854 # never gets here +25730 (write-buffered *(ebp+0x10) ": stmt read-from-stream: second inout '") +25731 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +25732 (write-buffered *(ebp+0x10) %eax) +25733 (write-buffered *(ebp+0x10) "' does not have the right type\n") +25734 (flush *(ebp+0x10)) +25735 (stop *(ebp+0x14) 1) +25736 # never gets here +25737 +25738 $check-mu-read-from-stream-stmt:error-too-many-inouts: +25739 (write-buffered *(ebp+0x10) "fn ") +25740 8b/-> *(ebp+0xc) 0/r32/eax +25741 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25742 (write-buffered *(ebp+0x10) %eax) +25743 (write-buffered *(ebp+0x10) ": stmt read-from-stream: too many inouts (2 required)\n") +25744 (flush *(ebp+0x10)) +25745 (stop *(ebp+0x14) 1) +25746 # never gets here +25747 +25748 $check-mu-read-from-stream-stmt:error-unexpected-output: +25749 (write-buffered *(ebp+0x10) "fn ") +25750 8b/-> *(ebp+0xc) 0/r32/eax +25751 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25752 (write-buffered *(ebp+0x10) %eax) +25753 (write-buffered *(ebp+0x10) ": stmt read-from-stream: unexpected output\n") +25754 (flush *(ebp+0x10)) +25755 (stop *(ebp+0x14) 1) +25756 # never gets here +25757 +25758 check-mu-write-to-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +25759 # . prologue +25760 55/push-ebp +25761 89/<- %ebp 4/r32/esp +25762 # . save registers +25763 50/push-eax +25764 51/push-ecx +25765 52/push-edx +25766 53/push-ebx +25767 56/push-esi +25768 57/push-edi +25769 # esi = stmt +25770 8b/-> *(ebp+8) 6/r32/esi +25771 # - check for 0 inouts +25772 # var base/ecx: (addr var) = stmt->inouts->value +25773 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25774 $check-mu-write-to-stream-stmt:check-no-inouts: +25775 3d/compare-eax-and 0/imm32 +25776 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-too-few-inouts/disp32 +25777 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +25778 89/<- %ecx 0/r32/eax +25779 # - check base type is (addr stream T) +25780 # var base-type/ebx: (addr type-tree) = lookup(base->type) +25781 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +25782 89/<- %ebx 0/r32/eax +25783 $check-mu-write-to-stream-stmt:check-base-is-compound: +25784 # if base-type is an atom, abort +25785 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +25786 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32 +25787 $check-mu-write-to-stream-stmt:check-base-is-addr: +25788 # if type->left not addr, abort +25789 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +25790 (simple-mu-type? %eax 2) # addr => eax +25791 3d/compare-eax-and 0/imm32/false +25792 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32 +25793 $check-mu-write-to-stream-stmt:check-base-is-addr-to-stream: +25794 # base-type = base-type->right +25795 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +25796 89/<- %ebx 0/r32/eax +25797 # ensure base-type->left == stream +25798 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25799 (simple-mu-type? %eax 0xb) # stream => eax +25800 3d/compare-eax-and 0/imm32/false +25801 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32 +25802 # - check target type is (addr T) +25803 # var target/ecx: (addr stmt-var) = stmt->inouts->next->value +25804 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25805 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +25806 $check-mu-write-to-stream-stmt:check-single-inout: +25807 3d/compare-eax-and 0/imm32 +25808 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-too-few-inouts/disp32 +25809 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +25810 89/<- %ecx 0/r32/eax +25811 # var target-type/edx: (addr type-tree) +25812 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +25813 89/<- %edx 0/r32/eax +25814 # if target-type is an atom, it must be a literal or int +25815 $check-mu-write-to-stream-stmt:check-target-is-compound: +25816 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom +25817 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-target-type-not-address/disp32 +25818 $check-mu-write-to-stream-stmt:check-target-type: +25819 # target type must start with (addr ...) +25820 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +25821 (simple-mu-type? %eax 2) # addr => eax +25822 3d/compare-eax-and 0/imm32/false +25823 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-target-type-not-address/disp32 +25824 # if tail(base-type) != tail(target-type) abort +25825 (type-tail %ebx) # => eax +25826 89/<- %ebx 0/r32/eax +25827 (type-tail %edx) # => eax +25828 (type-equal? %ebx %eax) # => eax +25829 3d/compare-eax-and 0/imm32/false +25830 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-target-type/disp32 +25831 $check-mu-write-to-stream-stmt:check-too-many-inouts: +25832 # - check for too many inouts +25833 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25834 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +25835 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +25836 3d/compare-eax-and 0/imm32/false +25837 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-too-many-inouts/disp32 +25838 $check-mu-write-to-stream-stmt:check-unexpected-output: +25839 # - check for any output +25840 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +25841 3d/compare-eax-and 0/imm32/false +25842 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-unexpected-output/disp32 +25843 $check-mu-write-to-stream-stmt:end: +25844 # . restore registers +25845 5f/pop-to-edi +25846 5e/pop-to-esi +25847 5b/pop-to-ebx +25848 5a/pop-to-edx +25849 59/pop-to-ecx +25850 58/pop-to-eax +25851 # . epilogue +25852 89/<- %esp 5/r32/ebp +25853 5d/pop-to-ebp +25854 c3/return 25855 -25856 $check-mu-write-to-stream-stmt:error-target-type-not-address: +25856 $check-mu-write-to-stream-stmt:error-invalid-base-type: 25857 (write-buffered *(ebp+0x10) "fn ") 25858 8b/-> *(ebp+0xc) 0/r32/eax 25859 (lookup *eax *(eax+4)) # Function-name Function-name => eax 25860 (write-buffered *(ebp+0x10) %eax) -25861 (write-buffered *(ebp+0x10) ": stmt write-to-stream: target '") +25861 (write-buffered *(ebp+0x10) ": stmt write-to-stream: var '") 25862 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 25863 (write-buffered *(ebp+0x10) %eax) -25864 (write-buffered *(ebp+0x10) "' must be an addr\n") +25864 (write-buffered *(ebp+0x10) "' must be an addr to a stream\n") 25865 (flush *(ebp+0x10)) 25866 (stop *(ebp+0x14) 1) 25867 # never gets here 25868 -25869 $check-mu-write-to-stream-stmt:error-invalid-target-type: +25869 $check-mu-write-to-stream-stmt:error-too-few-inouts: 25870 (write-buffered *(ebp+0x10) "fn ") 25871 8b/-> *(ebp+0xc) 0/r32/eax 25872 (lookup *eax *(eax+4)) # Function-name Function-name => eax 25873 (write-buffered *(ebp+0x10) %eax) -25874 (write-buffered *(ebp+0x10) ": stmt write-to-stream: second inout '") -25875 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -25876 (write-buffered *(ebp+0x10) %eax) -25877 (write-buffered *(ebp+0x10) "' does not have the right type\n") -25878 (flush *(ebp+0x10)) -25879 (stop *(ebp+0x14) 1) -25880 # never gets here -25881 -25882 $check-mu-write-to-stream-stmt:error-too-many-inouts: -25883 (write-buffered *(ebp+0x10) "fn ") -25884 8b/-> *(ebp+0xc) 0/r32/eax -25885 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25874 (write-buffered *(ebp+0x10) ": stmt write-to-stream: too few inouts (2 required)\n") +25875 (flush *(ebp+0x10)) +25876 (stop *(ebp+0x14) 1) +25877 # never gets here +25878 +25879 $check-mu-write-to-stream-stmt:error-target-type-not-address: +25880 (write-buffered *(ebp+0x10) "fn ") +25881 8b/-> *(ebp+0xc) 0/r32/eax +25882 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25883 (write-buffered *(ebp+0x10) %eax) +25884 (write-buffered *(ebp+0x10) ": stmt write-to-stream: target '") +25885 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax 25886 (write-buffered *(ebp+0x10) %eax) -25887 (write-buffered *(ebp+0x10) ": stmt write-to-stream: too many inouts (2 required)\n") +25887 (write-buffered *(ebp+0x10) "' must be an addr\n") 25888 (flush *(ebp+0x10)) 25889 (stop *(ebp+0x14) 1) 25890 # never gets here 25891 -25892 $check-mu-write-to-stream-stmt:error-unexpected-output: +25892 $check-mu-write-to-stream-stmt:error-invalid-target-type: 25893 (write-buffered *(ebp+0x10) "fn ") 25894 8b/-> *(ebp+0xc) 0/r32/eax 25895 (lookup *eax *(eax+4)) # Function-name Function-name => eax 25896 (write-buffered *(ebp+0x10) %eax) -25897 (write-buffered *(ebp+0x10) ": stmt write-to-stream: unexpected output\n") -25898 (flush *(ebp+0x10)) -25899 (stop *(ebp+0x14) 1) -25900 # never gets here -25901 -25902 check-mu-convert-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -25903 # . prologue -25904 55/push-ebp -25905 89/<- %ebp 4/r32/esp -25906 # . save registers -25907 50/push-eax -25908 51/push-ecx -25909 52/push-edx -25910 56/push-esi -25911 57/push-edi -25912 $check-mu-convert-stmt:get-output: -25913 # esi = stmt -25914 8b/-> *(ebp+8) 6/r32/esi -25915 # var output/edi: (addr stmt-var) = stmt->outputs -25916 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -25917 89/<- %edi 0/r32/eax -25918 # zero outputs -25919 3d/compare-eax-and 0/imm32 -25920 0f 84/jump-if-= $check-mu-convert-stmt:error-no-output/disp32 -25921 # > 1 output -25922 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -25923 3d/compare-eax-and 0/imm32 -25924 0f 85/jump-if-!= $check-mu-convert-stmt:error-too-many-outputs/disp32 -25925 $check-mu-convert-stmt:get-inout: -25926 # var inout/esi: (addr stmt-var) = stmt->inouts -25927 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -25928 89/<- %esi 0/r32/eax -25929 # zero inouts -25930 3d/compare-eax-and 0/imm32 -25931 0f 84/jump-if-= $check-mu-convert-stmt:error-no-inout/disp32 -25932 # > 1 inout -25933 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -25934 3d/compare-eax-and 0/imm32 -25935 0f 85/jump-if-!= $check-mu-convert-stmt:error-too-many-inouts/disp32 -25936 $check-mu-convert-stmt:types: -25937 # var inout-type/ecx: (addr type-tree) = inout->value->type -25938 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -25939 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -25940 89/<- %ecx 0/r32/eax -25941 # if (inout->is-deref?) inout-type = inout-type->payload -25942 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref -25943 3d/compare-eax-and 0/imm32/false -25944 { -25945 74/jump-if-= break/disp8 -25946 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -25947 # if inout-type->right is null, t = inout-type->left -25948 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -25949 { -25950 75/jump-if-!= break/disp8 -25951 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -25952 } -25953 89/<- %ecx 0/r32/eax -25954 } -25955 # if input is not int or float, abort -25956 { -25957 (simple-mu-type? %ecx 1) # int => eax -25958 3d/compare-eax-and 0/imm32/false -25959 75/jump-if-!= break/disp8 -25960 (simple-mu-type? %ecx 0xf) # float => eax -25961 3d/compare-eax-and 0/imm32/false -25962 75/jump-if-!= break/disp8 -25963 e9/jump $check-mu-convert-stmt:error-invalid-inout-type/disp32 -25964 } -25965 # if output not in register, abort -25966 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25967 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -25968 3d/compare-eax-and 0/imm32 -25969 0f 84/jump-if-= $check-mu-convert-stmt:error-output-not-in-register/disp32 -25970 # var output-type/edx: (addr type-tree) = output->value->type -25971 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -25972 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -25973 89/<- %edx 0/r32/eax -25974 # if output is not int or float, abort -25975 { -25976 (simple-mu-type? %edx 1) # int => eax -25977 3d/compare-eax-and 0/imm32/false -25978 75/jump-if-!= break/disp8 -25979 (simple-mu-type? %edx 0xf) # float => eax -25980 3d/compare-eax-and 0/imm32/false -25981 75/jump-if-!= break/disp8 -25982 e9/jump $check-mu-convert-stmt:error-invalid-output-type/disp32 -25983 } -25984 # if both are ints, abort -25985 { -25986 (simple-mu-type? %edx 1) # int => eax -25987 3d/compare-eax-and 0/imm32/false -25988 74/jump-if-= break/disp8 -25989 (simple-mu-type? %ecx 1) # int => eax -25990 3d/compare-eax-and 0/imm32/false -25991 74/jump-if-= break/disp8 -25992 e9/jump $check-mu-convert-stmt:error-int-to-int/disp32 -25993 } -25994 # if both are floats, abort -25995 { -25996 (simple-mu-type? %edx 0xf) # float => eax -25997 3d/compare-eax-and 0/imm32/false -25998 74/jump-if-= break/disp8 -25999 (simple-mu-type? %ecx 0xf) # float => eax +25897 (write-buffered *(ebp+0x10) ": stmt write-to-stream: second inout '") +25898 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +25899 (write-buffered *(ebp+0x10) %eax) +25900 (write-buffered *(ebp+0x10) "' does not have the right type\n") +25901 (flush *(ebp+0x10)) +25902 (stop *(ebp+0x14) 1) +25903 # never gets here +25904 +25905 $check-mu-write-to-stream-stmt:error-too-many-inouts: +25906 (write-buffered *(ebp+0x10) "fn ") +25907 8b/-> *(ebp+0xc) 0/r32/eax +25908 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25909 (write-buffered *(ebp+0x10) %eax) +25910 (write-buffered *(ebp+0x10) ": stmt write-to-stream: too many inouts (2 required)\n") +25911 (flush *(ebp+0x10)) +25912 (stop *(ebp+0x14) 1) +25913 # never gets here +25914 +25915 $check-mu-write-to-stream-stmt:error-unexpected-output: +25916 (write-buffered *(ebp+0x10) "fn ") +25917 8b/-> *(ebp+0xc) 0/r32/eax +25918 (lookup *eax *(eax+4)) # Function-name Function-name => eax +25919 (write-buffered *(ebp+0x10) %eax) +25920 (write-buffered *(ebp+0x10) ": stmt write-to-stream: unexpected output\n") +25921 (flush *(ebp+0x10)) +25922 (stop *(ebp+0x14) 1) +25923 # never gets here +25924 +25925 check-mu-convert-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +25926 # . prologue +25927 55/push-ebp +25928 89/<- %ebp 4/r32/esp +25929 # . save registers +25930 50/push-eax +25931 51/push-ecx +25932 52/push-edx +25933 56/push-esi +25934 57/push-edi +25935 $check-mu-convert-stmt:get-output: +25936 # esi = stmt +25937 8b/-> *(ebp+8) 6/r32/esi +25938 # var output/edi: (addr stmt-var) = stmt->outputs +25939 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +25940 89/<- %edi 0/r32/eax +25941 # zero outputs +25942 3d/compare-eax-and 0/imm32 +25943 0f 84/jump-if-= $check-mu-convert-stmt:error-no-output/disp32 +25944 # > 1 output +25945 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +25946 3d/compare-eax-and 0/imm32 +25947 0f 85/jump-if-!= $check-mu-convert-stmt:error-too-many-outputs/disp32 +25948 $check-mu-convert-stmt:get-inout: +25949 # var inout/esi: (addr stmt-var) = stmt->inouts +25950 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +25951 89/<- %esi 0/r32/eax +25952 # zero inouts +25953 3d/compare-eax-and 0/imm32 +25954 0f 84/jump-if-= $check-mu-convert-stmt:error-no-inout/disp32 +25955 # > 1 inout +25956 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +25957 3d/compare-eax-and 0/imm32 +25958 0f 85/jump-if-!= $check-mu-convert-stmt:error-too-many-inouts/disp32 +25959 $check-mu-convert-stmt:types: +25960 # var inout-type/ecx: (addr type-tree) = inout->value->type +25961 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +25962 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25963 89/<- %ecx 0/r32/eax +25964 # if (inout->is-deref?) inout-type = inout-type->payload +25965 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref +25966 3d/compare-eax-and 0/imm32/false +25967 { +25968 74/jump-if-= break/disp8 +25969 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +25970 # if inout-type->right is null, t = inout-type->left +25971 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +25972 { +25973 75/jump-if-!= break/disp8 +25974 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +25975 } +25976 89/<- %ecx 0/r32/eax +25977 } +25978 # if input is not int or float, abort +25979 { +25980 (simple-mu-type? %ecx 1) # int => eax +25981 3d/compare-eax-and 0/imm32/false +25982 75/jump-if-!= break/disp8 +25983 (simple-mu-type? %ecx 0xf) # float => eax +25984 3d/compare-eax-and 0/imm32/false +25985 75/jump-if-!= break/disp8 +25986 e9/jump $check-mu-convert-stmt:error-invalid-inout-type/disp32 +25987 } +25988 # if output not in register, abort +25989 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25990 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +25991 3d/compare-eax-and 0/imm32 +25992 0f 84/jump-if-= $check-mu-convert-stmt:error-output-not-in-register/disp32 +25993 # var output-type/edx: (addr type-tree) = output->value->type +25994 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +25995 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +25996 89/<- %edx 0/r32/eax +25997 # if output is not int or float, abort +25998 { +25999 (simple-mu-type? %edx 1) # int => eax 26000 3d/compare-eax-and 0/imm32/false -26001 74/jump-if-= break/disp8 -26002 e9/jump $check-mu-convert-stmt:error-float-to-float/disp32 -26003 } -26004 $check-mu-convert-stmt:end: -26005 # . restore registers -26006 5f/pop-to-edi -26007 5e/pop-to-esi -26008 5a/pop-to-edx -26009 59/pop-to-ecx -26010 58/pop-to-eax -26011 # . epilogue -26012 89/<- %esp 5/r32/ebp -26013 5d/pop-to-ebp -26014 c3/return -26015 -26016 $check-mu-convert-stmt:error-no-inout: -26017 (write-buffered *(ebp+0x10) "fn ") -26018 8b/-> *(ebp+0xc) 0/r32/eax -26019 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26020 (write-buffered *(ebp+0x10) %eax) -26021 (write-buffered *(ebp+0x10) ": stmt 'convert' expects an inout\n") -26022 (flush *(ebp+0x10)) -26023 (stop *(ebp+0x14) 1) -26024 # never gets here -26025 -26026 $check-mu-convert-stmt:error-too-many-inouts: -26027 (write-buffered *(ebp+0x10) "fn ") -26028 8b/-> *(ebp+0xc) 0/r32/eax -26029 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26030 (write-buffered *(ebp+0x10) %eax) -26031 (write-buffered *(ebp+0x10) ": stmt 'convert' must have just one inout\n") -26032 (flush *(ebp+0x10)) -26033 (stop *(ebp+0x14) 1) -26034 # never gets here -26035 -26036 $check-mu-convert-stmt:error-no-output: -26037 (write-buffered *(ebp+0x10) "fn ") -26038 8b/-> *(ebp+0xc) 0/r32/eax -26039 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26040 (write-buffered *(ebp+0x10) %eax) -26041 (write-buffered *(ebp+0x10) ": stmt 'convert' expects an output\n") -26042 (flush *(ebp+0x10)) -26043 (stop *(ebp+0x14) 1) -26044 # never gets here -26045 -26046 $check-mu-convert-stmt:error-output-not-in-register: -26047 (write-buffered *(ebp+0x10) "fn ") -26048 8b/-> *(ebp+0xc) 0/r32/eax -26049 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26050 (write-buffered *(ebp+0x10) %eax) -26051 (write-buffered *(ebp+0x10) ": stmt convert: output '") -26052 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -26053 (lookup *eax *(eax+4)) # Var-name Var-name => eax -26054 (write-buffered *(ebp+0x10) %eax) -26055 (write-buffered *(ebp+0x10) "' not in a register\n") -26056 (flush *(ebp+0x10)) -26057 (stop *(ebp+0x14) 1) -26058 # never gets here -26059 -26060 $check-mu-convert-stmt:error-too-many-outputs: -26061 (write-buffered *(ebp+0x10) "fn ") -26062 8b/-> *(ebp+0xc) 0/r32/eax -26063 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26064 (write-buffered *(ebp+0x10) %eax) -26065 (write-buffered *(ebp+0x10) ": stmt 'convert' must have just one output\n") -26066 (flush *(ebp+0x10)) -26067 (stop *(ebp+0x14) 1) -26068 # never gets here -26069 -26070 $check-mu-convert-stmt:error-invalid-inout-type: -26071 (write-buffered *(ebp+0x10) "fn ") -26072 8b/-> *(ebp+0xc) 0/r32/eax -26073 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26074 (write-buffered *(ebp+0x10) %eax) -26075 (write-buffered *(ebp+0x10) ": stmt convert: inout '") -26076 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax -26077 (lookup *eax *(eax+4)) # Var-name Var-name => eax -26078 (write-buffered *(ebp+0x10) %eax) -26079 (write-buffered *(ebp+0x10) "' must be an int or float\n") -26080 (flush *(ebp+0x10)) -26081 (stop *(ebp+0x14) 1) -26082 # never gets here -26083 -26084 $check-mu-convert-stmt:error-invalid-output-type: -26085 (write-buffered *(ebp+0x10) "fn ") -26086 8b/-> *(ebp+0xc) 0/r32/eax -26087 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26088 (write-buffered *(ebp+0x10) %eax) -26089 (write-buffered *(ebp+0x10) ": stmt convert: output '") -26090 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax -26091 (lookup *eax *(eax+4)) # Var-name Var-name => eax -26092 (write-buffered *(ebp+0x10) %eax) -26093 (write-buffered *(ebp+0x10) "' must be an int or float\n") -26094 (flush *(ebp+0x10)) -26095 (stop *(ebp+0x14) 1) -26096 # never gets here -26097 -26098 $check-mu-convert-stmt:error-int-to-int: -26099 (write-buffered *(ebp+0x10) "fn ") -26100 8b/-> *(ebp+0xc) 0/r32/eax -26101 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26102 (write-buffered *(ebp+0x10) %eax) -26103 (write-buffered *(ebp+0x10) ": stmt convert: no need to convert int to int\n") -26104 (flush *(ebp+0x10)) -26105 (stop *(ebp+0x14) 1) -26106 # never gets here -26107 -26108 $check-mu-convert-stmt:error-float-to-float: -26109 (write-buffered *(ebp+0x10) "fn ") -26110 8b/-> *(ebp+0xc) 0/r32/eax -26111 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26112 (write-buffered *(ebp+0x10) %eax) -26113 (write-buffered *(ebp+0x10) ": stmt convert: no need to convert float to float\n") -26114 (flush *(ebp+0x10)) -26115 (stop *(ebp+0x14) 1) -26116 # never gets here -26117 -26118 check-mu-call: # stmt: (addr stmt), callee: (addr function), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -26119 # . prologue -26120 55/push-ebp -26121 89/<- %ebp 4/r32/esp -26122 # var type-parameters: (addr table (handle array byte) (addr type-tree) 8) -26123 68/push 0/imm32 -26124 # var type-parameters-storage: (table (handle array byte) (addr type-tree) 8) -26125 81 5/subop/subtract %esp 0x60/imm32 -26126 68/push 0x60/imm32/size -26127 68/push 0/imm32/read -26128 68/push 0/imm32/write -26129 # save a pointer to type-parameters-storage at type-parameters -26130 89/<- *(ebp-4) 4/r32/esp -26131 (clear-stream *(ebp-4)) -26132 # . save registers -26133 50/push-eax -26134 51/push-ecx -26135 52/push-edx -26136 53/push-ebx -26137 56/push-esi -26138 57/push-edi -26139 # esi = stmt -26140 8b/-> *(ebp+8) 6/r32/esi -26141 # edi = callee -26142 8b/-> *(ebp+0xc) 7/r32/edi -26143 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts) -26144 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -26145 89/<- %ecx 0/r32/eax -26146 # var expected/edx: (addr list var) = lookup(f->inouts) -26147 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax -26148 89/<- %edx 0/r32/eax -26149 { -26150 $check-mu-call:check-for-inouts: -26151 # if (inouts == 0) break -26152 81 7/subop/compare %ecx 0/imm32 -26153 0f 84/jump-if-= break/disp32 -26154 # if (expected == 0) error -26155 81 7/subop/compare %edx 0/imm32 -26156 0f 84/jump-if-= break/disp32 -26157 $check-mu-call:check-null-addr: -26158 # if (inouts->value->name == "0") continue -26159 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -26160 (lookup *eax *(eax+4)) # Var-name Var-name => eax -26161 (string-equal? %eax "0") # => eax -26162 3d/compare-eax-and 0/imm32/false -26163 0f 85/jump-if-!= $check-mu-call:continue-to-next-inout/disp32 -26164 $check-mu-call:check-inout-type: -26165 # var t/ebx: (addr type-tree) = inouts->value->type -26166 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -26167 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -26168 89/<- %ebx 0/r32/eax -26169 # if (inouts->is-deref?) t = t->right -26170 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -26171 { -26172 74/jump-if-= break/disp8 -26173 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -26174 89/<- %ebx 0/r32/eax -26175 # if t->right is null, t = t->left -26176 81 7/subop/compare *(ebx+0xc) 0/imm32 # Type-tree-right -26177 75/jump-if-!= break/disp8 -26178 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -26179 89/<- %ebx 0/r32/eax -26180 } -26181 # var v2/eax: (addr v) = lookup(expected->value) -26182 (lookup *edx *(edx+4)) # List-value List-value => eax -26183 # var t2/eax: (addr type-tree) = lookup(v2->type) -26184 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -26185 # if (t != t2) error -26186 (type-match? %eax %ebx *(ebp-4)) # => eax -26187 3d/compare-eax-and 0/imm32/false -26188 { -26189 0f 85/jump-if-!= break/disp32 -26190 (write-buffered *(ebp+0x14) "fn ") -26191 8b/-> *(ebp+0x10) 0/r32/eax -26192 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26193 (write-buffered *(ebp+0x14) %eax) -26194 (write-buffered *(ebp+0x14) ": call ") -26195 (lookup *edi *(edi+4)) # Function-name Function-name => eax -26196 (write-buffered *(ebp+0x14) %eax) -26197 (write-buffered *(ebp+0x14) ": type for inout '") -26198 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -26199 (lookup *eax *(eax+4)) # Var-name Var-name => eax -26200 (write-buffered *(ebp+0x14) %eax) -26201 (write-buffered *(ebp+0x14) "' is not right\n") -26202 (flush *(ebp+0x14)) -26203 (stop *(ebp+0x18) 1) -26204 } -26205 $check-mu-call:continue-to-next-inout: -26206 # inouts = lookup(inouts->next) -26207 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -26208 89/<- %ecx 0/r32/eax -26209 # expected = lookup(expected->next) -26210 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -26211 89/<- %edx 0/r32/eax -26212 # -26213 e9/jump loop/disp32 -26214 } -26215 $check-mu-call:check-inout-count: -26216 # if (inouts == expected) proceed -26217 39/compare %ecx 2/r32/edx -26218 { -26219 0f 84/jump-if-= break/disp32 -26220 # exactly one of the two is null -26221 # if (inouts == 0) error("too many inouts") -26222 { -26223 81 7/subop/compare %ecx 0/imm32 -26224 0f 84/jump-if-= break/disp32 -26225 (write-buffered *(ebp+0x14) "fn ") -26226 8b/-> *(ebp+0x10) 0/r32/eax -26227 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26228 (write-buffered *(ebp+0x14) %eax) -26229 (write-buffered *(ebp+0x14) ": call ") -26230 (lookup *edi *(edi+4)) # Function-name Function-name => eax -26231 (write-buffered *(ebp+0x14) %eax) -26232 (write-buffered *(ebp+0x14) ": too many inouts\n") -26233 (flush *(ebp+0x14)) -26234 (stop *(ebp+0x18) 1) -26235 } -26236 # if (expected == 0) error("too few inouts") -26237 { -26238 81 7/subop/compare %edx 0/imm32 -26239 0f 84/jump-if-= break/disp32 -26240 (write-buffered *(ebp+0x14) "fn ") -26241 8b/-> *(ebp+0x10) 0/r32/eax -26242 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26243 (write-buffered *(ebp+0x14) %eax) -26244 (write-buffered *(ebp+0x14) ": call ") -26245 (lookup *edi *(edi+4)) # Function-name Function-name => eax -26246 (write-buffered *(ebp+0x14) %eax) -26247 (write-buffered *(ebp+0x14) ": too few inouts\n") -26248 (flush *(ebp+0x14)) -26249 (stop *(ebp+0x18) 1) -26250 } -26251 } -26252 $check-mu-call:check-outputs: -26253 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs) -26254 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -26255 89/<- %ecx 0/r32/eax -26256 # var expected/edx: (addr list var) = lookup(f->outputs) -26257 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax -26258 89/<- %edx 0/r32/eax -26259 { -26260 $check-mu-call:check-for-outputs: -26261 # if (outputs == 0) break -26262 81 7/subop/compare %ecx 0/imm32 -26263 0f 84/jump-if-= break/disp32 -26264 # if (expected == 0) error -26265 81 7/subop/compare %edx 0/imm32 -26266 0f 84/jump-if-= break/disp32 -26267 $check-mu-call:check-output-type: -26268 # var v/eax: (addr v) = lookup(outputs->value) -26269 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -26270 # var t/ebx: (addr type-tree) = lookup(v->type) -26271 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -26272 89/<- %ebx 0/r32/eax -26273 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr -26274 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -26275 { -26276 74/jump-if-= break/disp8 -26277 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -26278 89/<- %ebx 0/r32/eax -26279 } -26280 # var v2/eax: (addr v) = lookup(expected->value) -26281 (lookup *edx *(edx+4)) # List-value List-value => eax -26282 # var t2/eax: (addr type-tree) = lookup(v2->type) -26283 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -26284 # if (t != t2) error -26285 (type-match? %eax %ebx *(ebp-4)) # => eax -26286 3d/compare-eax-and 0/imm32/false -26287 { -26288 0f 85/jump-if-!= break/disp32 -26289 (write-buffered *(ebp+0x14) "fn ") -26290 8b/-> *(ebp+0x10) 0/r32/eax -26291 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26292 (write-buffered *(ebp+0x14) %eax) -26293 (write-buffered *(ebp+0x14) ": call ") -26294 (lookup *edi *(edi+4)) # Function-name Function-name => eax -26295 (write-buffered *(ebp+0x14) %eax) -26296 (write-buffered *(ebp+0x14) ": type for output '") -26297 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -26298 (lookup *eax *(eax+4)) # Var-name Var-name => eax -26299 (write-buffered *(ebp+0x14) %eax) -26300 (write-buffered *(ebp+0x14) "' is not right\n") -26301 (flush *(ebp+0x14)) -26302 (stop *(ebp+0x18) 1) -26303 } -26304 $check-mu-call:check-output-register: -26305 # var v/eax: (addr v) = lookup(outputs->value) -26306 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -26307 # var r/ebx: (addr array byte) = lookup(v->register) -26308 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax -26309 89/<- %ebx 0/r32/eax -26310 # if (r == 0) error -26311 3d/compare-eax-and 0/imm32 -26312 { -26313 0f 85/jump-if-!= break/disp32 -26314 (write-buffered *(ebp+0x14) "fn ") -26315 8b/-> *(ebp+0x10) 0/r32/eax -26316 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26317 (write-buffered *(ebp+0x14) %eax) -26318 (write-buffered *(ebp+0x14) ": call ") -26319 (lookup *edi *(edi+4)) # Function-name Function-name => eax -26320 (write-buffered *(ebp+0x14) %eax) -26321 (write-buffered *(ebp+0x14) ": output '") -26322 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -26323 (lookup *eax *(eax+4)) # Var-name Var-name => eax -26324 (write-buffered *(ebp+0x14) %eax) -26325 (write-buffered *(ebp+0x14) "' is not in a register\n") -26326 (flush *(ebp+0x14)) -26327 (stop *(ebp+0x18) 1) -26328 } -26329 # var v2/eax: (addr v) = lookup(expected->value) -26330 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax -26331 # var r2/eax: (addr array byte) = lookup(v2->register) -26332 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax -26333 # if (r != r2) error -26334 (string-equal? %eax %ebx) # => eax -26335 3d/compare-eax-and 0/imm32/false -26336 { -26337 0f 85/jump-if-!= break/disp32 -26338 (write-buffered *(ebp+0x14) "fn ") -26339 8b/-> *(ebp+0x10) 0/r32/eax -26340 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26341 (write-buffered *(ebp+0x14) %eax) -26342 (write-buffered *(ebp+0x14) ": call ") -26343 (lookup *edi *(edi+4)) # Function-name Function-name => eax -26344 (write-buffered *(ebp+0x14) %eax) -26345 (write-buffered *(ebp+0x14) ": register for output '") -26346 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -26347 (lookup *eax *(eax+4)) # Var-name Var-name => eax -26348 (write-buffered *(ebp+0x14) %eax) -26349 (write-buffered *(ebp+0x14) "' is not right\n") -26350 (flush *(ebp+0x14)) -26351 (stop *(ebp+0x18) 1) -26352 } -26353 $check-mu-call:continue-to-next-output: -26354 # outputs = lookup(outputs->next) -26355 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -26356 89/<- %ecx 0/r32/eax -26357 # expected = lookup(expected->next) -26358 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -26359 89/<- %edx 0/r32/eax -26360 # -26361 e9/jump loop/disp32 -26362 } -26363 $check-mu-call:check-output-count: -26364 # if (outputs == expected) proceed -26365 39/compare %ecx 2/r32/edx -26366 { -26367 0f 84/jump-if-= break/disp32 -26368 # exactly one of the two is null -26369 # if (outputs == 0) error("too many outputs") -26370 { -26371 81 7/subop/compare %ecx 0/imm32 -26372 0f 84/jump-if-= break/disp32 -26373 (write-buffered *(ebp+0x14) "fn ") -26374 8b/-> *(ebp+0x10) 0/r32/eax -26375 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26376 (write-buffered *(ebp+0x14) %eax) -26377 (write-buffered *(ebp+0x14) ": call ") -26378 (lookup *edi *(edi+4)) # Function-name Function-name => eax -26379 (write-buffered *(ebp+0x14) %eax) -26380 (write-buffered *(ebp+0x14) ": too many outputs\n") -26381 (flush *(ebp+0x14)) -26382 (stop *(ebp+0x18) 1) -26383 } -26384 # if (expected == 0) error("too few outputs") -26385 { -26386 81 7/subop/compare %edx 0/imm32 -26387 0f 84/jump-if-= break/disp32 -26388 (write-buffered *(ebp+0x14) "fn ") -26389 8b/-> *(ebp+0x10) 0/r32/eax -26390 (lookup *eax *(eax+4)) # Function-name Function-name => eax -26391 (write-buffered *(ebp+0x14) %eax) -26392 (write-buffered *(ebp+0x14) ": call ") -26393 (lookup *edi *(edi+4)) # Function-name Function-name => eax -26394 (write-buffered *(ebp+0x14) %eax) -26395 (write-buffered *(ebp+0x14) ": too few outputs\n") -26396 (flush *(ebp+0x14)) -26397 (stop *(ebp+0x18) 1) -26398 } -26399 } -26400 $check-mu-call:end: -26401 # . restore registers -26402 5f/pop-to-edi -26403 5e/pop-to-esi -26404 5b/pop-to-ebx -26405 5a/pop-to-edx -26406 59/pop-to-ecx -26407 58/pop-to-eax -26408 # . reclaim locals exclusively on the stack -26409 81 0/subop/add %esp 0x70/imm32 -26410 # . epilogue -26411 89/<- %esp 5/r32/ebp -26412 5d/pop-to-ebp -26413 c3/return -26414 -26415 # like type-equal? but takes literals type parameters into account -26416 type-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean -26417 # . prologue -26418 55/push-ebp -26419 89/<- %ebp 4/r32/esp -26420 # if (call is literal and def is numberlike) return true -26421 { -26422 $type-match?:check-literal-int: -26423 (simple-mu-type? *(ebp+0xc) 0) # literal => eax -26424 3d/compare-eax-and 0/imm32/false -26425 74/jump-if-= break/disp8 -26426 (mu-numberlike-output? *(ebp+8)) # => eax -26427 3d/compare-eax-and 0/imm32/false -26428 74/jump-if-= break/disp8 -26429 b8/copy-to-eax 1/imm32/true -26430 e9/jump $type-match?:end/disp32 -26431 } -26432 # if (call is literal-string and def is string) return true -26433 { -26434 $type-match?:check-literal-string: -26435 (simple-mu-type? *(ebp+0xc) 0x10) # literal-string => eax -26436 3d/compare-eax-and 0/imm32/false -26437 74/jump-if-= break/disp8 -26438 (mu-string-type? *(ebp+8)) # => eax -26439 3d/compare-eax-and 0/imm32/false -26440 74/jump-if-= break/disp8 -26441 b8/copy-to-eax 1/imm32/true -26442 e9/jump $type-match?:end/disp32 -26443 } -26444 $type-match?:baseline: -26445 # otherwise fall back -26446 (type-component-match? *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax -26447 $type-match?:end: -26448 # . epilogue -26449 89/<- %esp 5/r32/ebp -26450 5d/pop-to-ebp -26451 c3/return -26452 -26453 type-component-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean -26454 # . prologue -26455 55/push-ebp -26456 89/<- %ebp 4/r32/esp -26457 # . save registers -26458 51/push-ecx -26459 52/push-edx -26460 53/push-ebx -26461 # ecx = def -26462 8b/-> *(ebp+8) 1/r32/ecx -26463 # edx = call -26464 8b/-> *(ebp+0xc) 2/r32/edx -26465 $type-component-match?:compare-addr: -26466 # if (def == call) return true -26467 8b/-> %ecx 0/r32/eax # Var-type -26468 39/compare %edx 0/r32/eax # Var-type -26469 b8/copy-to-eax 1/imm32/true -26470 0f 84/jump-if-= $type-component-match?:end/disp32 -26471 # if (def == 0) return false -26472 b8/copy-to-eax 0/imm32/false -26473 81 7/subop/compare %ecx 0/imm32 # Type-tree-is-atom -26474 0f 84/jump-if-= $type-component-match?:end/disp32 -26475 # if (call == 0) return false -26476 81 7/subop/compare %edx 0/imm32 # Type-tree-is-atom -26477 0f 84/jump-if-= $type-component-match?:end/disp32 -26478 # if def is a type parameter, just check in type-parameters -26479 { -26480 $type-component-match?:check-type-parameter: -26481 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -26482 74/jump-if-= break/disp8 -26483 81 7/subop/compare *(ecx+4) 0xa/imm32/type-parameter # Type-tree-value -26484 75/jump-if-!= break/disp8 -26485 $type-component-match?:type-parameter: -26486 (type-parameter-match? *(ecx+8) *(ecx+0xc) %edx *(ebp+0x10)) # => eax -26487 e9/jump $type-component-match?:end/disp32 -26488 } -26489 # if def is a list containing just a type parameter, just check in type-parameters -26490 { -26491 $type-component-match?:check-list-type-parameter: -26492 # if def is a list.. -26493 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -26494 75/jump-if-!= break/disp8 -26495 # ..that's a singleton -26496 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-left -26497 75/jump-if-!= break/disp8 -26498 # ..and whose head is a type parameter -26499 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26500 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -26501 74/jump-if-= break/disp8 -26502 81 7/subop/compare *(eax+4) 0xa/imm32/type-parameter # Type-tree-value -26503 75/jump-if-!= break/disp8 -26504 $type-component-match?:list-type-parameter: -26505 (type-parameter-match? *(eax+8) *(eax+0xc) %edx *(ebp+0x10)) # => eax -26506 e9/jump $type-component-match?:end/disp32 -26507 } -26508 $type-component-match?:compare-atom-state: -26509 # if (def->is-atom? != call->is-atom?) return false -26510 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom -26511 39/compare *edx 3/r32/ebx # Type-tree-is-atom -26512 b8/copy-to-eax 0/imm32/false -26513 0f 85/jump-if-!= $type-component-match?:end/disp32 -26514 # if def->is-atom? return (def->value == call->value) -26515 { -26516 $type-component-match?:check-atom: -26517 81 7/subop/compare %ebx 0/imm32/false -26518 74/jump-if-= break/disp8 -26519 $type-component-match?:is-atom: -26520 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value -26521 39/compare *(edx+4) 0/r32/eax # Type-tree-value -26522 0f 94/set-if-= %al -26523 25/and-eax-with 0xff/imm32 -26524 e9/jump $type-component-match?:end/disp32 -26525 } -26526 $type-component-match?:check-left: -26527 # if (!type-component-match?(def->left, call->left)) return false -26528 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26529 89/<- %ebx 0/r32/eax -26530 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -26531 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax -26532 3d/compare-eax-and 0/imm32/false -26533 74/jump-if-= $type-component-match?:end/disp8 -26534 $type-component-match?:check-right: -26535 # return type-component-match?(def->right, call->right) -26536 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -26537 89/<- %ebx 0/r32/eax -26538 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax -26539 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax -26540 $type-component-match?:end: -26541 # . restore registers -26542 5b/pop-to-ebx -26543 5a/pop-to-edx -26544 59/pop-to-ecx -26545 # . epilogue -26546 89/<- %esp 5/r32/ebp -26547 5d/pop-to-ebp -26548 c3/return -26549 -26550 type-parameter-match?: # type-parameter-name: (handle array byte), type: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean -26551 # . prologue -26552 55/push-ebp -26553 89/<- %ebp 4/r32/esp -26554 # . save registers -26555 51/push-ecx -26556 # -26557 (get-or-insert-handle *(ebp+0x14) *(ebp+8) *(ebp+0xc) 0xc) # => eax -26558 # if parameter wasn't saved, save it -26559 { -26560 81 7/subop/compare *eax 0/imm32 -26561 75/jump-if-!= break/disp8 -26562 8b/-> *(ebp+0x10) 1/r32/ecx -26563 89/<- *eax 1/r32/ecx -26564 } -26565 # -26566 (type-equal? *(ebp+0x10) *eax) # => eax -26567 $type-parameter-match?:end: -26568 # . restore registers -26569 59/pop-to-ecx -26570 # . epilogue -26571 89/<- %esp 5/r32/ebp -26572 5d/pop-to-ebp -26573 c3/return -26574 -26575 size-of: # v: (addr var) -> result/eax: int -26576 # . prologue -26577 55/push-ebp -26578 89/<- %ebp 4/r32/esp -26579 # . save registers -26580 51/push-ecx -26581 # var t/ecx: (addr type-tree) = lookup(v->type) -26582 8b/-> *(ebp+8) 1/r32/ecx -26583 #? (write-buffered Stderr "size-of ") -26584 #? (write-int32-hex-buffered Stderr %ecx) -26585 #? (write-buffered Stderr Newline) -26586 #? (write-buffered Stderr "type allocid: ") -26587 #? (write-int32-hex-buffered Stderr *(ecx+8)) -26588 #? (write-buffered Stderr Newline) -26589 #? (flush Stderr) -26590 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -26591 89/<- %ecx 0/r32/eax -26592 # if mu-array?(t) return size-of-array(t) -26593 { -26594 (mu-array? %ecx) # => eax -26595 3d/compare-eax-and 0/imm32/false -26596 74/jump-if-= break/disp8 -26597 (size-of-array %ecx) # => eax -26598 eb/jump $size-of:end/disp8 -26599 } -26600 # if mu-stream?(t) return size-of-stream(t) -26601 { -26602 (mu-stream? %ecx) # => eax -26603 3d/compare-eax-and 0/imm32/false -26604 74/jump-if-= break/disp8 -26605 (size-of-stream %ecx) # => eax -26606 eb/jump $size-of:end/disp8 -26607 } -26608 # if (!t->is-atom?) t = lookup(t->left) -26609 { -26610 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -26611 75/jump-if-!= break/disp8 -26612 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26613 89/<- %ecx 0/r32/eax -26614 } -26615 # TODO: assert t->is-atom? -26616 (size-of-type-id *(ecx+4)) # Type-tree-value => eax -26617 $size-of:end: -26618 # . restore registers -26619 59/pop-to-ecx -26620 # . epilogue -26621 89/<- %esp 5/r32/ebp -26622 5d/pop-to-ebp -26623 c3/return -26624 -26625 size-of-deref: # v: (addr var) -> result/eax: int -26626 # . prologue -26627 55/push-ebp -26628 89/<- %ebp 4/r32/esp -26629 # . save registers -26630 51/push-ecx -26631 # var t/ecx: (addr type-tree) = lookup(v->type) -26632 8b/-> *(ebp+8) 1/r32/ecx -26633 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -26634 89/<- %ecx 0/r32/eax -26635 # TODO: assert(t is an addr) -26636 # t = lookup(t->right) -26637 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -26638 89/<- %ecx 0/r32/eax -26639 # if mu-array?(t) return size-of-array(t) -26640 { -26641 (mu-array? %ecx) # => eax -26642 3d/compare-eax-and 0/imm32/false -26643 74/jump-if-= break/disp8 -26644 (size-of-array %ecx) # => eax -26645 eb/jump $size-of-deref:end/disp8 -26646 } -26647 # if mu-stream?(t) return size-of-stream(t) -26648 { -26649 (mu-stream? %ecx) # => eax -26650 3d/compare-eax-and 0/imm32/false -26651 74/jump-if-= break/disp8 -26652 (size-of-stream %ecx) # => eax -26653 eb/jump $size-of-deref:end/disp8 -26654 } -26655 # if (!t->is-atom?) t = lookup(t->left) -26656 { -26657 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -26658 75/jump-if-!= break/disp8 -26659 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26660 89/<- %ecx 0/r32/eax -26661 } -26662 # TODO: assert t->is-atom? -26663 (size-of-type-id *(ecx+4)) # Type-tree-value => eax -26664 $size-of-deref:end: -26665 # . restore registers -26666 59/pop-to-ecx -26667 # . epilogue -26668 89/<- %esp 5/r32/ebp -26669 5d/pop-to-ebp -26670 c3/return -26671 -26672 mu-array?: # t: (addr type-tree) -> result/eax: boolean -26673 # . prologue -26674 55/push-ebp -26675 89/<- %ebp 4/r32/esp -26676 # . save registers -26677 51/push-ecx -26678 # ecx = t -26679 8b/-> *(ebp+8) 1/r32/ecx -26680 # if t->is-atom?, return false -26681 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -26682 75/jump-if-!= $mu-array?:return-false/disp8 -26683 # if !t->left->is-atom?, return false -26684 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26685 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -26686 74/jump-if-= $mu-array?:return-false/disp8 -26687 # return t->left->value == array -26688 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Type-tree-value -26689 0f 94/set-if-= %al -26690 25/and-eax-with 0xff/imm32 -26691 eb/jump $mu-array?:end/disp8 -26692 $mu-array?:return-false: -26693 b8/copy-to-eax 0/imm32/false -26694 $mu-array?:end: -26695 # . restore registers -26696 59/pop-to-ecx -26697 # . epilogue -26698 89/<- %esp 5/r32/ebp -26699 5d/pop-to-ebp -26700 c3/return -26701 -26702 # size of a statically allocated array where the size is part of the type expression -26703 size-of-array: # a: (addr type-tree) -> result/eax: int -26704 # . prologue -26705 55/push-ebp -26706 89/<- %ebp 4/r32/esp -26707 # . save registers -26708 51/push-ecx -26709 52/push-edx -26710 # -26711 8b/-> *(ebp+8) 1/r32/ecx -26712 # TODO: assert that a->left is 'array' -26713 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -26714 89/<- %ecx 0/r32/eax -26715 # var elem-type/edx: type-id = a->right->left->value -26716 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26717 8b/-> *(eax+4) 2/r32/edx # Type-tree-value -26718 # TODO: assert that a->right->right->left->value == size -26719 # var array-size/ecx: int = a->right->right->left->value-size -26720 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -26721 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -26722 8b/-> *(eax+8) 1/r32/ecx # Type-tree-value-size -26723 # return 4 + array-size * size-of(elem-type) -26724 (size-of-type-id-as-array-element %edx) # => eax -26725 f7 4/subop/multiply-into-edx-eax %ecx -26726 05/add-to-eax 4/imm32 # for array size -26727 # TODO: check edx for overflow -26728 $size-of-array:end: -26729 # . restore registers -26730 5a/pop-to-edx -26731 59/pop-to-ecx -26732 # . epilogue -26733 89/<- %esp 5/r32/ebp -26734 5d/pop-to-ebp -26735 c3/return -26736 -26737 mu-stream?: # t: (addr type-tree) -> result/eax: boolean -26738 # . prologue -26739 55/push-ebp -26740 89/<- %ebp 4/r32/esp -26741 # . save registers -26742 51/push-ecx -26743 # ecx = t -26744 8b/-> *(ebp+8) 1/r32/ecx -26745 # if t->is-atom?, return false -26746 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -26747 75/jump-if-!= $mu-stream?:return-false/disp8 -26748 # if !t->left->is-atom?, return false -26749 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26750 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -26751 74/jump-if-= $mu-stream?:return-false/disp8 -26752 # return t->left->value == stream -26753 81 7/subop/compare *(eax+4) 0xb/imm32/stream-type-id # Type-tree-value -26754 0f 94/set-if-= %al -26755 25/and-eax-with 0xff/imm32 -26756 eb/jump $mu-stream?:end/disp8 -26757 $mu-stream?:return-false: -26758 b8/copy-to-eax 0/imm32/false -26759 $mu-stream?:end: -26760 # . restore registers -26761 59/pop-to-ecx -26762 # . epilogue -26763 89/<- %esp 5/r32/ebp -26764 5d/pop-to-ebp -26765 c3/return -26766 -26767 # size of a statically allocated stream where the size is part of the type expression -26768 size-of-stream: # a: (addr type-tree) -> result/eax: int -26769 # . prologue -26770 55/push-ebp -26771 89/<- %ebp 4/r32/esp -26772 # -26773 (size-of-array *(ebp+8)) # assumes we ignore the actual type name 'array' in the type -26774 05/add-to-eax 8/imm32 # for read/write pointers -26775 $size-of-stream:end: -26776 # . epilogue -26777 89/<- %esp 5/r32/ebp -26778 5d/pop-to-ebp -26779 c3/return -26780 -26781 size-of-type-id: # t: type-id -> result/eax: int -26782 # . prologue -26783 55/push-ebp -26784 89/<- %ebp 4/r32/esp -26785 # . save registers -26786 51/push-ecx -26787 # var out/ecx: (handle typeinfo) -26788 68/push 0/imm32 -26789 68/push 0/imm32 -26790 89/<- %ecx 4/r32/esp -26791 # eax = t -26792 8b/-> *(ebp+8) 0/r32/eax -26793 # if t is a literal, return 0 -26794 3d/compare-eax-and 0/imm32 -26795 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int -26796 # if t is a byte, return 4 (because we don't really support non-multiples of 4) -26797 3d/compare-eax-and 8/imm32/byte -26798 { -26799 75/jump-if-!= break/disp8 -26800 b8/copy-to-eax 4/imm32 -26801 eb/jump $size-of-type-id:end/disp8 -26802 } -26803 # if t is a handle, return 8 -26804 3d/compare-eax-and 4/imm32/handle -26805 { -26806 75/jump-if-!= break/disp8 -26807 b8/copy-to-eax 8/imm32 -26808 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int -26809 } -26810 # if t is a slice, return 8 -26811 3d/compare-eax-and 0xc/imm32/slice -26812 { -26813 75/jump-if-!= break/disp8 -26814 b8/copy-to-eax 8/imm32 -26815 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int -26816 } -26817 # if t is a user-defined type, return its size -26818 # TODO: support non-atom type -26819 (find-typeinfo %eax %ecx) -26820 { -26821 81 7/subop/compare *ecx 0/imm32 -26822 74/jump-if-= break/disp8 -26823 $size-of-type-id:user-defined: -26824 (lookup *ecx *(ecx+4)) # => eax -26825 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes -26826 eb/jump $size-of-type-id:end/disp8 -26827 } -26828 # otherwise return the word size -26829 b8/copy-to-eax 4/imm32 -26830 $size-of-type-id:end: -26831 # . reclaim locals -26832 81 0/subop/add %esp 8/imm32 -26833 # . restore registers -26834 59/pop-to-ecx -26835 # . epilogue -26836 89/<- %esp 5/r32/ebp -26837 5d/pop-to-ebp -26838 c3/return -26839 -26840 # Minor violation of our type system since it returns an addr. But we could -26841 # replace it with a handle some time. -26842 # Returns null if t is an atom. -26843 type-tail: # t: (addr type-tree) -> out/eax: (addr type-tree) -26844 # . prologue -26845 55/push-ebp -26846 89/<- %ebp 4/r32/esp -26847 # . save registers -26848 51/push-ecx -26849 # eax = 0 -26850 b8/copy-to-eax 0/imm32 -26851 # ecx = t -26852 8b/-> *(ebp+8) 1/r32/ecx -26853 $type-tail:check-atom: -26854 # if t->is-atom? return 0 -26855 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -26856 0f 85/jump-if-!= $type-tail:end/disp32 -26857 # var tail = t->right -26858 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -26859 89/<- %ecx 0/r32/eax -26860 $type-tail:check-singleton: -26861 # if (tail->right == 0) return tail->left -26862 { -26863 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-right -26864 75/jump-if-!= break/disp8 -26865 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26866 e9/jump $type-tail:end/disp32 -26867 } -26868 # if tail->right->left is an array-capacity, return tail->left -26869 { -26870 $type-tail:check-array-capacity: -26871 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -26872 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -26873 75/jump-if-!= break/disp8 -26874 $type-tail:check-array-capacity-1: -26875 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -26876 3d/compare-eax-and 0/imm32 -26877 74/jump-if-= break/disp8 -26878 $type-tail:check-array-capacity-2: -26879 (simple-mu-type? %eax 9) # array-capacity => eax -26880 3d/compare-eax-and 0/imm32/false -26881 74/jump-if-= break/disp8 -26882 $type-tail:array-capacity: -26883 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26884 eb/jump $type-tail:end/disp8 -26885 } -26886 $type-tail:check-compound-left: -26887 # if !tail->left->is-atom? return tail->left -26888 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26889 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -26890 74/jump-if-= $type-tail:end/disp8 -26891 $type-tail:return-tail: -26892 # return tail -26893 89/<- %eax 1/r32/ecx -26894 $type-tail:end: -26895 # . restore registers -26896 59/pop-to-ecx -26897 # . epilogue -26898 89/<- %esp 5/r32/ebp -26899 5d/pop-to-ebp -26900 c3/return -26901 -26902 type-equal?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean -26903 # . prologue -26904 55/push-ebp -26905 89/<- %ebp 4/r32/esp -26906 # . save registers -26907 51/push-ecx -26908 52/push-edx -26909 53/push-ebx -26910 # ecx = a -26911 8b/-> *(ebp+8) 1/r32/ecx -26912 # edx = b -26913 8b/-> *(ebp+0xc) 2/r32/edx -26914 $type-equal?:compare-addr: -26915 # if (a == b) return true -26916 8b/-> %ecx 0/r32/eax # Var-type -26917 39/compare %edx 0/r32/eax # Var-type -26918 b8/copy-to-eax 1/imm32/true -26919 0f 84/jump-if-= $type-equal?:end/disp32 -26920 $type-equal?:compare-null-a: -26921 # if (a == 0) return false -26922 b8/copy-to-eax 0/imm32/false -26923 81 7/subop/compare %ecx 0/imm32 -26924 0f 84/jump-if-= $type-equal?:end/disp32 -26925 $type-equal?:compare-null-b: -26926 # if (b == 0) return false -26927 81 7/subop/compare %edx 0/imm32 -26928 0f 84/jump-if-= $type-equal?:end/disp32 -26929 $type-equal?:compare-atom-state: -26930 # if (a->is-atom? != b->is-atom?) return false -26931 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom -26932 39/compare *edx 3/r32/ebx # Type-tree-is-atom -26933 b8/copy-to-eax 0/imm32/false -26934 0f 85/jump-if-!= $type-equal?:end/disp32 -26935 # if a->is-atom? return (a->value == b->value) -26936 { -26937 $type-equal?:check-atom: -26938 81 7/subop/compare %ebx 0/imm32/false -26939 74/jump-if-= break/disp8 -26940 $type-equal?:is-atom: -26941 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value -26942 39/compare *(edx+4) 0/r32/eax # Type-tree-value -26943 0f 94/set-if-= %al -26944 25/and-eax-with 0xff/imm32 -26945 e9/jump $type-equal?:end/disp32 -26946 } -26947 $type-equal?:check-left: -26948 # if (!type-equal?(a->left, b->left)) return false -26949 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -26950 89/<- %ebx 0/r32/eax -26951 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -26952 (type-equal? %eax %ebx) # => eax -26953 3d/compare-eax-and 0/imm32/false -26954 74/jump-if-= $type-equal?:end/disp8 -26955 $type-equal?:check-right: -26956 # return type-equal?(a->right, b->right) -26957 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -26958 89/<- %ebx 0/r32/eax -26959 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax -26960 (type-equal? %eax %ebx) # => eax -26961 $type-equal?:end: -26962 # . restore registers -26963 5b/pop-to-ebx -26964 5a/pop-to-edx -26965 59/pop-to-ecx -26966 # . epilogue -26967 89/<- %esp 5/r32/ebp -26968 5d/pop-to-ebp -26969 c3/return -26970 -26971 ####################################################### -26972 # Code-generation -26973 ####################################################### -26974 -26975 == data -26976 -26977 # Global state added to each var record when performing code-generation. -26978 Curr-local-stack-offset: # (addr int) -26979 0/imm32 -26980 -26981 == code -26982 -26983 # We may not need to pass err/ed everywhere here. I think they're relics of Mu -26984 # getting type checks later in life. -26985 # But we do need them for runtime checks, particularly array index bounds checks. -26986 # So perhaps it's not worth taking them out. They're a safety net. -26987 -26988 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) -26989 # . prologue -26990 55/push-ebp -26991 89/<- %ebp 4/r32/esp -26992 # . save registers -26993 50/push-eax -26994 # var curr/eax: (addr function) = *Program->functions -26995 (lookup *_Program-functions *_Program-functions->payload) # => eax -26996 { -26997 # if (curr == null) break -26998 3d/compare-eax-and 0/imm32 -26999 0f 84/jump-if-= break/disp32 -27000 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) -27001 # curr = lookup(curr->next) -27002 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax -27003 e9/jump loop/disp32 -27004 } -27005 $emit-subx:end: -27006 # . restore registers -27007 58/pop-to-eax -27008 # . epilogue -27009 89/<- %esp 5/r32/ebp -27010 5d/pop-to-ebp -27011 c3/return -27012 -27013 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -27014 # . prologue -27015 55/push-ebp -27016 89/<- %ebp 4/r32/esp -27017 # some preprocessing -27018 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) -27019 # . save registers -27020 50/push-eax -27021 51/push-ecx -27022 52/push-edx -27023 # initialize some global state -27024 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase -27025 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 -27026 # ecx = f -27027 8b/-> *(ebp+0xc) 1/r32/ecx -27028 # var vars/edx: (stack (addr var) 256) -27029 81 5/subop/subtract %esp 0xc00/imm32 -27030 68/push 0xc00/imm32/size -27031 68/push 0/imm32/top -27032 89/<- %edx 4/r32/esp -27033 # var name/eax: (addr array byte) = lookup(f->name) -27034 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -27035 # -27036 (write-buffered *(ebp+8) %eax) -27037 (write-buffered *(ebp+8) ":\n") -27038 (emit-subx-prologue *(ebp+8)) -27039 # var body/eax: (addr block) = lookup(f->body) -27040 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax -27041 # -27042 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -27043 (emit-subx-epilogue *(ebp+8)) -27044 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have -27045 # been cleaned up -27046 $emit-subx-function:end: -27047 # . reclaim locals -27048 81 0/subop/add %esp 0xc08/imm32 -27049 # . restore registers -27050 5a/pop-to-edx -27051 59/pop-to-ecx -27052 58/pop-to-eax -27053 # . epilogue -27054 89/<- %esp 5/r32/ebp -27055 5d/pop-to-ebp -27056 c3/return -27057 -27058 populate-mu-type-offsets-in-inouts: # f: (addr function) -27059 # . prologue -27060 55/push-ebp -27061 89/<- %ebp 4/r32/esp -27062 # . save registers -27063 50/push-eax -27064 51/push-ecx -27065 52/push-edx -27066 53/push-ebx -27067 57/push-edi -27068 # var next-offset/edx: int = 8 -27069 ba/copy-to-edx 8/imm32 -27070 # var curr/ecx: (addr list var) = lookup(f->inouts) -27071 8b/-> *(ebp+8) 1/r32/ecx -27072 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax -27073 89/<- %ecx 0/r32/eax -27074 { -27075 $populate-mu-type-offsets-in-inouts:loop: -27076 81 7/subop/compare %ecx 0/imm32 -27077 74/jump-if-= break/disp8 -27078 # var v/ebx: (addr var) = lookup(curr->value) -27079 (lookup *ecx *(ecx+4)) # List-value List-value => eax -27080 89/<- %ebx 0/r32/eax -27081 #? (lookup *ebx *(ebx+4)) -27082 #? (write-buffered Stderr "setting offset of fn inout ") -27083 #? (write-buffered Stderr %eax) -27084 #? (write-buffered Stderr "@") -27085 #? (write-int32-hex-buffered Stderr %ebx) -27086 #? (write-buffered Stderr " to ") -27087 #? (write-int32-hex-buffered Stderr %edx) -27088 #? (write-buffered Stderr Newline) -27089 #? (flush Stderr) -27090 # v->offset = next-offset -27091 89/<- *(ebx+0x14) 2/r32/edx # Var-offset -27092 # next-offset += size-of(v) -27093 (size-of %ebx) # => eax -27094 01/add-to %edx 0/r32/eax -27095 # curr = lookup(curr->next) -27096 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -27097 89/<- %ecx 0/r32/eax -27098 # -27099 eb/jump loop/disp8 -27100 } -27101 $populate-mu-type-offsets-in-inouts:end: -27102 # . restore registers -27103 5f/pop-to-edi -27104 5b/pop-to-ebx -27105 5a/pop-to-edx -27106 59/pop-to-ecx -27107 58/pop-to-eax -27108 # . epilogue -27109 89/<- %esp 5/r32/ebp -27110 5d/pop-to-ebp -27111 c3/return -27112 -27113 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (addr list stmt), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -27114 # . prologue -27115 55/push-ebp -27116 89/<- %ebp 4/r32/esp -27117 # . save registers -27118 50/push-eax -27119 51/push-ecx -27120 53/push-ebx -27121 56/push-esi -27122 # esi = stmts -27123 8b/-> *(ebp+0xc) 6/r32/esi -27124 # -27125 { -27126 $emit-subx-stmt-list:loop: -27127 81 7/subop/compare %esi 0/imm32 -27128 0f 84/jump-if-= break/disp32 -27129 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) -27130 (lookup *esi *(esi+4)) # List-value List-value => eax -27131 89/<- %ecx 0/r32/eax -27132 { -27133 $emit-subx-stmt-list:check-for-block: -27134 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -27135 75/jump-if-!= break/disp8 -27136 $emit-subx-stmt-list:block: -27137 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -27138 } -27139 { -27140 $emit-subx-stmt-list:check-for-stmt: -27141 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -27142 0f 85/jump-if-!= break/disp32 -27143 $emit-subx-stmt-list:stmt1: -27144 { -27145 (mu-branch? %ecx) # => eax -27146 3d/compare-eax-and 0/imm32/false -27147 0f 84/jump-if-= break/disp32 -27148 $emit-subx-stmt-list:branch-stmt: -27149 +-- 25 lines: # unconditional return ---------------------------------------------------------------------------------------------------------------------------------------------------- -27174 +-- 27 lines: # unconditional loops ----------------------------------------------------------------------------------------------------------------------------------------------------- -27201 +-- 16 lines: # unconditional breaks ---------------------------------------------------------------------------------------------------------------------------------------------------- -27217 +-- 38 lines: # simple conditional branches without a target ---------------------------------------------------------------------------------------------------------------------------- -27255 +-- 19 lines: # conditional branches with an explicit target ---------------------------------------------------------------------------------------------------------------------------- -27274 } -27275 $emit-subx-stmt-list:1-to-1: -27276 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -27277 e9/jump $emit-subx-stmt-list:continue/disp32 -27278 } -27279 { -27280 $emit-subx-stmt-list:check-for-var-def: -27281 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag -27282 75/jump-if-!= break/disp8 -27283 $emit-subx-stmt-list:var-def: -27284 (emit-subx-var-def *(ebp+8) %ecx *(ebp+0x18) *(ebp+0x1c)) -27285 (push *(ebp+0x10) *(ecx+4)) # Vardef-var -27286 (push *(ebp+0x10) *(ecx+8)) # Vardef-var -27287 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack -27288 # -27289 eb/jump $emit-subx-stmt-list:continue/disp8 -27290 } -27291 { -27292 $emit-subx-stmt-list:check-for-reg-var-def: -27293 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag -27294 0f 85/jump-if-!= break/disp32 -27295 $emit-subx-stmt-list:reg-var-def: -27296 # TODO: ensure that there's exactly one output -27297 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -27298 # emit the instruction as usual -27299 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -27300 # -27301 eb/jump $emit-subx-stmt-list:continue/disp8 -27302 } -27303 $emit-subx-stmt-list:continue: -27304 # TODO: raise an error on unrecognized Stmt-tag -27305 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax -27306 89/<- %esi 0/r32/eax -27307 e9/jump loop/disp32 -27308 } -27309 $emit-subx-stmt-list:emit-cleanup: -27310 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) -27311 $emit-subx-stmt-list:clean-up: -27312 (clean-up-stack-offset-state *(ebp+0x10) *Curr-block-depth) -27313 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14)) -27314 $emit-subx-stmt-list:end: -27315 # . restore registers -27316 5e/pop-to-esi -27317 5b/pop-to-ebx -27318 59/pop-to-ecx -27319 58/pop-to-eax -27320 # . epilogue -27321 89/<- %esp 5/r32/ebp -27322 5d/pop-to-ebp -27323 c3/return -27324 -27325 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. -27326 push-output-and-maybe-emit-spill: # out: (addr buffered-file), stmt: (addr reg-var-def), vars: (addr stack (handle var)), later-stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -27327 # . prologue -27328 55/push-ebp -27329 89/<- %ebp 4/r32/esp -27330 # . save registers -27331 50/push-eax -27332 51/push-ecx -27333 52/push-edx -27334 # ecx = stmt -27335 8b/-> *(ebp+0xc) 1/r32/ecx -27336 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) -27337 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax -27338 # TODO: assert !sv->is-deref? -27339 # var v/ecx: (addr var) = lookup(sv->value) -27340 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -27341 89/<- %ecx 0/r32/eax -27342 # v->block-depth = *Curr-block-depth -27343 8b/-> *Curr-block-depth 0/r32/eax -27344 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -27345 #? (write-buffered Stderr "var ") -27346 #? (lookup *ecx *(ecx+4)) -27347 #? (write-buffered Stderr %eax) -27348 #? (write-buffered Stderr " at depth ") -27349 #? (write-int32-hex-buffered Stderr *(ecx+0x10)) -27350 #? (write-buffered Stderr Newline) -27351 #? (flush Stderr) -27352 # ensure that v is in a register -27353 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -27354 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 -27355 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn) -27356 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax -27357 89/<- %edx 0/r32/eax -27358 3d/compare-eax-and 0/imm32/false -27359 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 -27360 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax -27361 89/<- %edx 0/r32/eax -27362 # check emit-spill? -27363 3d/compare-eax-and 0/imm32/false -27364 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 -27365 # TODO: assert(size-of(output) == 4) -27366 # *Curr-local-stack-offset -= 4 -27367 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 -27368 # emit spill -27369 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -27370 (emit-push-register *(ebp+8) %eax) -27371 $push-output-and-maybe-emit-spill:push: -27372 8b/-> *(ebp+0xc) 1/r32/ecx -27373 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax -27374 # push(vars, {sv->value, emit-spill?}) -27375 (push *(ebp+0x10) *eax) # Stmt-var-value -27376 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value -27377 (push *(ebp+0x10) %edx) -27378 $push-output-and-maybe-emit-spill:end: -27379 # . restore registers -27380 5a/pop-to-edx -27381 59/pop-to-ecx -27382 58/pop-to-eax -27383 # . epilogue -27384 89/<- %esp 5/r32/ebp -27385 5d/pop-to-ebp -27386 c3/return -27387 -27388 $push-output-and-maybe-emit-spill:abort: -27389 # error("var '" var->name "' initialized from an instruction must live in a register\n") -27390 (write-buffered *(ebp+0x1c) "var '") -27391 (write-buffered *(ebp+0x1c) *eax) # Var-name -27392 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n") -27393 (flush *(ebp+0x1c)) -27394 (stop *(ebp+0x20) 1) -27395 # never gets here -27396 -27397 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) -27398 # . prologue -27399 55/push-ebp -27400 89/<- %ebp 4/r32/esp -27401 # . save registers -27402 50/push-eax -27403 51/push-ecx -27404 # ecx = stmt -27405 8b/-> *(ebp+0xc) 1/r32/ecx -27406 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name -27407 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -27408 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -27409 (lookup *eax *(eax+4)) # Var-name Var-name => eax -27410 # clean up until target block -27411 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) -27412 # emit jump to target block -27413 (emit-indent *(ebp+8) *Curr-block-depth) -27414 (write-buffered *(ebp+8) "e9/jump ") -27415 (write-buffered *(ebp+8) %eax) -27416 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -27417 (string-starts-with? %eax "break") -27418 3d/compare-eax-and 0/imm32/false -27419 { -27420 74/jump-if-= break/disp8 -27421 (write-buffered *(ebp+8) ":break/disp32\n") -27422 eb/jump $emit-subx-cleanup-and-unconditional-nonlocal-branch:end/disp8 -27423 } -27424 (write-buffered *(ebp+8) ":loop/disp32\n") -27425 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: -27426 # . restore registers -27427 59/pop-to-ecx -27428 58/pop-to-eax -27429 # . epilogue -27430 89/<- %esp 5/r32/ebp -27431 5d/pop-to-ebp -27432 c3/return -27433 -27434 emit-outputs: # out: (addr buffered-file), return-stmt: (addr stmt1), fn: (addr function) -27435 # . prologue -27436 55/push-ebp -27437 89/<- %ebp 4/r32/esp -27438 # . save registers -27439 50/push-eax -27440 51/push-ecx -27441 56/push-esi -27442 57/push-edi -27443 # var curr-inout/esi: (addr stmt-var) = return-stmt->inouts -27444 8b/-> *(ebp+0xc) 0/r32/eax -27445 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -27446 89/<- %esi 0/r32/eax -27447 # var curr-output/edi: (addr list var) = fn->outputs -27448 8b/-> *(ebp+0x10) 0/r32/eax -27449 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax -27450 89/<- %edi 0/r32/eax -27451 { -27452 $emit-outputs:loop: -27453 81 7/subop/compare %esi 0/imm32 -27454 0f 84/jump-if-= break/disp32 -27455 # emit copy to output register -27456 # var curr-output-register/ecx: (addr array byte) = curr-output->value->register -27457 (lookup *edi *(edi+4)) # List-value List-value => eax -27458 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -27459 89/<- %ecx 0/r32/eax -27460 # if curr-output-register starts with "x", emit a floating-point copy -27461 8a/copy-byte *(ecx+4) 0/r32/AL -27462 25/and-eax-with 0xff/imm32 -27463 3d/compare-eax-and 0x78/imm32/x -27464 { -27465 75/jump-if-!= break/disp8 -27466 (emit-float-output *(ebp+8) %esi %ecx) -27467 eb/jump $emit-outputs:continue/disp8 -27468 } -27469 # otherwise emit an int copy -27470 (emit-int-output *(ebp+8) %esi %ecx) -27471 $emit-outputs:continue: -27472 # curr-inout = curr-inout->next -27473 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -27474 89/<- %esi 0/r32/eax -27475 # curr-output = curr-output->next -27476 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -27477 89/<- %edi 0/r32/eax -27478 # -27479 e9/jump loop/disp32 -27480 } -27481 $emit-outputs:end: -27482 # . restore registers -27483 5f/pop-to-edi -27484 5e/pop-to-esi -27485 59/pop-to-ecx -27486 58/pop-to-eax -27487 # . epilogue -27488 89/<- %esp 5/r32/ebp -27489 5d/pop-to-ebp -27490 c3/return -27491 -27492 emit-int-output: # out: (addr buffered-file), return-var: (addr stmt-var), dest-reg: (addr array byte) -27493 # . prologue -27494 55/push-ebp -27495 89/<- %ebp 4/r32/esp -27496 # . save registers -27497 50/push-eax -27498 51/push-ecx -27499 # ecx = return-var->value -27500 8b/-> *(ebp+0xc) 0/r32/eax -27501 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -27502 89/<- %ecx 0/r32/eax -27503 # if curr-var is a literal, emit copy of a literal to the output -27504 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -27505 (simple-mu-type? %eax 0) # literal => eax -27506 { -27507 3d/compare-eax-and 0/imm32/false -27508 0f 84/jump-if-= break/disp32 -27509 (emit-indent *(ebp+8) *Curr-block-depth) -27510 (write-buffered *(ebp+8) "c7 0/subop/copy %") -27511 (write-buffered *(ebp+8) *(ebp+0x10)) -27512 (write-buffered *(ebp+8) " ") -27513 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -27514 (write-buffered *(ebp+8) %eax) -27515 (write-buffered *(ebp+8) "/imm32\n") -27516 e9/jump $emit-int-output:end/disp32 -27517 } -27518 # otherwise emit an integer copy -27519 (emit-indent *(ebp+8) *Curr-block-depth) -27520 (write-buffered *(ebp+8) "8b/->") -27521 (emit-subx-var-as-rm32 *(ebp+8) *(ebp+0xc)) -27522 (write-buffered *(ebp+8) " ") -27523 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax -27524 (write-int32-hex-buffered *(ebp+8) *eax) -27525 (write-buffered *(ebp+8) "/r32\n") -27526 $emit-int-output:end: -27527 # . restore registers -27528 59/pop-to-ecx -27529 58/pop-to-eax -27530 # . epilogue -27531 89/<- %esp 5/r32/ebp -27532 5d/pop-to-ebp -27533 c3/return -27534 -27535 emit-float-output: # out: (addr buffered-file), return-var: (addr stmt-var), dest-reg: (addr array byte) -27536 # . prologue -27537 55/push-ebp -27538 89/<- %ebp 4/r32/esp -27539 # . save registers -27540 50/push-eax -27541 # -27542 (emit-indent *(ebp+8) *Curr-block-depth) -27543 (write-buffered *(ebp+8) "f3 0f 10/->") -27544 (emit-subx-var-as-rm32 *(ebp+8) *(ebp+0xc)) -27545 (write-buffered *(ebp+8) " ") -27546 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax -27547 (write-int32-hex-buffered *(ebp+8) *eax) -27548 (write-buffered *(ebp+8) "/x32\n") -27549 $emit-float-output:end: -27550 # . restore registers -27551 58/pop-to-eax -27552 # . epilogue -27553 89/<- %esp 5/r32/ebp -27554 5d/pop-to-ebp -27555 c3/return -27556 -27557 mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean -27558 # . prologue -27559 55/push-ebp -27560 89/<- %ebp 4/r32/esp -27561 # . save registers -27562 51/push-ecx -27563 # ecx = lookup(stmt->operation) -27564 8b/-> *(ebp+8) 1/r32/ecx -27565 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -27566 89/<- %ecx 0/r32/eax -27567 # if (stmt->operation starts with "loop") return true -27568 (string-starts-with? %ecx "loop") # => eax -27569 3d/compare-eax-and 0/imm32/false -27570 75/jump-if-not-equal $mu-branch?:end/disp8 -27571 # if (stmt->operation starts with "break") return true -27572 (string-starts-with? %ecx "break") # => eax -27573 3d/compare-eax-and 0/imm32/false -27574 75/jump-if-not-equal $mu-branch?:end/disp8 -27575 # otherwise return (stmt->operation starts with "return") -27576 (string-starts-with? %ecx "return") # => eax -27577 $mu-branch?:end: -27578 # . restore registers -27579 59/pop-to-ecx -27580 # . epilogue -27581 89/<- %esp 5/r32/ebp -27582 5d/pop-to-ebp -27583 c3/return -27584 -27585 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) -27586 # . prologue -27587 55/push-ebp -27588 89/<- %ebp 4/r32/esp -27589 # . save registers -27590 50/push-eax -27591 # eax = stmt -27592 8b/-> *(ebp+0xc) 0/r32/eax -27593 # -27594 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -27595 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) -27596 (emit-indent *(ebp+8) *Curr-block-depth) -27597 (lookup *eax *(eax+4)) # => eax -27598 (write-buffered *(ebp+8) %eax) -27599 (write-buffered *(ebp+8) " break/disp32\n") -27600 $emit-reverse-break:end: -27601 # . restore registers -27602 58/pop-to-eax -27603 # . epilogue -27604 89/<- %esp 5/r32/ebp -27605 5d/pop-to-ebp -27606 c3/return -27607 -27608 == data -27609 -27610 # Table from Mu branch instructions to the reverse SubX opcodes for them. -27611 Reverse-branch: # (table (handle array byte) (handle array byte)) -27612 # a table is a stream -27613 0x240/imm32/write -27614 0/imm32/read -27615 0x240/imm32/size -27616 # data -27617 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 -27618 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 -27619 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 -27620 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 -27621 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 -27622 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 -27623 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 -27624 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 -27625 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_8f_jump_label/imm32 -27626 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_8f_jump_label/imm32 -27627 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 -27628 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 -27629 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -27630 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -27631 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -27632 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -27633 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -27634 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -27635 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -27636 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -27637 0x11/imm32/alloc-id _string-break-if-float</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -27638 0x11/imm32/alloc-id _string-loop-if-float</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -27639 0x11/imm32/alloc-id _string-break-if-float>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -27640 0x11/imm32/alloc-id _string-loop-if-float>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -27641 0x11/imm32/alloc-id _string-break-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -27642 0x11/imm32/alloc-id _string-loop-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -27643 0x11/imm32/alloc-id _string-break-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -27644 0x11/imm32/alloc-id _string-loop-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -27645 0x11/imm32/alloc-id _string-break-if-carry/imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -27646 0x11/imm32/alloc-id _string-loop-if-carry/imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -27647 0x11/imm32/alloc-id _string-break-if-not-carry/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -27648 0x11/imm32/alloc-id _string-loop-if-not-carry/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -27649 0x11/imm32/alloc-id _string-break-if-overflow/imm32 0x11/imm32/alloc-id _string_0f_81_jump_label/imm32 -27650 0x11/imm32/alloc-id _string-loop-if-overflow/imm32 0x11/imm32/alloc-id _string_0f_81_jump_label/imm32 -27651 0x11/imm32/alloc-id _string-break-if-not-overflow/imm32 0x11/imm32/alloc-id _string_0f_80_jump_label/imm32 -27652 0x11/imm32/alloc-id _string-loop-if-not-overflow/imm32 0x11/imm32/alloc-id _string_0f_80_jump_label/imm32 -27653 -27654 == code -27655 -27656 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) -27657 # . prologue -27658 55/push-ebp -27659 89/<- %ebp 4/r32/esp -27660 # . save registers -27661 50/push-eax -27662 51/push-ecx -27663 52/push-edx -27664 53/push-ebx -27665 56/push-esi -27666 # ecx = vars -27667 8b/-> *(ebp+0xc) 1/r32/ecx -27668 # var eax: int = vars->top -27669 8b/-> *ecx 0/r32/eax -27670 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -27671 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -27672 # var min/ecx: (addr handle var) = vars->data -27673 8d/copy-address *(ecx+8) 1/r32/ecx -27674 # edx = depth -27675 8b/-> *(ebp+0x10) 2/r32/edx -27676 { -27677 $emit-unconditional-jump-to-depth:loop: -27678 # if (curr < min) break -27679 39/compare %esi 1/r32/ecx -27680 0f 82/jump-if-addr< break/disp32 -27681 # var v/ebx: (addr var) = lookup(*curr) -27682 (lookup *esi *(esi+4)) # => eax -27683 89/<- %ebx 0/r32/eax -27684 # if (v->block-depth < until-block-depth) break -27685 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -27686 0f 8c/jump-if-< break/disp32 -27687 { -27688 $emit-unconditional-jump-to-depth:check: -27689 # if v->block-depth != until-block-depth, continue -27690 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -27691 0f 85/jump-if-!= break/disp32 -27692 $emit-unconditional-jump-to-depth:depth-found: -27693 # if v is not a literal, continue -27694 (size-of %ebx) # => eax -27695 3d/compare-eax-and 0/imm32 -27696 0f 85/jump-if-!= break/disp32 -27697 $emit-unconditional-jump-to-depth:label-found: -27698 # emit unconditional jump, then return -27699 (emit-indent *(ebp+8) *Curr-block-depth) -27700 (write-buffered *(ebp+8) "e9/jump ") -27701 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -27702 (write-buffered *(ebp+8) %eax) -27703 (write-buffered *(ebp+8) ":") -27704 (write-buffered *(ebp+8) *(ebp+0x14)) -27705 (write-buffered *(ebp+8) "/disp32\n") -27706 eb/jump $emit-unconditional-jump-to-depth:end/disp8 -27707 } -27708 # curr -= 12 -27709 81 5/subop/subtract %esi 0xc/imm32 -27710 e9/jump loop/disp32 -27711 } -27712 # TODO: error if no label at 'depth' was found -27713 $emit-unconditional-jump-to-depth:end: -27714 # . restore registers -27715 5e/pop-to-esi -27716 5b/pop-to-ebx -27717 5a/pop-to-edx -27718 59/pop-to-ecx -27719 58/pop-to-eax -27720 # . epilogue -27721 89/<- %esp 5/r32/ebp -27722 5d/pop-to-ebp -27723 c3/return -27724 -27725 # emit clean-up code for 'vars' until some block depth -27726 # doesn't actually modify 'vars' so we need traverse manually inside the stack -27727 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int -27728 # . prologue -27729 55/push-ebp -27730 89/<- %ebp 4/r32/esp -27731 # . save registers -27732 50/push-eax -27733 51/push-ecx -27734 52/push-edx -27735 53/push-ebx -27736 56/push-esi -27737 #? (write-buffered Stderr "--- cleanup\n") -27738 #? (flush Stderr) -27739 # ecx = vars -27740 8b/-> *(ebp+0xc) 1/r32/ecx -27741 # var esi: int = vars->top -27742 8b/-> *ecx 6/r32/esi -27743 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -27744 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -27745 # var min/ecx: (addr handle var) = vars->data -27746 81 0/subop/add %ecx 8/imm32 -27747 # edx = until-block-depth -27748 8b/-> *(ebp+0x10) 2/r32/edx -27749 { -27750 $emit-cleanup-code-until-depth:loop: -27751 # if (curr < min) break -27752 39/compare %esi 1/r32/ecx -27753 0f 82/jump-if-addr< break/disp32 -27754 # var v/ebx: (addr var) = lookup(*curr) -27755 (lookup *esi *(esi+4)) # => eax -27756 89/<- %ebx 0/r32/eax -27757 #? (lookup *ebx *(ebx+4)) # Var-name -27758 #? (write-buffered Stderr "var ") -27759 #? (write-buffered Stderr %eax) -27760 #? (write-buffered Stderr Newline) -27761 #? (flush Stderr) -27762 # if (v->block-depth < until-block-depth) break -27763 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -27764 0f 8c/jump-if-< break/disp32 -27765 # if v is in a register -27766 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -27767 { -27768 0f 84/jump-if-= break/disp32 -27769 { -27770 $emit-cleanup-code-until-depth:check-for-previous-spill: -27771 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled -27772 3d/compare-eax-and 0/imm32/false -27773 74/jump-if-= break/disp8 -27774 $emit-cleanup-code-until-depth:reclaim-var-in-register: -27775 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -27776 (emit-pop-register *(ebp+8) %eax) -27777 } -27778 eb/jump $emit-cleanup-code-until-depth:continue/disp8 -27779 } -27780 # otherwise v is on the stack -27781 { -27782 75/jump-if-!= break/disp8 -27783 $emit-cleanup-code-until-depth:var-on-stack: -27784 (size-of %ebx) # => eax -27785 # don't emit code for labels -27786 3d/compare-eax-and 0/imm32 -27787 74/jump-if-= break/disp8 -27788 $emit-cleanup-code-until-depth:reclaim-var-on-stack: -27789 (emit-indent *(ebp+8) *Curr-block-depth) -27790 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -27791 (write-int32-hex-buffered *(ebp+8) %eax) -27792 (write-buffered *(ebp+8) "/imm32\n") -27793 } -27794 $emit-cleanup-code-until-depth:continue: -27795 # curr -= 12 -27796 81 5/subop/subtract %esi 0xc/imm32 -27797 e9/jump loop/disp32 -27798 } -27799 $emit-cleanup-code-until-depth:end: -27800 # . restore registers -27801 5e/pop-to-esi -27802 5b/pop-to-ebx -27803 5a/pop-to-edx -27804 59/pop-to-ecx -27805 58/pop-to-eax -27806 # . epilogue -27807 89/<- %esp 5/r32/ebp -27808 5d/pop-to-ebp -27809 c3/return -27810 -27811 # emit clean-up code for 'vars' that don't conflict with output registers -27812 # doesn't actually modify 'vars' so we need traverse manually inside the stack -27813 emit-cleanup-code-for-non-outputs: # out: (addr buffered-file), vars: (addr stack live-var), fn: (addr function) -27814 # . prologue -27815 55/push-ebp -27816 89/<- %ebp 4/r32/esp -27817 # . save registers -27818 50/push-eax -27819 51/push-ecx -27820 52/push-edx -27821 53/push-ebx -27822 56/push-esi -27823 57/push-edi -27824 # ecx = vars -27825 8b/-> *(ebp+0xc) 1/r32/ecx -27826 # var esi: int = vars->top -27827 8b/-> *ecx 6/r32/esi -27828 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -27829 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -27830 # var min/ecx: (addr handle var) = vars->data -27831 81 0/subop/add %ecx 8/imm32 -27832 { -27833 $emit-cleanup-code-for-non-outputs:loop: -27834 # if (curr < min) break -27835 39/compare %esi 1/r32/ecx -27836 0f 82/jump-if-addr< break/disp32 -27837 # var v/ebx: (addr var) = lookup(*curr) -27838 (lookup *esi *(esi+4)) # => eax -27839 89/<- %ebx 0/r32/eax -27840 # if v is in a register -27841 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -27842 { -27843 0f 84/jump-if-= break/disp32 -27844 { -27845 $emit-cleanup-code-for-non-outputs:check-for-previous-spill: -27846 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled -27847 3d/compare-eax-and 0/imm32/false -27848 0f 84/jump-if-= break/disp32 -27849 $emit-cleanup-code-for-non-outputs:reclaim-var-in-register: -27850 # var reg/edi: (addr array name) = v->register -27851 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -27852 89/<- %edi 0/r32/eax -27853 # if reg is not in function outputs, emit a pop -27854 (reg-in-function-outputs? *(ebp+0x10) %edi) # => eax -27855 3d/compare-eax-and 0/imm32/false -27856 { -27857 75/jump-if-!= break/disp8 -27858 (emit-pop-register *(ebp+8) %edi) -27859 eb/jump $emit-cleanup-code-for-non-outputs:reclaim-var-in-register-done/disp8 -27860 } -27861 # otherwise just drop it from the stack -27862 (emit-indent *(ebp+8) *Curr-block-depth) -27863 (write-buffered *(ebp+8) "81 0/subop/add %esp 4/imm32\n") -27864 } -27865 $emit-cleanup-code-for-non-outputs:reclaim-var-in-register-done: -27866 eb/jump $emit-cleanup-code-for-non-outputs:continue/disp8 -27867 } -27868 # otherwise v is on the stack -27869 { -27870 75/jump-if-!= break/disp8 -27871 $emit-cleanup-code-for-non-outputs:var-on-stack: -27872 (size-of %ebx) # => eax -27873 # don't emit code for labels -27874 3d/compare-eax-and 0/imm32 -27875 74/jump-if-= break/disp8 -27876 $emit-cleanup-code-for-non-outputs:reclaim-var-on-stack: -27877 (emit-indent *(ebp+8) *Curr-block-depth) -27878 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -27879 (write-int32-hex-buffered *(ebp+8) %eax) -27880 (write-buffered *(ebp+8) "/imm32\n") -27881 } -27882 $emit-cleanup-code-for-non-outputs:continue: -27883 # curr -= 12 -27884 81 5/subop/subtract %esi 0xc/imm32 -27885 e9/jump loop/disp32 -27886 } -27887 $emit-cleanup-code-for-non-outputs:end: -27888 # . restore registers -27889 5f/pop-to-edi -27890 5e/pop-to-esi -27891 5b/pop-to-ebx -27892 5a/pop-to-edx -27893 59/pop-to-ecx -27894 58/pop-to-eax -27895 # . epilogue -27896 89/<- %esp 5/r32/ebp -27897 5d/pop-to-ebp -27898 c3/return -27899 -27900 emit-push-register: # out: (addr buffered-file), reg: (addr array byte) -27901 # . prologue -27902 55/push-ebp -27903 89/<- %ebp 4/r32/esp -27904 # eax = reg -27905 8b/-> *(ebp+0xc) 0/r32/eax -27906 # var prefix/eax: byte = reg->data[0] -27907 8a/copy-byte *(eax+4) 0/r32/AL -27908 25/and-eax-with 0xff/imm32 -27909 # if (prefix == 'x') push xmm register -27910 { -27911 3d/compare-eax-and 0x78/imm32/x -27912 0f 85/jump-if-!= break/disp32 -27913 # TODO validate register -27914 (emit-indent *(ebp+8) *Curr-block-depth) -27915 (write-buffered *(ebp+8) "81 5/subop/subtract %esp 4/imm32\n") -27916 (emit-indent *(ebp+8) *Curr-block-depth) -27917 (write-buffered *(ebp+8) "f3 0f 11/<- *esp ") -27918 # var prefix/eax: byte = reg->data[3] -27919 8b/-> *(ebp+0xc) 0/r32/eax -27920 8a/copy-byte *(eax+7) 0/r32/AL -27921 25/and-eax-with 0xff/imm32 -27922 (write-byte-buffered *(ebp+8) %eax) -27923 (write-buffered *(ebp+8) "/x32\n") -27924 e9/jump $emit-push-register:end/disp32 -27925 } -27926 # otherwise push gp register -27927 (emit-indent *(ebp+8) *Curr-block-depth) -27928 (write-buffered *(ebp+8) "ff 6/subop/push %") -27929 (write-buffered *(ebp+8) *(ebp+0xc)) -27930 (write-buffered *(ebp+8) Newline) -27931 $emit-push-register:end: -27932 # . epilogue -27933 89/<- %esp 5/r32/ebp -27934 5d/pop-to-ebp -27935 c3/return -27936 -27937 emit-pop-register: # out: (addr buffered-file), reg: (addr array byte) -27938 # . prologue -27939 55/push-ebp -27940 89/<- %ebp 4/r32/esp -27941 # . save registers -27942 50/push-eax -27943 # eax = reg -27944 8b/-> *(ebp+0xc) 0/r32/eax -27945 # var prefix/eax: byte = reg->data[0] -27946 8a/copy-byte *(eax+4) 0/r32/AL -27947 25/and-eax-with 0xff/imm32 -27948 # if (prefix == 'x') pop to xmm register -27949 { -27950 3d/compare-eax-and 0x78/imm32/x -27951 0f 85/jump-if-!= break/disp32 -27952 # TODO validate register -27953 (emit-indent *(ebp+8) *Curr-block-depth) -27954 (write-buffered *(ebp+8) "f3 0f 10/-> *esp ") -27955 # var prefix/eax: byte = reg->data[3] -27956 8b/-> *(ebp+0xc) 0/r32/eax -27957 8a/copy-byte *(eax+7) 0/r32/AL -27958 25/and-eax-with 0xff/imm32 -27959 (write-byte-buffered *(ebp+8) %eax) -27960 (write-buffered *(ebp+8) "/x32\n") -27961 (emit-indent *(ebp+8) *Curr-block-depth) -27962 (write-buffered *(ebp+8) "81 0/subop/add %esp 4/imm32\n") -27963 e9/jump $emit-pop-register:end/disp32 -27964 } -27965 # otherwise pop to gp register -27966 (emit-indent *(ebp+8) *Curr-block-depth) -27967 (write-buffered *(ebp+8) "8f 0/subop/pop %") -27968 (write-buffered *(ebp+8) *(ebp+0xc)) -27969 (write-buffered *(ebp+8) Newline) -27970 $emit-pop-register:end: -27971 # . restore registers -27972 58/pop-to-eax -27973 # . epilogue -27974 89/<- %esp 5/r32/ebp -27975 5d/pop-to-ebp -27976 c3/return -27977 -27978 # emit clean-up code for 'vars' until a given label is encountered -27979 # doesn't actually modify 'vars' so we need traverse manually inside the stack -27980 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) -27981 # . prologue -27982 55/push-ebp -27983 89/<- %ebp 4/r32/esp -27984 # . save registers -27985 50/push-eax -27986 51/push-ecx -27987 52/push-edx -27988 53/push-ebx -27989 # ecx = vars -27990 8b/-> *(ebp+0xc) 1/r32/ecx -27991 # var eax: int = vars->top -27992 8b/-> *ecx 0/r32/eax -27993 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] -27994 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size -27995 # var min/ecx: (addr handle var) = vars->data -27996 81 0/subop/add %ecx 8/imm32 -27997 { -27998 $emit-cleanup-code-until-target:loop: -27999 # if (curr < min) break -28000 39/compare %edx 1/r32/ecx -28001 0f 82/jump-if-addr< break/disp32 -28002 # var v/ebx: (handle var) = lookup(*curr) -28003 (lookup *edx *(edx+4)) # => eax -28004 89/<- %ebx 0/r32/eax -28005 # if (v->name == until-block-label) break -28006 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -28007 (string-equal? %eax *(ebp+0x10)) # => eax -28008 3d/compare-eax-and 0/imm32/false -28009 0f 85/jump-if-!= break/disp32 -28010 # if v is in a register -28011 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -28012 { -28013 0f 84/jump-if-= break/disp32 -28014 { -28015 $emit-cleanup-code-until-target:check-for-previous-spill: -28016 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled -28017 3d/compare-eax-and 0/imm32/false -28018 74/jump-if-= break/disp8 -28019 $emit-cleanup-code-until-target:reclaim-var-in-register: -28020 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -28021 (emit-pop-register *(ebp+8) %eax) -28022 } -28023 eb/jump $emit-cleanup-code-until-target:continue/disp8 -28024 } -28025 # otherwise v is on the stack -28026 { -28027 75/jump-if-!= break/disp8 -28028 $emit-cleanup-code-until-target:reclaim-var-on-stack: -28029 (size-of %ebx) # => eax -28030 # don't emit code for labels -28031 3d/compare-eax-and 0/imm32 -28032 74/jump-if-= break/disp8 -28033 # -28034 (emit-indent *(ebp+8) *Curr-block-depth) -28035 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -28036 (write-int32-hex-buffered *(ebp+8) %eax) -28037 (write-buffered *(ebp+8) "/imm32\n") -28038 } -28039 $emit-cleanup-code-until-target:continue: -28040 # curr -= 12 -28041 81 5/subop/subtract %edx 0xc/imm32 -28042 e9/jump loop/disp32 -28043 } -28044 $emit-cleanup-code-until-target:end: -28045 # . restore registers -28046 5b/pop-to-ebx -28047 5a/pop-to-edx -28048 59/pop-to-ecx -28049 58/pop-to-eax -28050 # . epilogue -28051 89/<- %esp 5/r32/ebp -28052 5d/pop-to-ebp -28053 c3/return -28054 -28055 # update Curr-local-stack-offset assuming vars until some block depth are popped -28056 # doesn't actually modify 'vars', so we need traverse manually inside the stack -28057 clean-up-stack-offset-state: # vars: (addr stack live-var), until-block-depth: int -28058 # . prologue -28059 55/push-ebp -28060 89/<- %ebp 4/r32/esp -28061 # . save registers -28062 50/push-eax -28063 51/push-ecx -28064 52/push-edx -28065 53/push-ebx -28066 56/push-esi -28067 # ecx = vars -28068 8b/-> *(ebp+8) 1/r32/ecx -28069 # var esi: int = vars->top -28070 8b/-> *ecx 6/r32/esi -28071 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -28072 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -28073 # var min/ecx: (addr handle var) = vars->data -28074 81 0/subop/add %ecx 8/imm32 -28075 # edx = until-block-depth -28076 8b/-> *(ebp+0xc) 2/r32/edx -28077 { -28078 $clean-up-stack-offset-state:loop: -28079 # if (curr < min) break -28080 39/compare %esi 1/r32/ecx -28081 0f 82/jump-if-addr< break/disp32 -28082 # var v/ebx: (addr var) = lookup(*curr) -28083 (lookup *esi *(esi+4)) # => eax -28084 89/<- %ebx 0/r32/eax -28085 # if (v->block-depth < until-block-depth) break -28086 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -28087 0f 8c/jump-if-< break/disp32 -28088 # if v is in a register -28089 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -28090 { -28091 0f 84/jump-if-= break/disp32 -28092 { -28093 $clean-up-stack-offset-state:check-for-previous-spill: -28094 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled -28095 3d/compare-eax-and 0/imm32/false -28096 74/jump-if-= break/disp8 -28097 $clean-up-stack-offset-state:reclaim-var-in-register: -28098 81 0/subop/add *Curr-local-stack-offset 4/imm32 -28099 } -28100 eb/jump $clean-up-stack-offset-state:continue/disp8 -28101 } -28102 # otherwise v is on the stack -28103 { -28104 75/jump-if-!= break/disp8 -28105 $clean-up-stack-offset-state:var-on-stack: -28106 (size-of %ebx) # => eax -28107 01/add-to *Curr-local-stack-offset 0/r32/eax -28108 } -28109 $clean-up-stack-offset-state:continue: -28110 # curr -= 12 -28111 81 5/subop/subtract %esi 0xc/imm32 -28112 e9/jump loop/disp32 -28113 } -28114 $clean-up-stack-offset-state:end: -28115 # . restore registers -28116 5e/pop-to-esi -28117 5b/pop-to-ebx -28118 5a/pop-to-edx -28119 59/pop-to-ecx -28120 58/pop-to-eax -28121 # . epilogue -28122 89/<- %esp 5/r32/ebp -28123 5d/pop-to-ebp -28124 c3/return -28125 -28126 # Return true if there isn't a variable in 'vars' with the same block-depth -28127 # and register as 'v'. -28128 # 'v' is guaranteed not to be within 'vars'. -28129 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean -28130 # . prologue -28131 55/push-ebp -28132 89/<- %ebp 4/r32/esp -28133 # . save registers -28134 51/push-ecx -28135 52/push-edx -28136 53/push-ebx -28137 56/push-esi -28138 57/push-edi -28139 # ecx = vars -28140 8b/-> *(ebp+0xc) 1/r32/ecx -28141 # var eax: int = vars->top -28142 8b/-> *ecx 0/r32/eax -28143 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] -28144 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size -28145 # var min/ecx: (addr handle var) = vars->data -28146 8d/copy-address *(ecx+8) 1/r32/ecx -28147 # var depth/ebx: int = v->block-depth -28148 8b/-> *(ebp+8) 3/r32/ebx -28149 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth -28150 # var needle/esi: (addr array byte) = v->register -28151 8b/-> *(ebp+8) 6/r32/esi -28152 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -28153 89/<- %esi 0/r32/eax -28154 { -28155 $not-yet-spilled-this-block?:loop: -28156 # if (curr < min) break -28157 39/compare %edx 1/r32/ecx -28158 0f 82/jump-if-addr< break/disp32 -28159 # var cand/edi: (addr var) = lookup(*curr) -28160 (lookup *edx *(edx+4)) # => eax -28161 89/<- %edi 0/r32/eax -28162 # if (cand->block-depth < depth) break -28163 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth -28164 0f 8c/jump-if-< break/disp32 -28165 # var cand-reg/edi: (array array byte) = cand->reg -28166 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -28167 89/<- %edi 0/r32/eax -28168 # if (cand-reg == null) continue -28169 { -28170 $not-yet-spilled-this-block?:check-reg: -28171 81 7/subop/compare %edi 0/imm32 -28172 0f 84/jump-if-= break/disp32 -28173 # if (cand-reg == needle) return true -28174 (string-equal? %esi %edi) # => eax -28175 3d/compare-eax-and 0/imm32/false -28176 74/jump-if-= break/disp8 -28177 $not-yet-spilled-this-block?:return-false: -28178 b8/copy-to-eax 0/imm32/false -28179 eb/jump $not-yet-spilled-this-block?:end/disp8 -28180 } -28181 $not-yet-spilled-this-block?:continue: -28182 # curr -= 12 -28183 81 5/subop/subtract %edx 0xc/imm32 -28184 e9/jump loop/disp32 -28185 } -28186 $not-yet-spilled-this-block?:return-true: -28187 # return true -28188 b8/copy-to-eax 1/imm32/true -28189 $not-yet-spilled-this-block?:end: -28190 # . restore registers -28191 5f/pop-to-edi -28192 5e/pop-to-esi -28193 5b/pop-to-ebx -28194 5a/pop-to-edx -28195 59/pop-to-ecx -28196 # . epilogue -28197 89/<- %esp 5/r32/ebp -28198 5d/pop-to-ebp -28199 c3/return -28200 -28201 # could the register of 'v' ever be written to by one of the vars in fn-outputs? -28202 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean -28203 # . prologue -28204 55/push-ebp -28205 89/<- %ebp 4/r32/esp -28206 # eax = v -28207 8b/-> *(ebp+8) 0/r32/eax -28208 # var reg/eax: (addr array byte) = lookup(v->register) -28209 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -28210 # var target/eax: (addr var) = find-register(fn-outputs, reg) -28211 (find-register *(ebp+0x10) %eax) # => eax -28212 # if (target == 0) return true -28213 { -28214 3d/compare-eax-and 0/imm32 -28215 75/jump-if-!= break/disp8 -28216 b8/copy-to-eax 1/imm32/true -28217 eb/jump $will-not-write-some-register?:end/disp8 -28218 } -28219 # return !assigns-in-stmts?(stmts, target) -28220 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax -28221 3d/compare-eax-and 0/imm32/false -28222 # assume: true = 1, so no need to mask with 0x000000ff -28223 0f 94/set-if-= %al -28224 $will-not-write-some-register?:end: -28225 # . epilogue -28226 89/<- %esp 5/r32/ebp -28227 5d/pop-to-ebp -28228 c3/return -28229 -28230 # return fn output with matching register -28231 # always returns false if 'reg' is null -28232 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var) -28233 # . prologue -28234 55/push-ebp -28235 89/<- %ebp 4/r32/esp -28236 # . save registers -28237 51/push-ecx -28238 # var curr/ecx: (addr list var) = lookup(fn->outputs) -28239 8b/-> *(ebp+8) 1/r32/ecx -28240 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax -28241 89/<- %ecx 0/r32/eax -28242 { -28243 $find-register:loop: -28244 # if (curr == 0) break -28245 81 7/subop/compare %ecx 0/imm32 -28246 74/jump-if-= break/disp8 -28247 # eax = curr->value->register -28248 (lookup *ecx *(ecx+4)) # List-value List-value => eax -28249 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -28250 # if (eax == reg) return curr->value -28251 $find-register:compare: -28252 (string-equal? *(ebp+0xc) %eax) # => eax -28253 { -28254 3d/compare-eax-and 0/imm32/false -28255 74/jump-if-= break/disp8 -28256 $find-register:found: -28257 (lookup *ecx *(ecx+4)) # List-value List-value => eax -28258 eb/jump $find-register:end/disp8 -28259 } -28260 # curr = lookup(curr->next) -28261 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -28262 89/<- %ecx 0/r32/eax -28263 # -28264 eb/jump loop/disp8 -28265 } -28266 $find-register:end: -28267 # . restore registers -28268 59/pop-to-ecx -28269 # . epilogue -28270 89/<- %esp 5/r32/ebp -28271 5d/pop-to-ebp -28272 c3/return -28273 -28274 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean -28275 # . prologue -28276 55/push-ebp -28277 89/<- %ebp 4/r32/esp -28278 # . save registers -28279 51/push-ecx -28280 # var curr/ecx: (addr list stmt) = stmts -28281 8b/-> *(ebp+8) 1/r32/ecx -28282 { -28283 # if (curr == 0) break -28284 81 7/subop/compare %ecx 0/imm32 -28285 74/jump-if-= break/disp8 -28286 # if assigns-in-stmt?(curr->value, v) return true -28287 (lookup *ecx *(ecx+4)) # List-value List-value => eax -28288 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax -28289 3d/compare-eax-and 0/imm32/false -28290 75/jump-if-!= break/disp8 -28291 # curr = lookup(curr->next) -28292 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -28293 89/<- %ecx 0/r32/eax -28294 # -28295 eb/jump loop/disp8 -28296 } -28297 $assigns-in-stmts?:end: -28298 # . restore registers -28299 59/pop-to-ecx -28300 # . epilogue -28301 89/<- %esp 5/r32/ebp -28302 5d/pop-to-ebp -28303 c3/return -28304 -28305 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean -28306 # . prologue -28307 55/push-ebp -28308 89/<- %ebp 4/r32/esp -28309 # . save registers -28310 51/push-ecx -28311 # ecx = stmt -28312 8b/-> *(ebp+8) 1/r32/ecx -28313 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) -28314 { -28315 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -28316 75/jump-if-!= break/disp8 -28317 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -28318 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax -28319 eb/jump $assigns-in-stmt?:end/disp8 -28320 } -28321 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) -28322 { -28323 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -28324 75/jump-if-!= break/disp8 -28325 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax -28326 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax -28327 eb/jump $assigns-in-stmt?:end/disp8 -28328 } -28329 # otherwise return false -28330 b8/copy 0/imm32/false -28331 $assigns-in-stmt?:end: -28332 # . restore registers -28333 59/pop-to-ecx -28334 # . epilogue -28335 89/<- %esp 5/r32/ebp -28336 5d/pop-to-ebp -28337 c3/return -28338 -28339 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean -28340 # . prologue -28341 55/push-ebp -28342 89/<- %ebp 4/r32/esp -28343 # . save registers -28344 51/push-ecx -28345 # var curr/ecx: (addr stmt-var) = stmt-var -28346 8b/-> *(ebp+8) 1/r32/ecx -28347 { -28348 # if (curr == 0) break -28349 81 7/subop/compare %ecx 0/imm32 -28350 74/jump-if-= break/disp8 -28351 # eax = lookup(curr->value) -28352 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -28353 # if (eax == v && curr->is-deref? == false) return true -28354 { -28355 39/compare *(ebp+0xc) 0/r32/eax -28356 75/jump-if-!= break/disp8 -28357 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -28358 75/jump-if-!= break/disp8 -28359 b8/copy-to-eax 1/imm32/true -28360 eb/jump $assigns-in-stmt-vars?:end/disp8 -28361 } -28362 # curr = lookup(curr->next) -28363 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -28364 89/<- %ecx 0/r32/eax -28365 # -28366 eb/jump loop/disp8 -28367 } -28368 $assigns-in-stmt-vars?:end: -28369 # . restore registers -28370 59/pop-to-ecx -28371 # . epilogue -28372 89/<- %esp 5/r32/ebp -28373 5d/pop-to-ebp -28374 c3/return -28375 -28376 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? -28377 # v is guaranteed to be within vars -28378 # 'start' is provided as an optimization, a pointer within vars -28379 # *start == v -28380 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean -28381 # . prologue -28382 55/push-ebp -28383 89/<- %ebp 4/r32/esp -28384 # . save registers -28385 51/push-ecx -28386 52/push-edx -28387 53/push-ebx -28388 56/push-esi -28389 57/push-edi -28390 # ecx = v -28391 8b/-> *(ebp+8) 1/r32/ecx -28392 # var reg/edx: (addr array byte) = lookup(v->register) -28393 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -28394 89/<- %edx 0/r32/eax -28395 # var depth/ebx: int = v->block-depth -28396 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth -28397 # var min/ecx: (addr handle var) = vars->data -28398 8b/-> *(ebp+0xc) 1/r32/ecx -28399 81 0/subop/add %ecx 8/imm32 -28400 # TODO: check that start >= min and start < &vars->data[top] -28401 # TODO: check that *start == v -28402 # var curr/esi: (addr handle var) = start -28403 8b/-> *(ebp+0x10) 6/r32/esi -28404 # curr -= 8 -28405 81 5/subop/subtract %esi 8/imm32 -28406 { -28407 $same-register-spilled-before?:loop: -28408 # if (curr < min) break -28409 39/compare %esi 1/r32/ecx -28410 0f 82/jump-if-addr< break/disp32 -28411 # var x/eax: (addr var) = lookup(*curr) -28412 (lookup *esi *(esi+4)) # => eax -28413 # if (x->block-depth < depth) break -28414 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth -28415 0f 8c/jump-if-< break/disp32 -28416 # if (x->register == 0) continue -28417 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -28418 74/jump-if-= $same-register-spilled-before?:continue/disp8 -28419 # if (x->register == reg) return true -28420 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -28421 (string-equal? %eax %edx) # => eax -28422 3d/compare-eax-and 0/imm32/false -28423 b8/copy-to-eax 1/imm32/true -28424 75/jump-if-!= $same-register-spilled-before?:end/disp8 -28425 $same-register-spilled-before?:continue: -28426 # curr -= 8 -28427 81 5/subop/subtract %esi 8/imm32 -28428 e9/jump loop/disp32 -28429 } -28430 $same-register-spilled-before?:false: -28431 b8/copy-to-eax 0/imm32/false -28432 $same-register-spilled-before?:end: -28433 # . restore registers -28434 5f/pop-to-edi -28435 5e/pop-to-esi -28436 5b/pop-to-ebx -28437 5a/pop-to-edx -28438 59/pop-to-ecx -28439 # . epilogue -28440 89/<- %esp 5/r32/ebp -28441 5d/pop-to-ebp -28442 c3/return -28443 -28444 # clean up global state for 'vars' until some block depth (inclusive) -28445 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function) -28446 # . prologue -28447 55/push-ebp -28448 89/<- %ebp 4/r32/esp -28449 # . save registers -28450 50/push-eax -28451 51/push-ecx -28452 56/push-esi -28453 # esi = vars -28454 8b/-> *(ebp+8) 6/r32/esi -28455 # ecx = until-block-depth -28456 8b/-> *(ebp+0xc) 1/r32/ecx -28457 { -28458 $clean-up-blocks:reclaim-loop: -28459 # if (vars->top <= 0) break -28460 8b/-> *esi 0/r32/eax # Stack-top -28461 3d/compare-eax-and 0/imm32 -28462 0f 8e/jump-if-<= break/disp32 -28463 # var v/eax: (addr var) = lookup(vars[vars->top-12]) -28464 (lookup *(esi+eax-4) *(esi+eax)) # vars + 8 + vars->top - 12 => eax -28465 # if (v->block-depth < until-block-depth) break -28466 39/compare *(eax+0x10) 1/r32/ecx # Var-block-depth -28467 0f 8c/jump-if-< break/disp32 -28468 (pop %esi) # => eax -28469 (pop %esi) # => eax -28470 (pop %esi) # => eax -28471 e9/jump loop/disp32 -28472 } -28473 $clean-up-blocks:end: -28474 # . restore registers -28475 5e/pop-to-esi -28476 59/pop-to-ecx -28477 58/pop-to-eax -28478 # . epilogue -28479 89/<- %esp 5/r32/ebp -28480 5d/pop-to-ebp -28481 c3/return -28482 -28483 reg-in-function-outputs?: # fn: (addr function), target: (addr array byte) -> result/eax: boolean -28484 # . prologue -28485 55/push-ebp -28486 89/<- %ebp 4/r32/esp -28487 # . save registers -28488 51/push-ecx -28489 # var curr/ecx: (addr list var) = lookup(fn->outputs) -28490 8b/-> *(ebp+8) 0/r32/eax -28491 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax -28492 89/<- %ecx 0/r32/eax -28493 # while curr != null -28494 { -28495 81 7/subop/compare %ecx 0/imm32 -28496 74/jump-if-= break/disp8 -28497 # var v/eax: (addr var) = lookup(curr->value) -28498 (lookup *ecx *(ecx+4)) # List-value List-value => eax -28499 # var reg/eax: (addr array byte) = lookup(v->register) -28500 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -28501 # if (reg == target) return true -28502 (string-equal? %eax *(ebp+0xc)) # => eax -28503 3d/compare-eax-and 0/imm32/false -28504 75/jump-if-!= $reg-in-function-outputs?:end/disp8 -28505 # curr = curr->next -28506 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -28507 89/<- %ecx 0/r32/eax -28508 # -28509 eb/jump loop/disp8 -28510 } -28511 # return false -28512 b8/copy-to-eax 0/imm32 -28513 $reg-in-function-outputs?:end: -28514 # . restore registers -28515 59/pop-to-ecx -28516 # . epilogue -28517 89/<- %esp 5/r32/ebp -28518 5d/pop-to-ebp -28519 c3/return -28520 -28521 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -28522 # . prologue -28523 55/push-ebp -28524 89/<- %ebp 4/r32/esp -28525 # . save registers -28526 50/push-eax -28527 51/push-ecx -28528 52/push-edx -28529 # eax = stmt -28530 8b/-> *(ebp+0xc) 0/r32/eax -28531 # var v/ecx: (addr var) -28532 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax -28533 89/<- %ecx 0/r32/eax -28534 # v->block-depth = *Curr-block-depth -28535 8b/-> *Curr-block-depth 0/r32/eax -28536 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -28537 # var n/edx: int = size-of(stmt->var) -28538 (size-of %ecx) # => eax -28539 89/<- %edx 0/r32/eax -28540 # *Curr-local-stack-offset -= n -28541 29/subtract-from *Curr-local-stack-offset 2/r32/edx -28542 # v->offset = *Curr-local-stack-offset -28543 8b/-> *Curr-local-stack-offset 0/r32/eax -28544 89/<- *(ecx+0x14) 0/r32/eax # Var-offset -28545 # if v is an array, do something special to initialize it -28546 { -28547 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -28548 (mu-array? %eax) # => eax -28549 3d/compare-eax-and 0/imm32/false -28550 0f 84/jump-if-= break/disp32 -28551 # var array-size-without-size/edx: int = n-4 -28552 81 5/subop/subtract %edx 4/imm32 -28553 # -28554 (emit-array-data-initialization *(ebp+8) %edx) -28555 e9/jump $emit-subx-var-def:end/disp32 -28556 } -28557 # another special-case for initializing streams -28558 # a stream is an array with 2 extra pointers -28559 { -28560 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -28561 (mu-stream? %eax) # => eax -28562 3d/compare-eax-and 0/imm32/false -28563 0f 84/jump-if-= break/disp32 -28564 # var array-size-without-size/edx: int = n-12 -28565 81 5/subop/subtract %edx 0xc/imm32 -28566 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -28567 (emit-stream-data-initialization *(ebp+8) %edx %eax *(ebp+0x10) *(ebp+0x14)) -28568 # emit read and write pointers -28569 (emit-indent *(ebp+8) *Curr-block-depth) -28570 (write-buffered *(ebp+8) "68/push 0/imm32\n") -28571 (emit-indent *(ebp+8) *Curr-block-depth) -28572 (write-buffered *(ebp+8) "68/push 0/imm32\n") +26001 75/jump-if-!= break/disp8 +26002 (simple-mu-type? %edx 0xf) # float => eax +26003 3d/compare-eax-and 0/imm32/false +26004 75/jump-if-!= break/disp8 +26005 e9/jump $check-mu-convert-stmt:error-invalid-output-type/disp32 +26006 } +26007 # if both are ints, abort +26008 { +26009 (simple-mu-type? %edx 1) # int => eax +26010 3d/compare-eax-and 0/imm32/false +26011 74/jump-if-= break/disp8 +26012 (simple-mu-type? %ecx 1) # int => eax +26013 3d/compare-eax-and 0/imm32/false +26014 74/jump-if-= break/disp8 +26015 e9/jump $check-mu-convert-stmt:error-int-to-int/disp32 +26016 } +26017 # if both are floats, abort +26018 { +26019 (simple-mu-type? %edx 0xf) # float => eax +26020 3d/compare-eax-and 0/imm32/false +26021 74/jump-if-= break/disp8 +26022 (simple-mu-type? %ecx 0xf) # float => eax +26023 3d/compare-eax-and 0/imm32/false +26024 74/jump-if-= break/disp8 +26025 e9/jump $check-mu-convert-stmt:error-float-to-float/disp32 +26026 } +26027 $check-mu-convert-stmt:end: +26028 # . restore registers +26029 5f/pop-to-edi +26030 5e/pop-to-esi +26031 5a/pop-to-edx +26032 59/pop-to-ecx +26033 58/pop-to-eax +26034 # . epilogue +26035 89/<- %esp 5/r32/ebp +26036 5d/pop-to-ebp +26037 c3/return +26038 +26039 $check-mu-convert-stmt:error-no-inout: +26040 (write-buffered *(ebp+0x10) "fn ") +26041 8b/-> *(ebp+0xc) 0/r32/eax +26042 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26043 (write-buffered *(ebp+0x10) %eax) +26044 (write-buffered *(ebp+0x10) ": stmt 'convert' expects an inout\n") +26045 (flush *(ebp+0x10)) +26046 (stop *(ebp+0x14) 1) +26047 # never gets here +26048 +26049 $check-mu-convert-stmt:error-too-many-inouts: +26050 (write-buffered *(ebp+0x10) "fn ") +26051 8b/-> *(ebp+0xc) 0/r32/eax +26052 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26053 (write-buffered *(ebp+0x10) %eax) +26054 (write-buffered *(ebp+0x10) ": stmt 'convert' must have just one inout\n") +26055 (flush *(ebp+0x10)) +26056 (stop *(ebp+0x14) 1) +26057 # never gets here +26058 +26059 $check-mu-convert-stmt:error-no-output: +26060 (write-buffered *(ebp+0x10) "fn ") +26061 8b/-> *(ebp+0xc) 0/r32/eax +26062 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26063 (write-buffered *(ebp+0x10) %eax) +26064 (write-buffered *(ebp+0x10) ": stmt 'convert' expects an output\n") +26065 (flush *(ebp+0x10)) +26066 (stop *(ebp+0x14) 1) +26067 # never gets here +26068 +26069 $check-mu-convert-stmt:error-output-not-in-register: +26070 (write-buffered *(ebp+0x10) "fn ") +26071 8b/-> *(ebp+0xc) 0/r32/eax +26072 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26073 (write-buffered *(ebp+0x10) %eax) +26074 (write-buffered *(ebp+0x10) ": stmt convert: output '") +26075 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +26076 (lookup *eax *(eax+4)) # Var-name Var-name => eax +26077 (write-buffered *(ebp+0x10) %eax) +26078 (write-buffered *(ebp+0x10) "' not in a register\n") +26079 (flush *(ebp+0x10)) +26080 (stop *(ebp+0x14) 1) +26081 # never gets here +26082 +26083 $check-mu-convert-stmt:error-too-many-outputs: +26084 (write-buffered *(ebp+0x10) "fn ") +26085 8b/-> *(ebp+0xc) 0/r32/eax +26086 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26087 (write-buffered *(ebp+0x10) %eax) +26088 (write-buffered *(ebp+0x10) ": stmt 'convert' must have just one output\n") +26089 (flush *(ebp+0x10)) +26090 (stop *(ebp+0x14) 1) +26091 # never gets here +26092 +26093 $check-mu-convert-stmt:error-invalid-inout-type: +26094 (write-buffered *(ebp+0x10) "fn ") +26095 8b/-> *(ebp+0xc) 0/r32/eax +26096 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26097 (write-buffered *(ebp+0x10) %eax) +26098 (write-buffered *(ebp+0x10) ": stmt convert: inout '") +26099 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax +26100 (lookup *eax *(eax+4)) # Var-name Var-name => eax +26101 (write-buffered *(ebp+0x10) %eax) +26102 (write-buffered *(ebp+0x10) "' must be an int or float\n") +26103 (flush *(ebp+0x10)) +26104 (stop *(ebp+0x14) 1) +26105 # never gets here +26106 +26107 $check-mu-convert-stmt:error-invalid-output-type: +26108 (write-buffered *(ebp+0x10) "fn ") +26109 8b/-> *(ebp+0xc) 0/r32/eax +26110 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26111 (write-buffered *(ebp+0x10) %eax) +26112 (write-buffered *(ebp+0x10) ": stmt convert: output '") +26113 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax +26114 (lookup *eax *(eax+4)) # Var-name Var-name => eax +26115 (write-buffered *(ebp+0x10) %eax) +26116 (write-buffered *(ebp+0x10) "' must be an int or float\n") +26117 (flush *(ebp+0x10)) +26118 (stop *(ebp+0x14) 1) +26119 # never gets here +26120 +26121 $check-mu-convert-stmt:error-int-to-int: +26122 (write-buffered *(ebp+0x10) "fn ") +26123 8b/-> *(ebp+0xc) 0/r32/eax +26124 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26125 (write-buffered *(ebp+0x10) %eax) +26126 (write-buffered *(ebp+0x10) ": stmt convert: no need to convert int to int\n") +26127 (flush *(ebp+0x10)) +26128 (stop *(ebp+0x14) 1) +26129 # never gets here +26130 +26131 $check-mu-convert-stmt:error-float-to-float: +26132 (write-buffered *(ebp+0x10) "fn ") +26133 8b/-> *(ebp+0xc) 0/r32/eax +26134 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26135 (write-buffered *(ebp+0x10) %eax) +26136 (write-buffered *(ebp+0x10) ": stmt convert: no need to convert float to float\n") +26137 (flush *(ebp+0x10)) +26138 (stop *(ebp+0x14) 1) +26139 # never gets here +26140 +26141 check-mu-call: # stmt: (addr stmt), callee: (addr function), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +26142 # . prologue +26143 55/push-ebp +26144 89/<- %ebp 4/r32/esp +26145 # var type-parameters: (addr table (handle array byte) (addr type-tree) 8) +26146 68/push 0/imm32 +26147 # var type-parameters-storage: (table (handle array byte) (addr type-tree) 8) +26148 81 5/subop/subtract %esp 0x60/imm32 +26149 68/push 0x60/imm32/size +26150 68/push 0/imm32/read +26151 68/push 0/imm32/write +26152 # save a pointer to type-parameters-storage at type-parameters +26153 89/<- *(ebp-4) 4/r32/esp +26154 (clear-stream *(ebp-4)) +26155 # . save registers +26156 50/push-eax +26157 51/push-ecx +26158 52/push-edx +26159 53/push-ebx +26160 56/push-esi +26161 57/push-edi +26162 # esi = stmt +26163 8b/-> *(ebp+8) 6/r32/esi +26164 # edi = callee +26165 8b/-> *(ebp+0xc) 7/r32/edi +26166 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts) +26167 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +26168 89/<- %ecx 0/r32/eax +26169 # var expected/edx: (addr list var) = lookup(f->inouts) +26170 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax +26171 89/<- %edx 0/r32/eax +26172 { +26173 $check-mu-call:check-for-inouts: +26174 # if (inouts == 0) break +26175 81 7/subop/compare %ecx 0/imm32 +26176 0f 84/jump-if-= break/disp32 +26177 # if (expected == 0) error +26178 81 7/subop/compare %edx 0/imm32 +26179 0f 84/jump-if-= break/disp32 +26180 $check-mu-call:check-null-addr: +26181 # if (inouts->value->name == "0") continue +26182 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +26183 (lookup *eax *(eax+4)) # Var-name Var-name => eax +26184 (string-equal? %eax "0") # => eax +26185 3d/compare-eax-and 0/imm32/false +26186 0f 85/jump-if-!= $check-mu-call:continue-to-next-inout/disp32 +26187 $check-mu-call:check-inout-type: +26188 # var t/ebx: (addr type-tree) = inouts->value->type +26189 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +26190 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +26191 89/<- %ebx 0/r32/eax +26192 # if (inouts->is-deref?) t = t->right +26193 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +26194 { +26195 74/jump-if-= break/disp8 +26196 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +26197 89/<- %ebx 0/r32/eax +26198 # if t->right is null, t = t->left +26199 81 7/subop/compare *(ebx+0xc) 0/imm32 # Type-tree-right +26200 75/jump-if-!= break/disp8 +26201 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +26202 89/<- %ebx 0/r32/eax +26203 } +26204 # var v2/eax: (addr v) = lookup(expected->value) +26205 (lookup *edx *(edx+4)) # List-value List-value => eax +26206 # var t2/eax: (addr type-tree) = lookup(v2->type) +26207 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +26208 # if (t != t2) error +26209 (type-match? %eax %ebx *(ebp-4)) # => eax +26210 3d/compare-eax-and 0/imm32/false +26211 { +26212 0f 85/jump-if-!= break/disp32 +26213 (write-buffered *(ebp+0x14) "fn ") +26214 8b/-> *(ebp+0x10) 0/r32/eax +26215 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26216 (write-buffered *(ebp+0x14) %eax) +26217 (write-buffered *(ebp+0x14) ": call ") +26218 (lookup *edi *(edi+4)) # Function-name Function-name => eax +26219 (write-buffered *(ebp+0x14) %eax) +26220 (write-buffered *(ebp+0x14) ": type for inout '") +26221 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +26222 (lookup *eax *(eax+4)) # Var-name Var-name => eax +26223 (write-buffered *(ebp+0x14) %eax) +26224 (write-buffered *(ebp+0x14) "' is not right\n") +26225 (flush *(ebp+0x14)) +26226 (stop *(ebp+0x18) 1) +26227 } +26228 $check-mu-call:continue-to-next-inout: +26229 # inouts = lookup(inouts->next) +26230 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +26231 89/<- %ecx 0/r32/eax +26232 # expected = lookup(expected->next) +26233 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +26234 89/<- %edx 0/r32/eax +26235 # +26236 e9/jump loop/disp32 +26237 } +26238 $check-mu-call:check-inout-count: +26239 # if (inouts == expected) proceed +26240 39/compare %ecx 2/r32/edx +26241 { +26242 0f 84/jump-if-= break/disp32 +26243 # exactly one of the two is null +26244 # if (inouts == 0) error("too many inouts") +26245 { +26246 81 7/subop/compare %ecx 0/imm32 +26247 0f 84/jump-if-= break/disp32 +26248 (write-buffered *(ebp+0x14) "fn ") +26249 8b/-> *(ebp+0x10) 0/r32/eax +26250 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26251 (write-buffered *(ebp+0x14) %eax) +26252 (write-buffered *(ebp+0x14) ": call ") +26253 (lookup *edi *(edi+4)) # Function-name Function-name => eax +26254 (write-buffered *(ebp+0x14) %eax) +26255 (write-buffered *(ebp+0x14) ": too many inouts\n") +26256 (flush *(ebp+0x14)) +26257 (stop *(ebp+0x18) 1) +26258 } +26259 # if (expected == 0) error("too few inouts") +26260 { +26261 81 7/subop/compare %edx 0/imm32 +26262 0f 84/jump-if-= break/disp32 +26263 (write-buffered *(ebp+0x14) "fn ") +26264 8b/-> *(ebp+0x10) 0/r32/eax +26265 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26266 (write-buffered *(ebp+0x14) %eax) +26267 (write-buffered *(ebp+0x14) ": call ") +26268 (lookup *edi *(edi+4)) # Function-name Function-name => eax +26269 (write-buffered *(ebp+0x14) %eax) +26270 (write-buffered *(ebp+0x14) ": too few inouts\n") +26271 (flush *(ebp+0x14)) +26272 (stop *(ebp+0x18) 1) +26273 } +26274 } +26275 $check-mu-call:check-outputs: +26276 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs) +26277 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +26278 89/<- %ecx 0/r32/eax +26279 # var expected/edx: (addr list var) = lookup(f->outputs) +26280 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax +26281 89/<- %edx 0/r32/eax +26282 { +26283 $check-mu-call:check-for-outputs: +26284 # if (outputs == 0) break +26285 81 7/subop/compare %ecx 0/imm32 +26286 0f 84/jump-if-= break/disp32 +26287 # if (expected == 0) error +26288 81 7/subop/compare %edx 0/imm32 +26289 0f 84/jump-if-= break/disp32 +26290 $check-mu-call:check-output-type: +26291 # var v/eax: (addr v) = lookup(outputs->value) +26292 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +26293 # var t/ebx: (addr type-tree) = lookup(v->type) +26294 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +26295 89/<- %ebx 0/r32/eax +26296 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr +26297 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +26298 { +26299 74/jump-if-= break/disp8 +26300 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +26301 89/<- %ebx 0/r32/eax +26302 } +26303 # var v2/eax: (addr v) = lookup(expected->value) +26304 (lookup *edx *(edx+4)) # List-value List-value => eax +26305 # var t2/eax: (addr type-tree) = lookup(v2->type) +26306 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +26307 # if (t != t2) error +26308 (type-match? %eax %ebx *(ebp-4)) # => eax +26309 3d/compare-eax-and 0/imm32/false +26310 { +26311 0f 85/jump-if-!= break/disp32 +26312 (write-buffered *(ebp+0x14) "fn ") +26313 8b/-> *(ebp+0x10) 0/r32/eax +26314 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26315 (write-buffered *(ebp+0x14) %eax) +26316 (write-buffered *(ebp+0x14) ": call ") +26317 (lookup *edi *(edi+4)) # Function-name Function-name => eax +26318 (write-buffered *(ebp+0x14) %eax) +26319 (write-buffered *(ebp+0x14) ": type for output '") +26320 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +26321 (lookup *eax *(eax+4)) # Var-name Var-name => eax +26322 (write-buffered *(ebp+0x14) %eax) +26323 (write-buffered *(ebp+0x14) "' is not right\n") +26324 (flush *(ebp+0x14)) +26325 (stop *(ebp+0x18) 1) +26326 } +26327 $check-mu-call:check-output-register: +26328 # var v/eax: (addr v) = lookup(outputs->value) +26329 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +26330 # var r/ebx: (addr array byte) = lookup(v->register) +26331 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax +26332 89/<- %ebx 0/r32/eax +26333 # if (r == 0) error +26334 3d/compare-eax-and 0/imm32 +26335 { +26336 0f 85/jump-if-!= break/disp32 +26337 (write-buffered *(ebp+0x14) "fn ") +26338 8b/-> *(ebp+0x10) 0/r32/eax +26339 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26340 (write-buffered *(ebp+0x14) %eax) +26341 (write-buffered *(ebp+0x14) ": call ") +26342 (lookup *edi *(edi+4)) # Function-name Function-name => eax +26343 (write-buffered *(ebp+0x14) %eax) +26344 (write-buffered *(ebp+0x14) ": output '") +26345 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +26346 (lookup *eax *(eax+4)) # Var-name Var-name => eax +26347 (write-buffered *(ebp+0x14) %eax) +26348 (write-buffered *(ebp+0x14) "' is not in a register\n") +26349 (flush *(ebp+0x14)) +26350 (stop *(ebp+0x18) 1) +26351 } +26352 # var v2/eax: (addr v) = lookup(expected->value) +26353 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax +26354 # var r2/eax: (addr array byte) = lookup(v2->register) +26355 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax +26356 # if (r != r2) error +26357 (string-equal? %eax %ebx) # => eax +26358 3d/compare-eax-and 0/imm32/false +26359 { +26360 0f 85/jump-if-!= break/disp32 +26361 (write-buffered *(ebp+0x14) "fn ") +26362 8b/-> *(ebp+0x10) 0/r32/eax +26363 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26364 (write-buffered *(ebp+0x14) %eax) +26365 (write-buffered *(ebp+0x14) ": call ") +26366 (lookup *edi *(edi+4)) # Function-name Function-name => eax +26367 (write-buffered *(ebp+0x14) %eax) +26368 (write-buffered *(ebp+0x14) ": register for output '") +26369 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +26370 (lookup *eax *(eax+4)) # Var-name Var-name => eax +26371 (write-buffered *(ebp+0x14) %eax) +26372 (write-buffered *(ebp+0x14) "' is not right\n") +26373 (flush *(ebp+0x14)) +26374 (stop *(ebp+0x18) 1) +26375 } +26376 $check-mu-call:continue-to-next-output: +26377 # outputs = lookup(outputs->next) +26378 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +26379 89/<- %ecx 0/r32/eax +26380 # expected = lookup(expected->next) +26381 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +26382 89/<- %edx 0/r32/eax +26383 # +26384 e9/jump loop/disp32 +26385 } +26386 $check-mu-call:check-output-count: +26387 # if (outputs == expected) proceed +26388 39/compare %ecx 2/r32/edx +26389 { +26390 0f 84/jump-if-= break/disp32 +26391 # exactly one of the two is null +26392 # if (outputs == 0) error("too many outputs") +26393 { +26394 81 7/subop/compare %ecx 0/imm32 +26395 0f 84/jump-if-= break/disp32 +26396 (write-buffered *(ebp+0x14) "fn ") +26397 8b/-> *(ebp+0x10) 0/r32/eax +26398 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26399 (write-buffered *(ebp+0x14) %eax) +26400 (write-buffered *(ebp+0x14) ": call ") +26401 (lookup *edi *(edi+4)) # Function-name Function-name => eax +26402 (write-buffered *(ebp+0x14) %eax) +26403 (write-buffered *(ebp+0x14) ": too many outputs\n") +26404 (flush *(ebp+0x14)) +26405 (stop *(ebp+0x18) 1) +26406 } +26407 # if (expected == 0) error("too few outputs") +26408 { +26409 81 7/subop/compare %edx 0/imm32 +26410 0f 84/jump-if-= break/disp32 +26411 (write-buffered *(ebp+0x14) "fn ") +26412 8b/-> *(ebp+0x10) 0/r32/eax +26413 (lookup *eax *(eax+4)) # Function-name Function-name => eax +26414 (write-buffered *(ebp+0x14) %eax) +26415 (write-buffered *(ebp+0x14) ": call ") +26416 (lookup *edi *(edi+4)) # Function-name Function-name => eax +26417 (write-buffered *(ebp+0x14) %eax) +26418 (write-buffered *(ebp+0x14) ": too few outputs\n") +26419 (flush *(ebp+0x14)) +26420 (stop *(ebp+0x18) 1) +26421 } +26422 } +26423 $check-mu-call:end: +26424 # . restore registers +26425 5f/pop-to-edi +26426 5e/pop-to-esi +26427 5b/pop-to-ebx +26428 5a/pop-to-edx +26429 59/pop-to-ecx +26430 58/pop-to-eax +26431 # . reclaim locals exclusively on the stack +26432 81 0/subop/add %esp 0x70/imm32 +26433 # . epilogue +26434 89/<- %esp 5/r32/ebp +26435 5d/pop-to-ebp +26436 c3/return +26437 +26438 # like type-equal? but takes literals type parameters into account +26439 type-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean +26440 # . prologue +26441 55/push-ebp +26442 89/<- %ebp 4/r32/esp +26443 # if call is literal and def is numberlike, return true +26444 { +26445 $type-match?:check-literal-int: +26446 (simple-mu-type? *(ebp+0xc) 0) # literal => eax +26447 3d/compare-eax-and 0/imm32/false +26448 74/jump-if-= break/disp8 +26449 (mu-numberlike-output? *(ebp+8)) # => eax +26450 3d/compare-eax-and 0/imm32/false +26451 74/jump-if-= break/disp8 +26452 b8/copy-to-eax 1/imm32/true +26453 e9/jump $type-match?:end/disp32 +26454 } +26455 # if call is literal-string, match against (addr array byte) +26456 { +26457 $type-match?:check-literal-string: +26458 (simple-mu-type? *(ebp+0xc) 0x10) # literal-string => eax +26459 3d/compare-eax-and 0/imm32/false +26460 74/jump-if-= break/disp8 +26461 (type-component-match? *(ebp+8) Addr-type-string *(ebp+0x10)) # => eax +26462 e9/jump $type-match?:end/disp32 +26463 } +26464 $type-match?:baseline: +26465 # otherwise fall back +26466 (type-component-match? *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax +26467 $type-match?:end: +26468 # . epilogue +26469 89/<- %esp 5/r32/ebp +26470 5d/pop-to-ebp +26471 c3/return +26472 +26473 type-component-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean +26474 # . prologue +26475 55/push-ebp +26476 89/<- %ebp 4/r32/esp +26477 # . save registers +26478 51/push-ecx +26479 52/push-edx +26480 53/push-ebx +26481 # ecx = def +26482 8b/-> *(ebp+8) 1/r32/ecx +26483 # edx = call +26484 8b/-> *(ebp+0xc) 2/r32/edx +26485 $type-component-match?:compare-addr: +26486 # if (def == call) return true +26487 8b/-> %ecx 0/r32/eax # Var-type +26488 39/compare %edx 0/r32/eax # Var-type +26489 b8/copy-to-eax 1/imm32/true +26490 0f 84/jump-if-= $type-component-match?:end/disp32 +26491 # if (def == 0) return false +26492 b8/copy-to-eax 0/imm32/false +26493 81 7/subop/compare %ecx 0/imm32 # Type-tree-is-atom +26494 0f 84/jump-if-= $type-component-match?:end/disp32 +26495 # if (call == 0) return false +26496 81 7/subop/compare %edx 0/imm32 # Type-tree-is-atom +26497 0f 84/jump-if-= $type-component-match?:end/disp32 +26498 # if def is a type parameter, just check in type-parameters +26499 { +26500 $type-component-match?:check-type-parameter: +26501 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +26502 74/jump-if-= break/disp8 +26503 81 7/subop/compare *(ecx+4) 0xa/imm32/type-parameter # Type-tree-value +26504 75/jump-if-!= break/disp8 +26505 $type-component-match?:type-parameter: +26506 (type-parameter-match? *(ecx+8) *(ecx+0xc) %edx *(ebp+0x10)) # => eax +26507 e9/jump $type-component-match?:end/disp32 +26508 } +26509 # if def is a list containing just a type parameter, just check in type-parameters +26510 { +26511 $type-component-match?:check-list-type-parameter: +26512 # if def is a list.. +26513 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +26514 75/jump-if-!= break/disp8 +26515 # ..that's a singleton +26516 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-left +26517 75/jump-if-!= break/disp8 +26518 # ..and whose head is a type parameter +26519 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26520 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +26521 74/jump-if-= break/disp8 +26522 81 7/subop/compare *(eax+4) 0xa/imm32/type-parameter # Type-tree-value +26523 75/jump-if-!= break/disp8 +26524 $type-component-match?:list-type-parameter: +26525 (type-parameter-match? *(eax+8) *(eax+0xc) %edx *(ebp+0x10)) # => eax +26526 e9/jump $type-component-match?:end/disp32 +26527 } +26528 $type-component-match?:compare-atom-state: +26529 # if (def->is-atom? != call->is-atom?) return false +26530 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom +26531 39/compare *edx 3/r32/ebx # Type-tree-is-atom +26532 b8/copy-to-eax 0/imm32/false +26533 0f 85/jump-if-!= $type-component-match?:end/disp32 +26534 # if def->is-atom? return (def->value == call->value) +26535 { +26536 $type-component-match?:check-atom: +26537 81 7/subop/compare %ebx 0/imm32/false +26538 74/jump-if-= break/disp8 +26539 $type-component-match?:is-atom: +26540 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value +26541 39/compare *(edx+4) 0/r32/eax # Type-tree-value +26542 0f 94/set-if-= %al +26543 25/and-eax-with 0xff/imm32 +26544 e9/jump $type-component-match?:end/disp32 +26545 } +26546 $type-component-match?:check-left: +26547 # if (!type-component-match?(def->left, call->left)) return false +26548 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26549 89/<- %ebx 0/r32/eax +26550 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +26551 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax +26552 3d/compare-eax-and 0/imm32/false +26553 74/jump-if-= $type-component-match?:end/disp8 +26554 $type-component-match?:check-right: +26555 # return type-component-match?(def->right, call->right) +26556 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +26557 89/<- %ebx 0/r32/eax +26558 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax +26559 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax +26560 $type-component-match?:end: +26561 # . restore registers +26562 5b/pop-to-ebx +26563 5a/pop-to-edx +26564 59/pop-to-ecx +26565 # . epilogue +26566 89/<- %esp 5/r32/ebp +26567 5d/pop-to-ebp +26568 c3/return +26569 +26570 type-parameter-match?: # type-parameter-name: (handle array byte), type: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean +26571 # . prologue +26572 55/push-ebp +26573 89/<- %ebp 4/r32/esp +26574 # . save registers +26575 51/push-ecx +26576 # +26577 (get-or-insert-handle *(ebp+0x14) *(ebp+8) *(ebp+0xc) 0xc) # => eax +26578 # if parameter wasn't saved, save it +26579 { +26580 81 7/subop/compare *eax 0/imm32 +26581 75/jump-if-!= break/disp8 +26582 8b/-> *(ebp+0x10) 1/r32/ecx +26583 89/<- *eax 1/r32/ecx +26584 } +26585 # +26586 (type-equal? *(ebp+0x10) *eax) # => eax +26587 $type-parameter-match?:end: +26588 # . restore registers +26589 59/pop-to-ecx +26590 # . epilogue +26591 89/<- %esp 5/r32/ebp +26592 5d/pop-to-ebp +26593 c3/return +26594 +26595 size-of: # v: (addr var) -> result/eax: int +26596 # . prologue +26597 55/push-ebp +26598 89/<- %ebp 4/r32/esp +26599 # . save registers +26600 51/push-ecx +26601 # var t/ecx: (addr type-tree) = lookup(v->type) +26602 8b/-> *(ebp+8) 1/r32/ecx +26603 #? (write-buffered Stderr "size-of ") +26604 #? (write-int32-hex-buffered Stderr %ecx) +26605 #? (write-buffered Stderr Newline) +26606 #? (write-buffered Stderr "type allocid: ") +26607 #? (write-int32-hex-buffered Stderr *(ecx+8)) +26608 #? (write-buffered Stderr Newline) +26609 #? (flush Stderr) +26610 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +26611 89/<- %ecx 0/r32/eax +26612 # if mu-array?(t) return size-of-array(t) +26613 { +26614 (mu-array? %ecx) # => eax +26615 3d/compare-eax-and 0/imm32/false +26616 74/jump-if-= break/disp8 +26617 (size-of-array %ecx) # => eax +26618 eb/jump $size-of:end/disp8 +26619 } +26620 # if mu-stream?(t) return size-of-stream(t) +26621 { +26622 (mu-stream? %ecx) # => eax +26623 3d/compare-eax-and 0/imm32/false +26624 74/jump-if-= break/disp8 +26625 (size-of-stream %ecx) # => eax +26626 eb/jump $size-of:end/disp8 +26627 } +26628 # if (!t->is-atom?) t = lookup(t->left) +26629 { +26630 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +26631 75/jump-if-!= break/disp8 +26632 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26633 89/<- %ecx 0/r32/eax +26634 } +26635 # TODO: assert t->is-atom? +26636 (size-of-type-id *(ecx+4)) # Type-tree-value => eax +26637 $size-of:end: +26638 # . restore registers +26639 59/pop-to-ecx +26640 # . epilogue +26641 89/<- %esp 5/r32/ebp +26642 5d/pop-to-ebp +26643 c3/return +26644 +26645 size-of-deref: # v: (addr var) -> result/eax: int +26646 # . prologue +26647 55/push-ebp +26648 89/<- %ebp 4/r32/esp +26649 # . save registers +26650 51/push-ecx +26651 # var t/ecx: (addr type-tree) = lookup(v->type) +26652 8b/-> *(ebp+8) 1/r32/ecx +26653 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +26654 89/<- %ecx 0/r32/eax +26655 # TODO: assert(t is an addr) +26656 # t = lookup(t->right) +26657 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +26658 89/<- %ecx 0/r32/eax +26659 # if mu-array?(t) return size-of-array(t) +26660 { +26661 (mu-array? %ecx) # => eax +26662 3d/compare-eax-and 0/imm32/false +26663 74/jump-if-= break/disp8 +26664 (size-of-array %ecx) # => eax +26665 eb/jump $size-of-deref:end/disp8 +26666 } +26667 # if mu-stream?(t) return size-of-stream(t) +26668 { +26669 (mu-stream? %ecx) # => eax +26670 3d/compare-eax-and 0/imm32/false +26671 74/jump-if-= break/disp8 +26672 (size-of-stream %ecx) # => eax +26673 eb/jump $size-of-deref:end/disp8 +26674 } +26675 # if (!t->is-atom?) t = lookup(t->left) +26676 { +26677 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +26678 75/jump-if-!= break/disp8 +26679 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26680 89/<- %ecx 0/r32/eax +26681 } +26682 # TODO: assert t->is-atom? +26683 (size-of-type-id *(ecx+4)) # Type-tree-value => eax +26684 $size-of-deref:end: +26685 # . restore registers +26686 59/pop-to-ecx +26687 # . epilogue +26688 89/<- %esp 5/r32/ebp +26689 5d/pop-to-ebp +26690 c3/return +26691 +26692 mu-array?: # t: (addr type-tree) -> result/eax: boolean +26693 # . prologue +26694 55/push-ebp +26695 89/<- %ebp 4/r32/esp +26696 # . save registers +26697 51/push-ecx +26698 # ecx = t +26699 8b/-> *(ebp+8) 1/r32/ecx +26700 # if t->is-atom?, return false +26701 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +26702 75/jump-if-!= $mu-array?:return-false/disp8 +26703 # if !t->left->is-atom?, return false +26704 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26705 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +26706 74/jump-if-= $mu-array?:return-false/disp8 +26707 # return t->left->value == array +26708 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Type-tree-value +26709 0f 94/set-if-= %al +26710 25/and-eax-with 0xff/imm32 +26711 eb/jump $mu-array?:end/disp8 +26712 $mu-array?:return-false: +26713 b8/copy-to-eax 0/imm32/false +26714 $mu-array?:end: +26715 # . restore registers +26716 59/pop-to-ecx +26717 # . epilogue +26718 89/<- %esp 5/r32/ebp +26719 5d/pop-to-ebp +26720 c3/return +26721 +26722 # size of a statically allocated array where the size is part of the type expression +26723 size-of-array: # a: (addr type-tree) -> result/eax: int +26724 # . prologue +26725 55/push-ebp +26726 89/<- %ebp 4/r32/esp +26727 # . save registers +26728 51/push-ecx +26729 52/push-edx +26730 # +26731 8b/-> *(ebp+8) 1/r32/ecx +26732 # TODO: assert that a->left is 'array' +26733 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +26734 89/<- %ecx 0/r32/eax +26735 # var elem-type/edx: type-id = a->right->left->value +26736 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26737 8b/-> *(eax+4) 2/r32/edx # Type-tree-value +26738 # TODO: assert that a->right->right->left->value == size +26739 # var array-size/ecx: int = a->right->right->left->value-size +26740 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +26741 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +26742 8b/-> *(eax+8) 1/r32/ecx # Type-tree-value-size +26743 # return 4 + array-size * size-of(elem-type) +26744 (size-of-type-id-as-array-element %edx) # => eax +26745 f7 4/subop/multiply-into-edx-eax %ecx +26746 05/add-to-eax 4/imm32 # for array size +26747 # TODO: check edx for overflow +26748 $size-of-array:end: +26749 # . restore registers +26750 5a/pop-to-edx +26751 59/pop-to-ecx +26752 # . epilogue +26753 89/<- %esp 5/r32/ebp +26754 5d/pop-to-ebp +26755 c3/return +26756 +26757 mu-stream?: # t: (addr type-tree) -> result/eax: boolean +26758 # . prologue +26759 55/push-ebp +26760 89/<- %ebp 4/r32/esp +26761 # . save registers +26762 51/push-ecx +26763 # ecx = t +26764 8b/-> *(ebp+8) 1/r32/ecx +26765 # if t->is-atom?, return false +26766 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +26767 75/jump-if-!= $mu-stream?:return-false/disp8 +26768 # if !t->left->is-atom?, return false +26769 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26770 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +26771 74/jump-if-= $mu-stream?:return-false/disp8 +26772 # return t->left->value == stream +26773 81 7/subop/compare *(eax+4) 0xb/imm32/stream-type-id # Type-tree-value +26774 0f 94/set-if-= %al +26775 25/and-eax-with 0xff/imm32 +26776 eb/jump $mu-stream?:end/disp8 +26777 $mu-stream?:return-false: +26778 b8/copy-to-eax 0/imm32/false +26779 $mu-stream?:end: +26780 # . restore registers +26781 59/pop-to-ecx +26782 # . epilogue +26783 89/<- %esp 5/r32/ebp +26784 5d/pop-to-ebp +26785 c3/return +26786 +26787 # size of a statically allocated stream where the size is part of the type expression +26788 size-of-stream: # a: (addr type-tree) -> result/eax: int +26789 # . prologue +26790 55/push-ebp +26791 89/<- %ebp 4/r32/esp +26792 # +26793 (size-of-array *(ebp+8)) # assumes we ignore the actual type name 'array' in the type +26794 05/add-to-eax 8/imm32 # for read/write pointers +26795 $size-of-stream:end: +26796 # . epilogue +26797 89/<- %esp 5/r32/ebp +26798 5d/pop-to-ebp +26799 c3/return +26800 +26801 size-of-type-id: # t: type-id -> result/eax: int +26802 # . prologue +26803 55/push-ebp +26804 89/<- %ebp 4/r32/esp +26805 # . save registers +26806 51/push-ecx +26807 # var out/ecx: (handle typeinfo) +26808 68/push 0/imm32 +26809 68/push 0/imm32 +26810 89/<- %ecx 4/r32/esp +26811 # eax = t +26812 8b/-> *(ebp+8) 0/r32/eax +26813 # if t is a literal, return 0 +26814 3d/compare-eax-and 0/imm32 +26815 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int +26816 # if t is a byte, return 4 (because we don't really support non-multiples of 4) +26817 3d/compare-eax-and 8/imm32/byte +26818 { +26819 75/jump-if-!= break/disp8 +26820 b8/copy-to-eax 4/imm32 +26821 eb/jump $size-of-type-id:end/disp8 +26822 } +26823 # if t is a handle, return 8 +26824 3d/compare-eax-and 4/imm32/handle +26825 { +26826 75/jump-if-!= break/disp8 +26827 b8/copy-to-eax 8/imm32 +26828 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int +26829 } +26830 # if t is a slice, return 8 +26831 3d/compare-eax-and 0xc/imm32/slice +26832 { +26833 75/jump-if-!= break/disp8 +26834 b8/copy-to-eax 8/imm32 +26835 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int +26836 } +26837 # if t is a user-defined type, return its size +26838 # TODO: support non-atom type +26839 (find-typeinfo %eax %ecx) +26840 { +26841 81 7/subop/compare *ecx 0/imm32 +26842 74/jump-if-= break/disp8 +26843 $size-of-type-id:user-defined: +26844 (lookup *ecx *(ecx+4)) # => eax +26845 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes +26846 eb/jump $size-of-type-id:end/disp8 +26847 } +26848 # otherwise return the word size +26849 b8/copy-to-eax 4/imm32 +26850 $size-of-type-id:end: +26851 # . reclaim locals +26852 81 0/subop/add %esp 8/imm32 +26853 # . restore registers +26854 59/pop-to-ecx +26855 # . epilogue +26856 89/<- %esp 5/r32/ebp +26857 5d/pop-to-ebp +26858 c3/return +26859 +26860 # Minor violation of our type system since it returns an addr. But we could +26861 # replace it with a handle some time. +26862 # Returns null if t is an atom. +26863 type-tail: # t: (addr type-tree) -> out/eax: (addr type-tree) +26864 # . prologue +26865 55/push-ebp +26866 89/<- %ebp 4/r32/esp +26867 # . save registers +26868 51/push-ecx +26869 # eax = 0 +26870 b8/copy-to-eax 0/imm32 +26871 # ecx = t +26872 8b/-> *(ebp+8) 1/r32/ecx +26873 $type-tail:check-atom: +26874 # if t->is-atom? return 0 +26875 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +26876 0f 85/jump-if-!= $type-tail:end/disp32 +26877 # var tail = t->right +26878 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +26879 89/<- %ecx 0/r32/eax +26880 $type-tail:check-singleton: +26881 # if (tail->right == 0) return tail->left +26882 { +26883 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-right +26884 75/jump-if-!= break/disp8 +26885 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26886 e9/jump $type-tail:end/disp32 +26887 } +26888 # if tail->right->left is an array-capacity, return tail->left +26889 { +26890 $type-tail:check-array-capacity: +26891 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +26892 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +26893 75/jump-if-!= break/disp8 +26894 $type-tail:check-array-capacity-1: +26895 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +26896 3d/compare-eax-and 0/imm32 +26897 74/jump-if-= break/disp8 +26898 $type-tail:check-array-capacity-2: +26899 (simple-mu-type? %eax 9) # array-capacity => eax +26900 3d/compare-eax-and 0/imm32/false +26901 74/jump-if-= break/disp8 +26902 $type-tail:array-capacity: +26903 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26904 eb/jump $type-tail:end/disp8 +26905 } +26906 $type-tail:check-compound-left: +26907 # if !tail->left->is-atom? return tail->left +26908 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26909 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +26910 74/jump-if-= $type-tail:end/disp8 +26911 $type-tail:return-tail: +26912 # return tail +26913 89/<- %eax 1/r32/ecx +26914 $type-tail:end: +26915 # . restore registers +26916 59/pop-to-ecx +26917 # . epilogue +26918 89/<- %esp 5/r32/ebp +26919 5d/pop-to-ebp +26920 c3/return +26921 +26922 type-equal?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean +26923 # . prologue +26924 55/push-ebp +26925 89/<- %ebp 4/r32/esp +26926 # . save registers +26927 51/push-ecx +26928 52/push-edx +26929 53/push-ebx +26930 # ecx = a +26931 8b/-> *(ebp+8) 1/r32/ecx +26932 # edx = b +26933 8b/-> *(ebp+0xc) 2/r32/edx +26934 $type-equal?:compare-addr: +26935 # if (a == b) return true +26936 8b/-> %ecx 0/r32/eax # Var-type +26937 39/compare %edx 0/r32/eax # Var-type +26938 b8/copy-to-eax 1/imm32/true +26939 0f 84/jump-if-= $type-equal?:end/disp32 +26940 $type-equal?:compare-null-a: +26941 # if (a == 0) return false +26942 b8/copy-to-eax 0/imm32/false +26943 81 7/subop/compare %ecx 0/imm32 +26944 0f 84/jump-if-= $type-equal?:end/disp32 +26945 $type-equal?:compare-null-b: +26946 # if (b == 0) return false +26947 81 7/subop/compare %edx 0/imm32 +26948 0f 84/jump-if-= $type-equal?:end/disp32 +26949 $type-equal?:compare-atom-state: +26950 # if (a->is-atom? != b->is-atom?) return false +26951 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom +26952 39/compare *edx 3/r32/ebx # Type-tree-is-atom +26953 b8/copy-to-eax 0/imm32/false +26954 0f 85/jump-if-!= $type-equal?:end/disp32 +26955 # if a->is-atom? return (a->value == b->value) +26956 { +26957 $type-equal?:check-atom: +26958 81 7/subop/compare %ebx 0/imm32/false +26959 74/jump-if-= break/disp8 +26960 $type-equal?:is-atom: +26961 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value +26962 39/compare *(edx+4) 0/r32/eax # Type-tree-value +26963 0f 94/set-if-= %al +26964 25/and-eax-with 0xff/imm32 +26965 e9/jump $type-equal?:end/disp32 +26966 } +26967 $type-equal?:check-left: +26968 # if (!type-equal?(a->left, b->left)) return false +26969 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +26970 89/<- %ebx 0/r32/eax +26971 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +26972 (type-equal? %eax %ebx) # => eax +26973 3d/compare-eax-and 0/imm32/false +26974 74/jump-if-= $type-equal?:end/disp8 +26975 $type-equal?:check-right: +26976 # return type-equal?(a->right, b->right) +26977 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +26978 89/<- %ebx 0/r32/eax +26979 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax +26980 (type-equal? %eax %ebx) # => eax +26981 $type-equal?:end: +26982 # . restore registers +26983 5b/pop-to-ebx +26984 5a/pop-to-edx +26985 59/pop-to-ecx +26986 # . epilogue +26987 89/<- %esp 5/r32/ebp +26988 5d/pop-to-ebp +26989 c3/return +26990 +26991 ####################################################### +26992 # Code-generation +26993 ####################################################### +26994 +26995 == data +26996 +26997 # Global state added to each var record when performing code-generation. +26998 Curr-local-stack-offset: # (addr int) +26999 0/imm32 +27000 +27001 == code +27002 +27003 # We may not need to pass err/ed everywhere here. I think they're relics of Mu +27004 # getting type checks later in life. +27005 # But we do need them for runtime checks, particularly array index bounds checks. +27006 # So perhaps it's not worth taking them out. They're a safety net. +27007 +27008 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) +27009 # . prologue +27010 55/push-ebp +27011 89/<- %ebp 4/r32/esp +27012 # . save registers +27013 50/push-eax +27014 # var curr/eax: (addr function) = *Program->functions +27015 (lookup *_Program-functions *_Program-functions->payload) # => eax +27016 { +27017 # if (curr == null) break +27018 3d/compare-eax-and 0/imm32 +27019 0f 84/jump-if-= break/disp32 +27020 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) +27021 # curr = lookup(curr->next) +27022 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax +27023 e9/jump loop/disp32 +27024 } +27025 $emit-subx:end: +27026 # . restore registers +27027 58/pop-to-eax +27028 # . epilogue +27029 89/<- %esp 5/r32/ebp +27030 5d/pop-to-ebp +27031 c3/return +27032 +27033 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +27034 # . prologue +27035 55/push-ebp +27036 89/<- %ebp 4/r32/esp +27037 # some preprocessing +27038 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) +27039 # . save registers +27040 50/push-eax +27041 51/push-ecx +27042 52/push-edx +27043 # initialize some global state +27044 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase +27045 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 +27046 # ecx = f +27047 8b/-> *(ebp+0xc) 1/r32/ecx +27048 # var vars/edx: (stack (addr var) 256) +27049 81 5/subop/subtract %esp 0xc00/imm32 +27050 68/push 0xc00/imm32/size +27051 68/push 0/imm32/top +27052 89/<- %edx 4/r32/esp +27053 # var name/eax: (addr array byte) = lookup(f->name) +27054 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +27055 # +27056 (write-buffered *(ebp+8) %eax) +27057 (write-buffered *(ebp+8) ":\n") +27058 (emit-subx-prologue *(ebp+8)) +27059 # var body/eax: (addr block) = lookup(f->body) +27060 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax +27061 # +27062 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +27063 (emit-subx-epilogue *(ebp+8)) +27064 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have +27065 # been cleaned up +27066 $emit-subx-function:end: +27067 # . reclaim locals +27068 81 0/subop/add %esp 0xc08/imm32 +27069 # . restore registers +27070 5a/pop-to-edx +27071 59/pop-to-ecx +27072 58/pop-to-eax +27073 # . epilogue +27074 89/<- %esp 5/r32/ebp +27075 5d/pop-to-ebp +27076 c3/return +27077 +27078 populate-mu-type-offsets-in-inouts: # f: (addr function) +27079 # . prologue +27080 55/push-ebp +27081 89/<- %ebp 4/r32/esp +27082 # . save registers +27083 50/push-eax +27084 51/push-ecx +27085 52/push-edx +27086 53/push-ebx +27087 57/push-edi +27088 # var next-offset/edx: int = 8 +27089 ba/copy-to-edx 8/imm32 +27090 # var curr/ecx: (addr list var) = lookup(f->inouts) +27091 8b/-> *(ebp+8) 1/r32/ecx +27092 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax +27093 89/<- %ecx 0/r32/eax +27094 { +27095 $populate-mu-type-offsets-in-inouts:loop: +27096 81 7/subop/compare %ecx 0/imm32 +27097 74/jump-if-= break/disp8 +27098 # var v/ebx: (addr var) = lookup(curr->value) +27099 (lookup *ecx *(ecx+4)) # List-value List-value => eax +27100 89/<- %ebx 0/r32/eax +27101 #? (lookup *ebx *(ebx+4)) +27102 #? (write-buffered Stderr "setting offset of fn inout ") +27103 #? (write-buffered Stderr %eax) +27104 #? (write-buffered Stderr "@") +27105 #? (write-int32-hex-buffered Stderr %ebx) +27106 #? (write-buffered Stderr " to ") +27107 #? (write-int32-hex-buffered Stderr %edx) +27108 #? (write-buffered Stderr Newline) +27109 #? (flush Stderr) +27110 # v->offset = next-offset +27111 89/<- *(ebx+0x14) 2/r32/edx # Var-offset +27112 # next-offset += size-of(v) +27113 (size-of %ebx) # => eax +27114 01/add-to %edx 0/r32/eax +27115 # curr = lookup(curr->next) +27116 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +27117 89/<- %ecx 0/r32/eax +27118 # +27119 eb/jump loop/disp8 +27120 } +27121 $populate-mu-type-offsets-in-inouts:end: +27122 # . restore registers +27123 5f/pop-to-edi +27124 5b/pop-to-ebx +27125 5a/pop-to-edx +27126 59/pop-to-ecx +27127 58/pop-to-eax +27128 # . epilogue +27129 89/<- %esp 5/r32/ebp +27130 5d/pop-to-ebp +27131 c3/return +27132 +27133 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (addr list stmt), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +27134 # . prologue +27135 55/push-ebp +27136 89/<- %ebp 4/r32/esp +27137 # . save registers +27138 50/push-eax +27139 51/push-ecx +27140 53/push-ebx +27141 56/push-esi +27142 # esi = stmts +27143 8b/-> *(ebp+0xc) 6/r32/esi +27144 # +27145 { +27146 $emit-subx-stmt-list:loop: +27147 81 7/subop/compare %esi 0/imm32 +27148 0f 84/jump-if-= break/disp32 +27149 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) +27150 (lookup *esi *(esi+4)) # List-value List-value => eax +27151 89/<- %ecx 0/r32/eax +27152 { +27153 $emit-subx-stmt-list:check-for-block: +27154 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +27155 75/jump-if-!= break/disp8 +27156 $emit-subx-stmt-list:block: +27157 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +27158 } +27159 { +27160 $emit-subx-stmt-list:check-for-stmt: +27161 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag +27162 0f 85/jump-if-!= break/disp32 +27163 $emit-subx-stmt-list:stmt1: +27164 { +27165 (mu-branch? %ecx) # => eax +27166 3d/compare-eax-and 0/imm32/false +27167 0f 84/jump-if-= break/disp32 +27168 $emit-subx-stmt-list:branch-stmt: +27169 +-- 25 lines: # unconditional return ---------------------------------------------------------------------------------------------------------------------------------------------------- +27194 +-- 27 lines: # unconditional loops ----------------------------------------------------------------------------------------------------------------------------------------------------- +27221 +-- 16 lines: # unconditional breaks ---------------------------------------------------------------------------------------------------------------------------------------------------- +27237 +-- 38 lines: # simple conditional branches without a target ---------------------------------------------------------------------------------------------------------------------------- +27275 +-- 19 lines: # conditional branches with an explicit target ---------------------------------------------------------------------------------------------------------------------------- +27294 } +27295 $emit-subx-stmt-list:1-to-1: +27296 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +27297 e9/jump $emit-subx-stmt-list:continue/disp32 +27298 } +27299 { +27300 $emit-subx-stmt-list:check-for-var-def: +27301 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag +27302 75/jump-if-!= break/disp8 +27303 $emit-subx-stmt-list:var-def: +27304 (emit-subx-var-def *(ebp+8) %ecx *(ebp+0x18) *(ebp+0x1c)) +27305 (push *(ebp+0x10) *(ecx+4)) # Vardef-var +27306 (push *(ebp+0x10) *(ecx+8)) # Vardef-var +27307 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack +27308 # +27309 eb/jump $emit-subx-stmt-list:continue/disp8 +27310 } +27311 { +27312 $emit-subx-stmt-list:check-for-reg-var-def: +27313 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag +27314 0f 85/jump-if-!= break/disp32 +27315 $emit-subx-stmt-list:reg-var-def: +27316 # TODO: ensure that there's exactly one output +27317 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +27318 # emit the instruction as usual +27319 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +27320 # +27321 eb/jump $emit-subx-stmt-list:continue/disp8 +27322 } +27323 $emit-subx-stmt-list:continue: +27324 # TODO: raise an error on unrecognized Stmt-tag +27325 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax +27326 89/<- %esi 0/r32/eax +27327 e9/jump loop/disp32 +27328 } +27329 $emit-subx-stmt-list:emit-cleanup: +27330 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) +27331 $emit-subx-stmt-list:clean-up: +27332 (clean-up-stack-offset-state *(ebp+0x10) *Curr-block-depth) +27333 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14)) +27334 $emit-subx-stmt-list:end: +27335 # . restore registers +27336 5e/pop-to-esi +27337 5b/pop-to-ebx +27338 59/pop-to-ecx +27339 58/pop-to-eax +27340 # . epilogue +27341 89/<- %esp 5/r32/ebp +27342 5d/pop-to-ebp +27343 c3/return +27344 +27345 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. +27346 push-output-and-maybe-emit-spill: # out: (addr buffered-file), stmt: (addr reg-var-def), vars: (addr stack (handle var)), later-stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +27347 # . prologue +27348 55/push-ebp +27349 89/<- %ebp 4/r32/esp +27350 # . save registers +27351 50/push-eax +27352 51/push-ecx +27353 52/push-edx +27354 # ecx = stmt +27355 8b/-> *(ebp+0xc) 1/r32/ecx +27356 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) +27357 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax +27358 # TODO: assert !sv->is-deref? +27359 # var v/ecx: (addr var) = lookup(sv->value) +27360 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +27361 89/<- %ecx 0/r32/eax +27362 # v->block-depth = *Curr-block-depth +27363 8b/-> *Curr-block-depth 0/r32/eax +27364 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +27365 #? (write-buffered Stderr "var ") +27366 #? (lookup *ecx *(ecx+4)) +27367 #? (write-buffered Stderr %eax) +27368 #? (write-buffered Stderr " at depth ") +27369 #? (write-int32-hex-buffered Stderr *(ecx+0x10)) +27370 #? (write-buffered Stderr Newline) +27371 #? (flush Stderr) +27372 # ensure that v is in a register +27373 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +27374 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 +27375 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn) +27376 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax +27377 89/<- %edx 0/r32/eax +27378 3d/compare-eax-and 0/imm32/false +27379 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 +27380 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax +27381 89/<- %edx 0/r32/eax +27382 # check emit-spill? +27383 3d/compare-eax-and 0/imm32/false +27384 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 +27385 # TODO: assert(size-of(output) == 4) +27386 # *Curr-local-stack-offset -= 4 +27387 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 +27388 # emit spill +27389 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +27390 (emit-push-register *(ebp+8) %eax) +27391 $push-output-and-maybe-emit-spill:push: +27392 8b/-> *(ebp+0xc) 1/r32/ecx +27393 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax +27394 # push(vars, {sv->value, emit-spill?}) +27395 (push *(ebp+0x10) *eax) # Stmt-var-value +27396 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value +27397 (push *(ebp+0x10) %edx) +27398 $push-output-and-maybe-emit-spill:end: +27399 # . restore registers +27400 5a/pop-to-edx +27401 59/pop-to-ecx +27402 58/pop-to-eax +27403 # . epilogue +27404 89/<- %esp 5/r32/ebp +27405 5d/pop-to-ebp +27406 c3/return +27407 +27408 $push-output-and-maybe-emit-spill:abort: +27409 # error("var '" var->name "' initialized from an instruction must live in a register\n") +27410 (write-buffered *(ebp+0x1c) "var '") +27411 (write-buffered *(ebp+0x1c) *eax) # Var-name +27412 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n") +27413 (flush *(ebp+0x1c)) +27414 (stop *(ebp+0x20) 1) +27415 # never gets here +27416 +27417 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) +27418 # . prologue +27419 55/push-ebp +27420 89/<- %ebp 4/r32/esp +27421 # . save registers +27422 50/push-eax +27423 51/push-ecx +27424 # ecx = stmt +27425 8b/-> *(ebp+0xc) 1/r32/ecx +27426 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name +27427 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +27428 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +27429 (lookup *eax *(eax+4)) # Var-name Var-name => eax +27430 # clean up until target block +27431 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) +27432 # emit jump to target block +27433 (emit-indent *(ebp+8) *Curr-block-depth) +27434 (write-buffered *(ebp+8) "e9/jump ") +27435 (write-buffered *(ebp+8) %eax) +27436 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +27437 (string-starts-with? %eax "break") +27438 3d/compare-eax-and 0/imm32/false +27439 { +27440 74/jump-if-= break/disp8 +27441 (write-buffered *(ebp+8) ":break/disp32\n") +27442 eb/jump $emit-subx-cleanup-and-unconditional-nonlocal-branch:end/disp8 +27443 } +27444 (write-buffered *(ebp+8) ":loop/disp32\n") +27445 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: +27446 # . restore registers +27447 59/pop-to-ecx +27448 58/pop-to-eax +27449 # . epilogue +27450 89/<- %esp 5/r32/ebp +27451 5d/pop-to-ebp +27452 c3/return +27453 +27454 emit-outputs: # out: (addr buffered-file), return-stmt: (addr stmt1), fn: (addr function) +27455 # . prologue +27456 55/push-ebp +27457 89/<- %ebp 4/r32/esp +27458 # . save registers +27459 50/push-eax +27460 51/push-ecx +27461 56/push-esi +27462 57/push-edi +27463 # var curr-inout/esi: (addr stmt-var) = return-stmt->inouts +27464 8b/-> *(ebp+0xc) 0/r32/eax +27465 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +27466 89/<- %esi 0/r32/eax +27467 # var curr-output/edi: (addr list var) = fn->outputs +27468 8b/-> *(ebp+0x10) 0/r32/eax +27469 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax +27470 89/<- %edi 0/r32/eax +27471 { +27472 $emit-outputs:loop: +27473 81 7/subop/compare %esi 0/imm32 +27474 0f 84/jump-if-= break/disp32 +27475 # emit copy to output register +27476 # var curr-output-register/ecx: (addr array byte) = curr-output->value->register +27477 (lookup *edi *(edi+4)) # List-value List-value => eax +27478 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +27479 89/<- %ecx 0/r32/eax +27480 # if curr-output-register starts with "x", emit a floating-point copy +27481 8a/copy-byte *(ecx+4) 0/r32/AL +27482 25/and-eax-with 0xff/imm32 +27483 3d/compare-eax-and 0x78/imm32/x +27484 { +27485 75/jump-if-!= break/disp8 +27486 (emit-float-output *(ebp+8) %esi %ecx) +27487 eb/jump $emit-outputs:continue/disp8 +27488 } +27489 # otherwise emit an int copy +27490 (emit-int-output *(ebp+8) %esi %ecx) +27491 $emit-outputs:continue: +27492 # curr-inout = curr-inout->next +27493 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +27494 89/<- %esi 0/r32/eax +27495 # curr-output = curr-output->next +27496 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +27497 89/<- %edi 0/r32/eax +27498 # +27499 e9/jump loop/disp32 +27500 } +27501 $emit-outputs:end: +27502 # . restore registers +27503 5f/pop-to-edi +27504 5e/pop-to-esi +27505 59/pop-to-ecx +27506 58/pop-to-eax +27507 # . epilogue +27508 89/<- %esp 5/r32/ebp +27509 5d/pop-to-ebp +27510 c3/return +27511 +27512 emit-int-output: # out: (addr buffered-file), return-var: (addr stmt-var), dest-reg: (addr array byte) +27513 # . prologue +27514 55/push-ebp +27515 89/<- %ebp 4/r32/esp +27516 # . save registers +27517 50/push-eax +27518 51/push-ecx +27519 # ecx = return-var->value +27520 8b/-> *(ebp+0xc) 0/r32/eax +27521 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +27522 89/<- %ecx 0/r32/eax +27523 # if curr-var is a literal, emit copy of a literal to the output +27524 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +27525 (simple-mu-type? %eax 0) # literal => eax +27526 { +27527 3d/compare-eax-and 0/imm32/false +27528 0f 84/jump-if-= break/disp32 +27529 (emit-indent *(ebp+8) *Curr-block-depth) +27530 (write-buffered *(ebp+8) "c7 0/subop/copy %") +27531 (write-buffered *(ebp+8) *(ebp+0x10)) +27532 (write-buffered *(ebp+8) " ") +27533 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +27534 (write-buffered *(ebp+8) %eax) +27535 (write-buffered *(ebp+8) "/imm32\n") +27536 e9/jump $emit-int-output:end/disp32 +27537 } +27538 # otherwise emit an integer copy +27539 (emit-indent *(ebp+8) *Curr-block-depth) +27540 (write-buffered *(ebp+8) "8b/->") +27541 (emit-subx-var-as-rm32 *(ebp+8) *(ebp+0xc)) +27542 (write-buffered *(ebp+8) " ") +27543 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax +27544 (write-int32-hex-buffered *(ebp+8) *eax) +27545 (write-buffered *(ebp+8) "/r32\n") +27546 $emit-int-output:end: +27547 # . restore registers +27548 59/pop-to-ecx +27549 58/pop-to-eax +27550 # . epilogue +27551 89/<- %esp 5/r32/ebp +27552 5d/pop-to-ebp +27553 c3/return +27554 +27555 emit-float-output: # out: (addr buffered-file), return-var: (addr stmt-var), dest-reg: (addr array byte) +27556 # . prologue +27557 55/push-ebp +27558 89/<- %ebp 4/r32/esp +27559 # . save registers +27560 50/push-eax +27561 # +27562 (emit-indent *(ebp+8) *Curr-block-depth) +27563 (write-buffered *(ebp+8) "f3 0f 10/->") +27564 (emit-subx-var-as-rm32 *(ebp+8) *(ebp+0xc)) +27565 (write-buffered *(ebp+8) " ") +27566 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax +27567 (write-int32-hex-buffered *(ebp+8) *eax) +27568 (write-buffered *(ebp+8) "/x32\n") +27569 $emit-float-output:end: +27570 # . restore registers +27571 58/pop-to-eax +27572 # . epilogue +27573 89/<- %esp 5/r32/ebp +27574 5d/pop-to-ebp +27575 c3/return +27576 +27577 mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean +27578 # . prologue +27579 55/push-ebp +27580 89/<- %ebp 4/r32/esp +27581 # . save registers +27582 51/push-ecx +27583 # ecx = lookup(stmt->operation) +27584 8b/-> *(ebp+8) 1/r32/ecx +27585 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +27586 89/<- %ecx 0/r32/eax +27587 # if (stmt->operation starts with "loop") return true +27588 (string-starts-with? %ecx "loop") # => eax +27589 3d/compare-eax-and 0/imm32/false +27590 75/jump-if-not-equal $mu-branch?:end/disp8 +27591 # if (stmt->operation starts with "break") return true +27592 (string-starts-with? %ecx "break") # => eax +27593 3d/compare-eax-and 0/imm32/false +27594 75/jump-if-not-equal $mu-branch?:end/disp8 +27595 # otherwise return (stmt->operation starts with "return") +27596 (string-starts-with? %ecx "return") # => eax +27597 $mu-branch?:end: +27598 # . restore registers +27599 59/pop-to-ecx +27600 # . epilogue +27601 89/<- %esp 5/r32/ebp +27602 5d/pop-to-ebp +27603 c3/return +27604 +27605 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) +27606 # . prologue +27607 55/push-ebp +27608 89/<- %ebp 4/r32/esp +27609 # . save registers +27610 50/push-eax +27611 # eax = stmt +27612 8b/-> *(ebp+0xc) 0/r32/eax +27613 # +27614 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +27615 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) +27616 (emit-indent *(ebp+8) *Curr-block-depth) +27617 (lookup *eax *(eax+4)) # => eax +27618 (write-buffered *(ebp+8) %eax) +27619 (write-buffered *(ebp+8) " break/disp32\n") +27620 $emit-reverse-break:end: +27621 # . restore registers +27622 58/pop-to-eax +27623 # . epilogue +27624 89/<- %esp 5/r32/ebp +27625 5d/pop-to-ebp +27626 c3/return +27627 +27628 == data +27629 +27630 # Table from Mu branch instructions to the reverse SubX opcodes for them. +27631 Reverse-branch: # (table (handle array byte) (handle array byte)) +27632 # a table is a stream +27633 0x240/imm32/write +27634 0/imm32/read +27635 0x240/imm32/size +27636 # data +27637 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 +27638 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 +27639 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 +27640 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 +27641 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 +27642 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 +27643 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 +27644 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 +27645 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_8f_jump_label/imm32 +27646 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_8f_jump_label/imm32 +27647 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 +27648 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 +27649 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +27650 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +27651 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +27652 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +27653 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +27654 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +27655 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +27656 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +27657 0x11/imm32/alloc-id _string-break-if-float</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +27658 0x11/imm32/alloc-id _string-loop-if-float</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +27659 0x11/imm32/alloc-id _string-break-if-float>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +27660 0x11/imm32/alloc-id _string-loop-if-float>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +27661 0x11/imm32/alloc-id _string-break-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +27662 0x11/imm32/alloc-id _string-loop-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +27663 0x11/imm32/alloc-id _string-break-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +27664 0x11/imm32/alloc-id _string-loop-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +27665 0x11/imm32/alloc-id _string-break-if-carry/imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +27666 0x11/imm32/alloc-id _string-loop-if-carry/imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +27667 0x11/imm32/alloc-id _string-break-if-not-carry/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +27668 0x11/imm32/alloc-id _string-loop-if-not-carry/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +27669 0x11/imm32/alloc-id _string-break-if-overflow/imm32 0x11/imm32/alloc-id _string_0f_81_jump_label/imm32 +27670 0x11/imm32/alloc-id _string-loop-if-overflow/imm32 0x11/imm32/alloc-id _string_0f_81_jump_label/imm32 +27671 0x11/imm32/alloc-id _string-break-if-not-overflow/imm32 0x11/imm32/alloc-id _string_0f_80_jump_label/imm32 +27672 0x11/imm32/alloc-id _string-loop-if-not-overflow/imm32 0x11/imm32/alloc-id _string_0f_80_jump_label/imm32 +27673 +27674 == code +27675 +27676 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) +27677 # . prologue +27678 55/push-ebp +27679 89/<- %ebp 4/r32/esp +27680 # . save registers +27681 50/push-eax +27682 51/push-ecx +27683 52/push-edx +27684 53/push-ebx +27685 56/push-esi +27686 # ecx = vars +27687 8b/-> *(ebp+0xc) 1/r32/ecx +27688 # var eax: int = vars->top +27689 8b/-> *ecx 0/r32/eax +27690 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +27691 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +27692 # var min/ecx: (addr handle var) = vars->data +27693 8d/copy-address *(ecx+8) 1/r32/ecx +27694 # edx = depth +27695 8b/-> *(ebp+0x10) 2/r32/edx +27696 { +27697 $emit-unconditional-jump-to-depth:loop: +27698 # if (curr < min) break +27699 39/compare %esi 1/r32/ecx +27700 0f 82/jump-if-addr< break/disp32 +27701 # var v/ebx: (addr var) = lookup(*curr) +27702 (lookup *esi *(esi+4)) # => eax +27703 89/<- %ebx 0/r32/eax +27704 # if (v->block-depth < until-block-depth) break +27705 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +27706 0f 8c/jump-if-< break/disp32 +27707 { +27708 $emit-unconditional-jump-to-depth:check: +27709 # if v->block-depth != until-block-depth, continue +27710 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +27711 0f 85/jump-if-!= break/disp32 +27712 $emit-unconditional-jump-to-depth:depth-found: +27713 # if v is not a literal, continue +27714 (size-of %ebx) # => eax +27715 3d/compare-eax-and 0/imm32 +27716 0f 85/jump-if-!= break/disp32 +27717 $emit-unconditional-jump-to-depth:label-found: +27718 # emit unconditional jump, then return +27719 (emit-indent *(ebp+8) *Curr-block-depth) +27720 (write-buffered *(ebp+8) "e9/jump ") +27721 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +27722 (write-buffered *(ebp+8) %eax) +27723 (write-buffered *(ebp+8) ":") +27724 (write-buffered *(ebp+8) *(ebp+0x14)) +27725 (write-buffered *(ebp+8) "/disp32\n") +27726 eb/jump $emit-unconditional-jump-to-depth:end/disp8 +27727 } +27728 # curr -= 12 +27729 81 5/subop/subtract %esi 0xc/imm32 +27730 e9/jump loop/disp32 +27731 } +27732 # TODO: error if no label at 'depth' was found +27733 $emit-unconditional-jump-to-depth:end: +27734 # . restore registers +27735 5e/pop-to-esi +27736 5b/pop-to-ebx +27737 5a/pop-to-edx +27738 59/pop-to-ecx +27739 58/pop-to-eax +27740 # . epilogue +27741 89/<- %esp 5/r32/ebp +27742 5d/pop-to-ebp +27743 c3/return +27744 +27745 # emit clean-up code for 'vars' until some block depth +27746 # doesn't actually modify 'vars' so we need traverse manually inside the stack +27747 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int +27748 # . prologue +27749 55/push-ebp +27750 89/<- %ebp 4/r32/esp +27751 # . save registers +27752 50/push-eax +27753 51/push-ecx +27754 52/push-edx +27755 53/push-ebx +27756 56/push-esi +27757 #? (write-buffered Stderr "--- cleanup\n") +27758 #? (flush Stderr) +27759 # ecx = vars +27760 8b/-> *(ebp+0xc) 1/r32/ecx +27761 # var esi: int = vars->top +27762 8b/-> *ecx 6/r32/esi +27763 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +27764 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +27765 # var min/ecx: (addr handle var) = vars->data +27766 81 0/subop/add %ecx 8/imm32 +27767 # edx = until-block-depth +27768 8b/-> *(ebp+0x10) 2/r32/edx +27769 { +27770 $emit-cleanup-code-until-depth:loop: +27771 # if (curr < min) break +27772 39/compare %esi 1/r32/ecx +27773 0f 82/jump-if-addr< break/disp32 +27774 # var v/ebx: (addr var) = lookup(*curr) +27775 (lookup *esi *(esi+4)) # => eax +27776 89/<- %ebx 0/r32/eax +27777 #? (lookup *ebx *(ebx+4)) # Var-name +27778 #? (write-buffered Stderr "var ") +27779 #? (write-buffered Stderr %eax) +27780 #? (write-buffered Stderr Newline) +27781 #? (flush Stderr) +27782 # if (v->block-depth < until-block-depth) break +27783 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +27784 0f 8c/jump-if-< break/disp32 +27785 # if v is in a register +27786 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +27787 { +27788 0f 84/jump-if-= break/disp32 +27789 { +27790 $emit-cleanup-code-until-depth:check-for-previous-spill: +27791 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled +27792 3d/compare-eax-and 0/imm32/false +27793 74/jump-if-= break/disp8 +27794 $emit-cleanup-code-until-depth:reclaim-var-in-register: +27795 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +27796 (emit-pop-register *(ebp+8) %eax) +27797 } +27798 eb/jump $emit-cleanup-code-until-depth:continue/disp8 +27799 } +27800 # otherwise v is on the stack +27801 { +27802 75/jump-if-!= break/disp8 +27803 $emit-cleanup-code-until-depth:var-on-stack: +27804 (size-of %ebx) # => eax +27805 # don't emit code for labels +27806 3d/compare-eax-and 0/imm32 +27807 74/jump-if-= break/disp8 +27808 $emit-cleanup-code-until-depth:reclaim-var-on-stack: +27809 (emit-indent *(ebp+8) *Curr-block-depth) +27810 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +27811 (write-int32-hex-buffered *(ebp+8) %eax) +27812 (write-buffered *(ebp+8) "/imm32\n") +27813 } +27814 $emit-cleanup-code-until-depth:continue: +27815 # curr -= 12 +27816 81 5/subop/subtract %esi 0xc/imm32 +27817 e9/jump loop/disp32 +27818 } +27819 $emit-cleanup-code-until-depth:end: +27820 # . restore registers +27821 5e/pop-to-esi +27822 5b/pop-to-ebx +27823 5a/pop-to-edx +27824 59/pop-to-ecx +27825 58/pop-to-eax +27826 # . epilogue +27827 89/<- %esp 5/r32/ebp +27828 5d/pop-to-ebp +27829 c3/return +27830 +27831 # emit clean-up code for 'vars' that don't conflict with output registers +27832 # doesn't actually modify 'vars' so we need traverse manually inside the stack +27833 emit-cleanup-code-for-non-outputs: # out: (addr buffered-file), vars: (addr stack live-var), fn: (addr function) +27834 # . prologue +27835 55/push-ebp +27836 89/<- %ebp 4/r32/esp +27837 # . save registers +27838 50/push-eax +27839 51/push-ecx +27840 52/push-edx +27841 53/push-ebx +27842 56/push-esi +27843 57/push-edi +27844 # ecx = vars +27845 8b/-> *(ebp+0xc) 1/r32/ecx +27846 # var esi: int = vars->top +27847 8b/-> *ecx 6/r32/esi +27848 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +27849 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +27850 # var min/ecx: (addr handle var) = vars->data +27851 81 0/subop/add %ecx 8/imm32 +27852 { +27853 $emit-cleanup-code-for-non-outputs:loop: +27854 # if (curr < min) break +27855 39/compare %esi 1/r32/ecx +27856 0f 82/jump-if-addr< break/disp32 +27857 # var v/ebx: (addr var) = lookup(*curr) +27858 (lookup *esi *(esi+4)) # => eax +27859 89/<- %ebx 0/r32/eax +27860 # if v is in a register +27861 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +27862 { +27863 0f 84/jump-if-= break/disp32 +27864 { +27865 $emit-cleanup-code-for-non-outputs:check-for-previous-spill: +27866 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled +27867 3d/compare-eax-and 0/imm32/false +27868 0f 84/jump-if-= break/disp32 +27869 $emit-cleanup-code-for-non-outputs:reclaim-var-in-register: +27870 # var reg/edi: (addr array name) = v->register +27871 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +27872 89/<- %edi 0/r32/eax +27873 # if reg is not in function outputs, emit a pop +27874 (reg-in-function-outputs? *(ebp+0x10) %edi) # => eax +27875 3d/compare-eax-and 0/imm32/false +27876 { +27877 75/jump-if-!= break/disp8 +27878 (emit-pop-register *(ebp+8) %edi) +27879 eb/jump $emit-cleanup-code-for-non-outputs:reclaim-var-in-register-done/disp8 +27880 } +27881 # otherwise just drop it from the stack +27882 (emit-indent *(ebp+8) *Curr-block-depth) +27883 (write-buffered *(ebp+8) "81 0/subop/add %esp 4/imm32\n") +27884 } +27885 $emit-cleanup-code-for-non-outputs:reclaim-var-in-register-done: +27886 eb/jump $emit-cleanup-code-for-non-outputs:continue/disp8 +27887 } +27888 # otherwise v is on the stack +27889 { +27890 75/jump-if-!= break/disp8 +27891 $emit-cleanup-code-for-non-outputs:var-on-stack: +27892 (size-of %ebx) # => eax +27893 # don't emit code for labels +27894 3d/compare-eax-and 0/imm32 +27895 74/jump-if-= break/disp8 +27896 $emit-cleanup-code-for-non-outputs:reclaim-var-on-stack: +27897 (emit-indent *(ebp+8) *Curr-block-depth) +27898 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +27899 (write-int32-hex-buffered *(ebp+8) %eax) +27900 (write-buffered *(ebp+8) "/imm32\n") +27901 } +27902 $emit-cleanup-code-for-non-outputs:continue: +27903 # curr -= 12 +27904 81 5/subop/subtract %esi 0xc/imm32 +27905 e9/jump loop/disp32 +27906 } +27907 $emit-cleanup-code-for-non-outputs:end: +27908 # . restore registers +27909 5f/pop-to-edi +27910 5e/pop-to-esi +27911 5b/pop-to-ebx +27912 5a/pop-to-edx +27913 59/pop-to-ecx +27914 58/pop-to-eax +27915 # . epilogue +27916 89/<- %esp 5/r32/ebp +27917 5d/pop-to-ebp +27918 c3/return +27919 +27920 emit-push-register: # out: (addr buffered-file), reg: (addr array byte) +27921 # . prologue +27922 55/push-ebp +27923 89/<- %ebp 4/r32/esp +27924 # eax = reg +27925 8b/-> *(ebp+0xc) 0/r32/eax +27926 # var prefix/eax: byte = reg->data[0] +27927 8a/copy-byte *(eax+4) 0/r32/AL +27928 25/and-eax-with 0xff/imm32 +27929 # if (prefix == 'x') push xmm register +27930 { +27931 3d/compare-eax-and 0x78/imm32/x +27932 0f 85/jump-if-!= break/disp32 +27933 # TODO validate register +27934 (emit-indent *(ebp+8) *Curr-block-depth) +27935 (write-buffered *(ebp+8) "81 5/subop/subtract %esp 4/imm32\n") +27936 (emit-indent *(ebp+8) *Curr-block-depth) +27937 (write-buffered *(ebp+8) "f3 0f 11/<- *esp ") +27938 # var prefix/eax: byte = reg->data[3] +27939 8b/-> *(ebp+0xc) 0/r32/eax +27940 8a/copy-byte *(eax+7) 0/r32/AL +27941 25/and-eax-with 0xff/imm32 +27942 (write-byte-buffered *(ebp+8) %eax) +27943 (write-buffered *(ebp+8) "/x32\n") +27944 e9/jump $emit-push-register:end/disp32 +27945 } +27946 # otherwise push gp register +27947 (emit-indent *(ebp+8) *Curr-block-depth) +27948 (write-buffered *(ebp+8) "ff 6/subop/push %") +27949 (write-buffered *(ebp+8) *(ebp+0xc)) +27950 (write-buffered *(ebp+8) Newline) +27951 $emit-push-register:end: +27952 # . epilogue +27953 89/<- %esp 5/r32/ebp +27954 5d/pop-to-ebp +27955 c3/return +27956 +27957 emit-pop-register: # out: (addr buffered-file), reg: (addr array byte) +27958 # . prologue +27959 55/push-ebp +27960 89/<- %ebp 4/r32/esp +27961 # . save registers +27962 50/push-eax +27963 # eax = reg +27964 8b/-> *(ebp+0xc) 0/r32/eax +27965 # var prefix/eax: byte = reg->data[0] +27966 8a/copy-byte *(eax+4) 0/r32/AL +27967 25/and-eax-with 0xff/imm32 +27968 # if (prefix == 'x') pop to xmm register +27969 { +27970 3d/compare-eax-and 0x78/imm32/x +27971 0f 85/jump-if-!= break/disp32 +27972 # TODO validate register +27973 (emit-indent *(ebp+8) *Curr-block-depth) +27974 (write-buffered *(ebp+8) "f3 0f 10/-> *esp ") +27975 # var prefix/eax: byte = reg->data[3] +27976 8b/-> *(ebp+0xc) 0/r32/eax +27977 8a/copy-byte *(eax+7) 0/r32/AL +27978 25/and-eax-with 0xff/imm32 +27979 (write-byte-buffered *(ebp+8) %eax) +27980 (write-buffered *(ebp+8) "/x32\n") +27981 (emit-indent *(ebp+8) *Curr-block-depth) +27982 (write-buffered *(ebp+8) "81 0/subop/add %esp 4/imm32\n") +27983 e9/jump $emit-pop-register:end/disp32 +27984 } +27985 # otherwise pop to gp register +27986 (emit-indent *(ebp+8) *Curr-block-depth) +27987 (write-buffered *(ebp+8) "8f 0/subop/pop %") +27988 (write-buffered *(ebp+8) *(ebp+0xc)) +27989 (write-buffered *(ebp+8) Newline) +27990 $emit-pop-register:end: +27991 # . restore registers +27992 58/pop-to-eax +27993 # . epilogue +27994 89/<- %esp 5/r32/ebp +27995 5d/pop-to-ebp +27996 c3/return +27997 +27998 # emit clean-up code for 'vars' until a given label is encountered +27999 # doesn't actually modify 'vars' so we need traverse manually inside the stack +28000 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) +28001 # . prologue +28002 55/push-ebp +28003 89/<- %ebp 4/r32/esp +28004 # . save registers +28005 50/push-eax +28006 51/push-ecx +28007 52/push-edx +28008 53/push-ebx +28009 # ecx = vars +28010 8b/-> *(ebp+0xc) 1/r32/ecx +28011 # var eax: int = vars->top +28012 8b/-> *ecx 0/r32/eax +28013 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] +28014 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size +28015 # var min/ecx: (addr handle var) = vars->data +28016 81 0/subop/add %ecx 8/imm32 +28017 { +28018 $emit-cleanup-code-until-target:loop: +28019 # if (curr < min) break +28020 39/compare %edx 1/r32/ecx +28021 0f 82/jump-if-addr< break/disp32 +28022 # var v/ebx: (handle var) = lookup(*curr) +28023 (lookup *edx *(edx+4)) # => eax +28024 89/<- %ebx 0/r32/eax +28025 # if (v->name == until-block-label) break +28026 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +28027 (string-equal? %eax *(ebp+0x10)) # => eax +28028 3d/compare-eax-and 0/imm32/false +28029 0f 85/jump-if-!= break/disp32 +28030 # if v is in a register +28031 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +28032 { +28033 0f 84/jump-if-= break/disp32 +28034 { +28035 $emit-cleanup-code-until-target:check-for-previous-spill: +28036 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled +28037 3d/compare-eax-and 0/imm32/false +28038 74/jump-if-= break/disp8 +28039 $emit-cleanup-code-until-target:reclaim-var-in-register: +28040 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +28041 (emit-pop-register *(ebp+8) %eax) +28042 } +28043 eb/jump $emit-cleanup-code-until-target:continue/disp8 +28044 } +28045 # otherwise v is on the stack +28046 { +28047 75/jump-if-!= break/disp8 +28048 $emit-cleanup-code-until-target:reclaim-var-on-stack: +28049 (size-of %ebx) # => eax +28050 # don't emit code for labels +28051 3d/compare-eax-and 0/imm32 +28052 74/jump-if-= break/disp8 +28053 # +28054 (emit-indent *(ebp+8) *Curr-block-depth) +28055 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +28056 (write-int32-hex-buffered *(ebp+8) %eax) +28057 (write-buffered *(ebp+8) "/imm32\n") +28058 } +28059 $emit-cleanup-code-until-target:continue: +28060 # curr -= 12 +28061 81 5/subop/subtract %edx 0xc/imm32 +28062 e9/jump loop/disp32 +28063 } +28064 $emit-cleanup-code-until-target:end: +28065 # . restore registers +28066 5b/pop-to-ebx +28067 5a/pop-to-edx +28068 59/pop-to-ecx +28069 58/pop-to-eax +28070 # . epilogue +28071 89/<- %esp 5/r32/ebp +28072 5d/pop-to-ebp +28073 c3/return +28074 +28075 # update Curr-local-stack-offset assuming vars until some block depth are popped +28076 # doesn't actually modify 'vars', so we need traverse manually inside the stack +28077 clean-up-stack-offset-state: # vars: (addr stack live-var), until-block-depth: int +28078 # . prologue +28079 55/push-ebp +28080 89/<- %ebp 4/r32/esp +28081 # . save registers +28082 50/push-eax +28083 51/push-ecx +28084 52/push-edx +28085 53/push-ebx +28086 56/push-esi +28087 # ecx = vars +28088 8b/-> *(ebp+8) 1/r32/ecx +28089 # var esi: int = vars->top +28090 8b/-> *ecx 6/r32/esi +28091 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +28092 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +28093 # var min/ecx: (addr handle var) = vars->data +28094 81 0/subop/add %ecx 8/imm32 +28095 # edx = until-block-depth +28096 8b/-> *(ebp+0xc) 2/r32/edx +28097 { +28098 $clean-up-stack-offset-state:loop: +28099 # if (curr < min) break +28100 39/compare %esi 1/r32/ecx +28101 0f 82/jump-if-addr< break/disp32 +28102 # var v/ebx: (addr var) = lookup(*curr) +28103 (lookup *esi *(esi+4)) # => eax +28104 89/<- %ebx 0/r32/eax +28105 # if (v->block-depth < until-block-depth) break +28106 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +28107 0f 8c/jump-if-< break/disp32 +28108 # if v is in a register +28109 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +28110 { +28111 0f 84/jump-if-= break/disp32 +28112 { +28113 $clean-up-stack-offset-state:check-for-previous-spill: +28114 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled +28115 3d/compare-eax-and 0/imm32/false +28116 74/jump-if-= break/disp8 +28117 $clean-up-stack-offset-state:reclaim-var-in-register: +28118 81 0/subop/add *Curr-local-stack-offset 4/imm32 +28119 } +28120 eb/jump $clean-up-stack-offset-state:continue/disp8 +28121 } +28122 # otherwise v is on the stack +28123 { +28124 75/jump-if-!= break/disp8 +28125 $clean-up-stack-offset-state:var-on-stack: +28126 (size-of %ebx) # => eax +28127 01/add-to *Curr-local-stack-offset 0/r32/eax +28128 } +28129 $clean-up-stack-offset-state:continue: +28130 # curr -= 12 +28131 81 5/subop/subtract %esi 0xc/imm32 +28132 e9/jump loop/disp32 +28133 } +28134 $clean-up-stack-offset-state:end: +28135 # . restore registers +28136 5e/pop-to-esi +28137 5b/pop-to-ebx +28138 5a/pop-to-edx +28139 59/pop-to-ecx +28140 58/pop-to-eax +28141 # . epilogue +28142 89/<- %esp 5/r32/ebp +28143 5d/pop-to-ebp +28144 c3/return +28145 +28146 # Return true if there isn't a variable in 'vars' with the same block-depth +28147 # and register as 'v'. +28148 # 'v' is guaranteed not to be within 'vars'. +28149 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean +28150 # . prologue +28151 55/push-ebp +28152 89/<- %ebp 4/r32/esp +28153 # . save registers +28154 51/push-ecx +28155 52/push-edx +28156 53/push-ebx +28157 56/push-esi +28158 57/push-edi +28159 # ecx = vars +28160 8b/-> *(ebp+0xc) 1/r32/ecx +28161 # var eax: int = vars->top +28162 8b/-> *ecx 0/r32/eax +28163 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] +28164 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size +28165 # var min/ecx: (addr handle var) = vars->data +28166 8d/copy-address *(ecx+8) 1/r32/ecx +28167 # var depth/ebx: int = v->block-depth +28168 8b/-> *(ebp+8) 3/r32/ebx +28169 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth +28170 # var needle/esi: (addr array byte) = v->register +28171 8b/-> *(ebp+8) 6/r32/esi +28172 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +28173 89/<- %esi 0/r32/eax +28174 { +28175 $not-yet-spilled-this-block?:loop: +28176 # if (curr < min) break +28177 39/compare %edx 1/r32/ecx +28178 0f 82/jump-if-addr< break/disp32 +28179 # var cand/edi: (addr var) = lookup(*curr) +28180 (lookup *edx *(edx+4)) # => eax +28181 89/<- %edi 0/r32/eax +28182 # if (cand->block-depth < depth) break +28183 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth +28184 0f 8c/jump-if-< break/disp32 +28185 # var cand-reg/edi: (array array byte) = cand->reg +28186 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +28187 89/<- %edi 0/r32/eax +28188 # if (cand-reg == null) continue +28189 { +28190 $not-yet-spilled-this-block?:check-reg: +28191 81 7/subop/compare %edi 0/imm32 +28192 0f 84/jump-if-= break/disp32 +28193 # if (cand-reg == needle) return true +28194 (string-equal? %esi %edi) # => eax +28195 3d/compare-eax-and 0/imm32/false +28196 74/jump-if-= break/disp8 +28197 $not-yet-spilled-this-block?:return-false: +28198 b8/copy-to-eax 0/imm32/false +28199 eb/jump $not-yet-spilled-this-block?:end/disp8 +28200 } +28201 $not-yet-spilled-this-block?:continue: +28202 # curr -= 12 +28203 81 5/subop/subtract %edx 0xc/imm32 +28204 e9/jump loop/disp32 +28205 } +28206 $not-yet-spilled-this-block?:return-true: +28207 # return true +28208 b8/copy-to-eax 1/imm32/true +28209 $not-yet-spilled-this-block?:end: +28210 # . restore registers +28211 5f/pop-to-edi +28212 5e/pop-to-esi +28213 5b/pop-to-ebx +28214 5a/pop-to-edx +28215 59/pop-to-ecx +28216 # . epilogue +28217 89/<- %esp 5/r32/ebp +28218 5d/pop-to-ebp +28219 c3/return +28220 +28221 # could the register of 'v' ever be written to by one of the vars in fn-outputs? +28222 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean +28223 # . prologue +28224 55/push-ebp +28225 89/<- %ebp 4/r32/esp +28226 # eax = v +28227 8b/-> *(ebp+8) 0/r32/eax +28228 # var reg/eax: (addr array byte) = lookup(v->register) +28229 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +28230 # var target/eax: (addr var) = find-register(fn-outputs, reg) +28231 (find-register *(ebp+0x10) %eax) # => eax +28232 # if (target == 0) return true +28233 { +28234 3d/compare-eax-and 0/imm32 +28235 75/jump-if-!= break/disp8 +28236 b8/copy-to-eax 1/imm32/true +28237 eb/jump $will-not-write-some-register?:end/disp8 +28238 } +28239 # return !assigns-in-stmts?(stmts, target) +28240 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax +28241 3d/compare-eax-and 0/imm32/false +28242 # assume: true = 1, so no need to mask with 0x000000ff +28243 0f 94/set-if-= %al +28244 $will-not-write-some-register?:end: +28245 # . epilogue +28246 89/<- %esp 5/r32/ebp +28247 5d/pop-to-ebp +28248 c3/return +28249 +28250 # return fn output with matching register +28251 # always returns false if 'reg' is null +28252 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var) +28253 # . prologue +28254 55/push-ebp +28255 89/<- %ebp 4/r32/esp +28256 # . save registers +28257 51/push-ecx +28258 # var curr/ecx: (addr list var) = lookup(fn->outputs) +28259 8b/-> *(ebp+8) 1/r32/ecx +28260 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +28261 89/<- %ecx 0/r32/eax +28262 { +28263 $find-register:loop: +28264 # if (curr == 0) break +28265 81 7/subop/compare %ecx 0/imm32 +28266 74/jump-if-= break/disp8 +28267 # eax = curr->value->register +28268 (lookup *ecx *(ecx+4)) # List-value List-value => eax +28269 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +28270 # if (eax == reg) return curr->value +28271 $find-register:compare: +28272 (string-equal? *(ebp+0xc) %eax) # => eax +28273 { +28274 3d/compare-eax-and 0/imm32/false +28275 74/jump-if-= break/disp8 +28276 $find-register:found: +28277 (lookup *ecx *(ecx+4)) # List-value List-value => eax +28278 eb/jump $find-register:end/disp8 +28279 } +28280 # curr = lookup(curr->next) +28281 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +28282 89/<- %ecx 0/r32/eax +28283 # +28284 eb/jump loop/disp8 +28285 } +28286 $find-register:end: +28287 # . restore registers +28288 59/pop-to-ecx +28289 # . epilogue +28290 89/<- %esp 5/r32/ebp +28291 5d/pop-to-ebp +28292 c3/return +28293 +28294 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean +28295 # . prologue +28296 55/push-ebp +28297 89/<- %ebp 4/r32/esp +28298 # . save registers +28299 51/push-ecx +28300 # var curr/ecx: (addr list stmt) = stmts +28301 8b/-> *(ebp+8) 1/r32/ecx +28302 { +28303 # if (curr == 0) break +28304 81 7/subop/compare %ecx 0/imm32 +28305 74/jump-if-= break/disp8 +28306 # if assigns-in-stmt?(curr->value, v) return true +28307 (lookup *ecx *(ecx+4)) # List-value List-value => eax +28308 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax +28309 3d/compare-eax-and 0/imm32/false +28310 75/jump-if-!= break/disp8 +28311 # curr = lookup(curr->next) +28312 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +28313 89/<- %ecx 0/r32/eax +28314 # +28315 eb/jump loop/disp8 +28316 } +28317 $assigns-in-stmts?:end: +28318 # . restore registers +28319 59/pop-to-ecx +28320 # . epilogue +28321 89/<- %esp 5/r32/ebp +28322 5d/pop-to-ebp +28323 c3/return +28324 +28325 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean +28326 # . prologue +28327 55/push-ebp +28328 89/<- %ebp 4/r32/esp +28329 # . save registers +28330 51/push-ecx +28331 # ecx = stmt +28332 8b/-> *(ebp+8) 1/r32/ecx +28333 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) +28334 { +28335 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag +28336 75/jump-if-!= break/disp8 +28337 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +28338 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax +28339 eb/jump $assigns-in-stmt?:end/disp8 +28340 } +28341 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) +28342 { +28343 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +28344 75/jump-if-!= break/disp8 +28345 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax +28346 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax +28347 eb/jump $assigns-in-stmt?:end/disp8 +28348 } +28349 # otherwise return false +28350 b8/copy 0/imm32/false +28351 $assigns-in-stmt?:end: +28352 # . restore registers +28353 59/pop-to-ecx +28354 # . epilogue +28355 89/<- %esp 5/r32/ebp +28356 5d/pop-to-ebp +28357 c3/return +28358 +28359 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean +28360 # . prologue +28361 55/push-ebp +28362 89/<- %ebp 4/r32/esp +28363 # . save registers +28364 51/push-ecx +28365 # var curr/ecx: (addr stmt-var) = stmt-var +28366 8b/-> *(ebp+8) 1/r32/ecx +28367 { +28368 # if (curr == 0) break +28369 81 7/subop/compare %ecx 0/imm32 +28370 74/jump-if-= break/disp8 +28371 # eax = lookup(curr->value) +28372 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +28373 # if (eax == v && curr->is-deref? == false) return true +28374 { +28375 39/compare *(ebp+0xc) 0/r32/eax +28376 75/jump-if-!= break/disp8 +28377 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +28378 75/jump-if-!= break/disp8 +28379 b8/copy-to-eax 1/imm32/true +28380 eb/jump $assigns-in-stmt-vars?:end/disp8 +28381 } +28382 # curr = lookup(curr->next) +28383 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +28384 89/<- %ecx 0/r32/eax +28385 # +28386 eb/jump loop/disp8 +28387 } +28388 $assigns-in-stmt-vars?:end: +28389 # . restore registers +28390 59/pop-to-ecx +28391 # . epilogue +28392 89/<- %esp 5/r32/ebp +28393 5d/pop-to-ebp +28394 c3/return +28395 +28396 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? +28397 # v is guaranteed to be within vars +28398 # 'start' is provided as an optimization, a pointer within vars +28399 # *start == v +28400 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean +28401 # . prologue +28402 55/push-ebp +28403 89/<- %ebp 4/r32/esp +28404 # . save registers +28405 51/push-ecx +28406 52/push-edx +28407 53/push-ebx +28408 56/push-esi +28409 57/push-edi +28410 # ecx = v +28411 8b/-> *(ebp+8) 1/r32/ecx +28412 # var reg/edx: (addr array byte) = lookup(v->register) +28413 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +28414 89/<- %edx 0/r32/eax +28415 # var depth/ebx: int = v->block-depth +28416 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth +28417 # var min/ecx: (addr handle var) = vars->data +28418 8b/-> *(ebp+0xc) 1/r32/ecx +28419 81 0/subop/add %ecx 8/imm32 +28420 # TODO: check that start >= min and start < &vars->data[top] +28421 # TODO: check that *start == v +28422 # var curr/esi: (addr handle var) = start +28423 8b/-> *(ebp+0x10) 6/r32/esi +28424 # curr -= 8 +28425 81 5/subop/subtract %esi 8/imm32 +28426 { +28427 $same-register-spilled-before?:loop: +28428 # if (curr < min) break +28429 39/compare %esi 1/r32/ecx +28430 0f 82/jump-if-addr< break/disp32 +28431 # var x/eax: (addr var) = lookup(*curr) +28432 (lookup *esi *(esi+4)) # => eax +28433 # if (x->block-depth < depth) break +28434 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth +28435 0f 8c/jump-if-< break/disp32 +28436 # if (x->register == 0) continue +28437 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +28438 74/jump-if-= $same-register-spilled-before?:continue/disp8 +28439 # if (x->register == reg) return true +28440 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +28441 (string-equal? %eax %edx) # => eax +28442 3d/compare-eax-and 0/imm32/false +28443 b8/copy-to-eax 1/imm32/true +28444 75/jump-if-!= $same-register-spilled-before?:end/disp8 +28445 $same-register-spilled-before?:continue: +28446 # curr -= 8 +28447 81 5/subop/subtract %esi 8/imm32 +28448 e9/jump loop/disp32 +28449 } +28450 $same-register-spilled-before?:false: +28451 b8/copy-to-eax 0/imm32/false +28452 $same-register-spilled-before?:end: +28453 # . restore registers +28454 5f/pop-to-edi +28455 5e/pop-to-esi +28456 5b/pop-to-ebx +28457 5a/pop-to-edx +28458 59/pop-to-ecx +28459 # . epilogue +28460 89/<- %esp 5/r32/ebp +28461 5d/pop-to-ebp +28462 c3/return +28463 +28464 # clean up global state for 'vars' until some block depth (inclusive) +28465 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function) +28466 # . prologue +28467 55/push-ebp +28468 89/<- %ebp 4/r32/esp +28469 # . save registers +28470 50/push-eax +28471 51/push-ecx +28472 56/push-esi +28473 # esi = vars +28474 8b/-> *(ebp+8) 6/r32/esi +28475 # ecx = until-block-depth +28476 8b/-> *(ebp+0xc) 1/r32/ecx +28477 { +28478 $clean-up-blocks:reclaim-loop: +28479 # if (vars->top <= 0) break +28480 8b/-> *esi 0/r32/eax # Stack-top +28481 3d/compare-eax-and 0/imm32 +28482 0f 8e/jump-if-<= break/disp32 +28483 # var v/eax: (addr var) = lookup(vars[vars->top-12]) +28484 (lookup *(esi+eax-4) *(esi+eax)) # vars + 8 + vars->top - 12 => eax +28485 # if (v->block-depth < until-block-depth) break +28486 39/compare *(eax+0x10) 1/r32/ecx # Var-block-depth +28487 0f 8c/jump-if-< break/disp32 +28488 (pop %esi) # => eax +28489 (pop %esi) # => eax +28490 (pop %esi) # => eax +28491 e9/jump loop/disp32 +28492 } +28493 $clean-up-blocks:end: +28494 # . restore registers +28495 5e/pop-to-esi +28496 59/pop-to-ecx +28497 58/pop-to-eax +28498 # . epilogue +28499 89/<- %esp 5/r32/ebp +28500 5d/pop-to-ebp +28501 c3/return +28502 +28503 reg-in-function-outputs?: # fn: (addr function), target: (addr array byte) -> result/eax: boolean +28504 # . prologue +28505 55/push-ebp +28506 89/<- %ebp 4/r32/esp +28507 # . save registers +28508 51/push-ecx +28509 # var curr/ecx: (addr list var) = lookup(fn->outputs) +28510 8b/-> *(ebp+8) 0/r32/eax +28511 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax +28512 89/<- %ecx 0/r32/eax +28513 # while curr != null +28514 { +28515 81 7/subop/compare %ecx 0/imm32 +28516 74/jump-if-= break/disp8 +28517 # var v/eax: (addr var) = lookup(curr->value) +28518 (lookup *ecx *(ecx+4)) # List-value List-value => eax +28519 # var reg/eax: (addr array byte) = lookup(v->register) +28520 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +28521 # if (reg == target) return true +28522 (string-equal? %eax *(ebp+0xc)) # => eax +28523 3d/compare-eax-and 0/imm32/false +28524 75/jump-if-!= $reg-in-function-outputs?:end/disp8 +28525 # curr = curr->next +28526 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +28527 89/<- %ecx 0/r32/eax +28528 # +28529 eb/jump loop/disp8 +28530 } +28531 # return false +28532 b8/copy-to-eax 0/imm32 +28533 $reg-in-function-outputs?:end: +28534 # . restore registers +28535 59/pop-to-ecx +28536 # . epilogue +28537 89/<- %esp 5/r32/ebp +28538 5d/pop-to-ebp +28539 c3/return +28540 +28541 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +28542 # . prologue +28543 55/push-ebp +28544 89/<- %ebp 4/r32/esp +28545 # . save registers +28546 50/push-eax +28547 51/push-ecx +28548 52/push-edx +28549 # eax = stmt +28550 8b/-> *(ebp+0xc) 0/r32/eax +28551 # var v/ecx: (addr var) +28552 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax +28553 89/<- %ecx 0/r32/eax +28554 # v->block-depth = *Curr-block-depth +28555 8b/-> *Curr-block-depth 0/r32/eax +28556 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +28557 # var n/edx: int = size-of(stmt->var) +28558 (size-of %ecx) # => eax +28559 89/<- %edx 0/r32/eax +28560 # *Curr-local-stack-offset -= n +28561 29/subtract-from *Curr-local-stack-offset 2/r32/edx +28562 # v->offset = *Curr-local-stack-offset +28563 8b/-> *Curr-local-stack-offset 0/r32/eax +28564 89/<- *(ecx+0x14) 0/r32/eax # Var-offset +28565 # if v is an array, do something special to initialize it +28566 { +28567 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +28568 (mu-array? %eax) # => eax +28569 3d/compare-eax-and 0/imm32/false +28570 0f 84/jump-if-= break/disp32 +28571 # var array-size-without-size/edx: int = n-4 +28572 81 5/subop/subtract %edx 4/imm32 28573 # -28574 eb/jump $emit-subx-var-def:end/disp8 -28575 } -28576 # while n > 0 -28577 { -28578 81 7/subop/compare %edx 0/imm32 -28579 7e/jump-if-<= break/disp8 -28580 (emit-indent *(ebp+8) *Curr-block-depth) -28581 (write-buffered *(ebp+8) "68/push 0/imm32\n") -28582 # n -= 4 -28583 81 5/subop/subtract %edx 4/imm32 -28584 # -28585 eb/jump loop/disp8 -28586 } -28587 $emit-subx-var-def:end: -28588 # . restore registers -28589 5a/pop-to-edx -28590 59/pop-to-ecx -28591 58/pop-to-eax -28592 # . epilogue -28593 89/<- %esp 5/r32/ebp -28594 5d/pop-to-ebp -28595 c3/return -28596 -28597 emit-array-data-initialization: # out: (addr buffered-file), n: int -28598 # . prologue -28599 55/push-ebp -28600 89/<- %ebp 4/r32/esp -28601 # -28602 (emit-indent *(ebp+8) *Curr-block-depth) -28603 (write-buffered *(ebp+8) "(push-n-zero-bytes ") -28604 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) -28605 (write-buffered *(ebp+8) ")\n") -28606 (emit-indent *(ebp+8) *Curr-block-depth) -28607 (write-buffered *(ebp+8) "68/push ") -28608 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) -28609 (write-buffered *(ebp+8) "/imm32\n") -28610 $emit-array-data-initialization:end: -28611 # . epilogue -28612 89/<- %esp 5/r32/ebp -28613 5d/pop-to-ebp -28614 c3/return -28615 -28616 emit-stream-data-initialization: # out: (addr buffered-file), n: int, type: (addr type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) -28617 # . prologue -28618 55/push-ebp -28619 89/<- %ebp 4/r32/esp -28620 # . save registers -28621 50/push-eax -28622 # Optimization: if it's a stream of bytes, don't initialize. -28623 # -28624 # We often construct large temporary streams on the stack for 'trace' -28625 # statements. Initializing such streams can significantly slow programs -28626 # down. -28627 # -28628 # Mu doesn't really depend on initializing stream contents for type- or -28629 # memory-safety; we're mostly doing so to make it easy to debug unsafe -28630 # SubX code that misuses stream objects by manipulating read/write -28631 # pointers. But you can't _really_ protect from unsafe SubX, so I think we -28632 # don't give up much safety or security here. -28633 { -28634 (stream-element-type-id *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) # => eax -28635 3d/compare-eax-and 8/imm32/byte -28636 75/jump-if-!= break/disp8 -28637 (emit-indent *(ebp+8) *Curr-block-depth) -28638 (write-buffered *(ebp+8) "81 5/subop/subtract %esp ") -28639 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) -28640 (write-buffered *(ebp+8) "/imm32\n") -28641 eb/jump $emit-stream-data-initialization:emit-length/disp8 -28642 } -28643 (emit-indent *(ebp+8) *Curr-block-depth) -28644 (write-buffered *(ebp+8) "(push-n-zero-bytes ") -28645 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) -28646 (write-buffered *(ebp+8) ")\n") -28647 $emit-stream-data-initialization:emit-length: -28648 (emit-indent *(ebp+8) *Curr-block-depth) -28649 (write-buffered *(ebp+8) "68/push ") -28650 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) -28651 (write-buffered *(ebp+8) "/imm32\n") -28652 $emit-stream-data-initialization:end: -28653 # . restore registers -28654 58/pop-to-eax -28655 # . epilogue -28656 89/<- %esp 5/r32/ebp -28657 5d/pop-to-ebp -28658 c3/return -28659 -28660 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -28661 # . prologue -28662 55/push-ebp -28663 89/<- %ebp 4/r32/esp -28664 # . save registers -28665 50/push-eax -28666 51/push-ecx -28667 # - some special-case primitives that don't actually use the 'primitives' data structure -28668 # var op/ecx: (addr array byte) = lookup(stmt->operation) -28669 8b/-> *(ebp+0xc) 1/r32/ecx -28670 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -28671 89/<- %ecx 0/r32/eax -28672 # copy byte (can be a primitive except we need to emit a second instruction) -28673 { -28674 # if (!string-equal?(stmt->operation, "copy-byte")) break -28675 (string-equal? %ecx "copy-byte") # => eax -28676 3d/compare-eax-and 0/imm32/false -28677 0f 84/jump-if-= break/disp32 -28678 (translate-mu-copy-byte-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28679 e9/jump $emit-subx-stmt:end/disp32 -28680 } -28681 # copy-byte-to can be a primitive; writes to memory don't need to clear surrounding bytes -28682 # array size -28683 { -28684 # if (!string-equal?(stmt->operation, "length")) break -28685 (string-equal? %ecx "length") # => eax -28686 3d/compare-eax-and 0/imm32/false -28687 0f 84/jump-if-= break/disp32 -28688 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28689 e9/jump $emit-subx-stmt:end/disp32 -28690 } -28691 # index into array -28692 { -28693 # if (!string-equal?(stmt->operation, "index")) break -28694 (string-equal? %ecx "index") # => eax -28695 3d/compare-eax-and 0/imm32/false -28696 0f 84/jump-if-= break/disp32 -28697 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -28698 e9/jump $emit-subx-stmt:end/disp32 -28699 } -28700 # compute-offset for index into array -28701 { -28702 # if (!string-equal?(stmt->operation, "compute-offset")) break -28703 (string-equal? %ecx "compute-offset") # => eax -28704 3d/compare-eax-and 0/imm32/false -28705 0f 84/jump-if-= break/disp32 -28706 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28707 e9/jump $emit-subx-stmt:end/disp32 -28708 } -28709 # get field from record -28710 { -28711 # if (!string-equal?(stmt->operation, "get")) break -28712 (string-equal? %ecx "get") # => eax -28713 3d/compare-eax-and 0/imm32/false -28714 0f 84/jump-if-= break/disp32 -28715 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) -28716 e9/jump $emit-subx-stmt:end/disp32 -28717 } -28718 # allocate scalar -28719 { -28720 # if (!string-equal?(stmt->operation, "allocate")) break -28721 (string-equal? %ecx "allocate") # => eax -28722 3d/compare-eax-and 0/imm32/false -28723 0f 84/jump-if-= break/disp32 -28724 (translate-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28725 e9/jump $emit-subx-stmt:end/disp32 -28726 } -28727 # copy-object -28728 { -28729 # if (!string-equal?(stmt->operation, "copy-object")) break -28730 (string-equal? %ecx "copy-object") # => eax -28731 3d/compare-eax-and 0/imm32/false -28732 0f 84/jump-if-= break/disp32 -28733 (translate-mu-copy-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28734 e9/jump $emit-subx-stmt:end/disp32 -28735 } -28736 # clear-object -28737 { -28738 # if (!string-equal?(stmt->operation, "clear-object")) break -28739 (string-equal? %ecx "clear-object") # => eax -28740 3d/compare-eax-and 0/imm32/false -28741 0f 84/jump-if-= break/disp32 -28742 (translate-mu-clear-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28743 e9/jump $emit-subx-stmt:end/disp32 -28744 } -28745 # allocate array -28746 { -28747 # if (!string-equal?(stmt->operation, "populate")) break -28748 (string-equal? %ecx "populate") # => eax -28749 3d/compare-eax-and 0/imm32/false -28750 0f 84/jump-if-= break/disp32 -28751 (translate-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28752 e9/jump $emit-subx-stmt:end/disp32 -28753 } -28754 # allocate stream -28755 { -28756 # if (!string-equal?(stmt->operation, "populate-stream")) break -28757 (string-equal? %ecx "populate-stream") # => eax -28758 3d/compare-eax-and 0/imm32/false -28759 0f 84/jump-if-= break/disp32 -28760 (translate-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28761 e9/jump $emit-subx-stmt:end/disp32 -28762 } -28763 # read from stream -28764 { -28765 # if (!string-equal?(stmt->operation, "read-from-stream")) break -28766 (string-equal? %ecx "read-from-stream") # => eax -28767 3d/compare-eax-and 0/imm32/false -28768 0f 84/jump-if-= break/disp32 -28769 (translate-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28770 e9/jump $emit-subx-stmt:end/disp32 -28771 } -28772 # write to stream -28773 { -28774 # if (!string-equal?(stmt->operation, "write-to-stream")) break -28775 (string-equal? %ecx "write-to-stream") # => eax -28776 3d/compare-eax-and 0/imm32/false -28777 0f 84/jump-if-= break/disp32 -28778 (translate-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) -28779 e9/jump $emit-subx-stmt:end/disp32 -28780 } -28781 # - optimizations -28782 # if copy instruction has same register in source and destination, emit nothing -28783 (redundant-copy? *(ebp+0xc)) # => eax -28784 3d/compare-eax-and 0/imm32/false -28785 75/jump-if-!= $emit-subx-stmt:end/disp8 -28786 # - if stmt matches a primitive, emit it -28787 { -28788 $emit-subx-stmt:check-for-primitive: -28789 # var curr/eax: (addr primitive) -28790 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax -28791 3d/compare-eax-and 0/imm32 -28792 74/jump-if-= break/disp8 -28793 $emit-subx-stmt:primitive: -28794 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr -28795 e9/jump $emit-subx-stmt:end/disp32 -28796 } -28797 # - otherwise emit a call -28798 # TODO: type-checking -28799 $emit-subx-stmt:call: -28800 (emit-call *(ebp+8) *(ebp+0xc)) -28801 $emit-subx-stmt:end: -28802 # . restore registers -28803 59/pop-to-ecx -28804 58/pop-to-eax -28805 # . epilogue -28806 89/<- %esp 5/r32/ebp -28807 5d/pop-to-ebp -28808 c3/return -28809 -28810 redundant-copy?: # stmt: (addr stmt) -> result/eax: boolean -28811 # . prologue -28812 55/push-ebp -28813 89/<- %ebp 4/r32/esp -28814 # . save registers -28815 56/push-esi -28816 57/push-edi -28817 # esi = stmt -28818 8b/-> *(ebp+8) 6/r32/esi -28819 # if stmt->operation != "copy" return false -28820 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -28821 (string-equal? %eax "copy") # => eax -28822 3d/compare-eax-and 0/imm32/false -28823 0f 84/jump-if-= $redundant-copy?:end/disp32 -28824 # var output-reg/edi: (addr stmt-var) = stmt->outputs->value->register -28825 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -28826 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -28827 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -28828 # . if output-reg == null, return false -28829 3d/compare-eax-and 0/imm32 -28830 74/jump-if-= $redundant-copy?:end/disp8 -28831 89/<- %edi 0/r32/eax -28832 # return (inout->value->register == output->value->register) -28833 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -28834 # . if inout->is-deref return false -28835 81 7/subop/compare *(eax+0x10) 0/imm32/false # Stmt-var-is-deref -28836 { -28837 74/jump-if-= break/disp8 -28838 b8/copy-to-eax 0/imm32/false -28839 e9/jump $redundant-copy?:end/disp32 -28840 } -28841 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -28842 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -28843 # . if inout-reg == null, return false -28844 3d/compare-eax-and 0/imm32 -28845 74/jump-if-= $redundant-copy?:end/disp8 -28846 (string-equal? %eax %edi) # => eax -28847 $redundant-copy?:end: -28848 # . restore registers -28849 5f/pop-to-edi -28850 5e/pop-to-esi -28851 # . epilogue -28852 89/<- %esp 5/r32/ebp -28853 5d/pop-to-ebp -28854 c3/return -28855 -28856 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -28857 # . prologue -28858 55/push-ebp -28859 89/<- %ebp 4/r32/esp -28860 # . save registers -28861 50/push-eax -28862 51/push-ecx -28863 52/push-edx -28864 53/push-ebx -28865 56/push-esi -28866 # esi = stmt -28867 8b/-> *(ebp+0xc) 6/r32/esi -28868 # var base/ebx: (addr var) = stmt->inouts[0]->value -28869 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -28870 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -28871 89/<- %ebx 0/r32/eax -28872 # var elemsize/ecx: int = array-element-size(base) -28873 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -28874 89/<- %ecx 0/r32/eax -28875 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register -28876 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -28877 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -28878 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -28879 89/<- %edx 0/r32/eax -28880 # if elemsize == 1 -28881 { -28882 81 7/subop/compare %ecx 1/imm32 -28883 75/jump-if-!= break/disp8 -28884 $translate-mu-length-stmt:size-1: -28885 (emit-save-size-to *(ebp+8) %ebx %edx) -28886 e9/jump $translate-mu-length-stmt:end/disp32 -28887 } -28888 # if elemsize is a power of 2 less than 256 -28889 { -28890 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -28891 3d/compare-eax-and 0/imm32/false -28892 74/jump-if-= break/disp8 -28893 81 7/subop/compare %ecx 0xff/imm32 -28894 7f/jump-if-> break/disp8 -28895 $translate-mu-length-stmt:size-power-of-2: -28896 (emit-save-size-to *(ebp+8) %ebx %edx) -28897 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) -28898 e9/jump $translate-mu-length-stmt:end/disp32 -28899 } -28900 # otherwise, the complex case -28901 # . emit register spills -28902 { -28903 $translate-mu-length-stmt:complex: -28904 (string-equal? %edx "eax") # => eax -28905 3d/compare-eax-and 0/imm32/false -28906 75/break-if-!= break/disp8 -28907 (emit-indent *(ebp+8) *Curr-block-depth) -28908 (write-buffered *(ebp+8) "50/push-eax\n") -28909 } -28910 { -28911 (string-equal? %edx "ecx") # => eax -28912 3d/compare-eax-and 0/imm32/false -28913 75/break-if-!= break/disp8 -28914 (emit-indent *(ebp+8) *Curr-block-depth) -28915 (write-buffered *(ebp+8) "51/push-ecx\n") -28916 } -28917 { -28918 (string-equal? %edx "edx") # => eax -28919 3d/compare-eax-and 0/imm32/false -28920 75/break-if-!= break/disp8 -28921 (emit-indent *(ebp+8) *Curr-block-depth) -28922 (write-buffered *(ebp+8) "52/push-edx\n") -28923 } -28924 # . -28925 (emit-save-size-to *(ebp+8) %ebx "eax") -28926 (emit-indent *(ebp+8) *Curr-block-depth) -28927 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") -28928 (emit-indent *(ebp+8) *Curr-block-depth) -28929 (write-buffered *(ebp+8) "b9/copy-to-ecx ") -28930 (write-int32-hex-buffered *(ebp+8) %ecx) -28931 (write-buffered *(ebp+8) "/imm32\n") -28932 (emit-indent *(ebp+8) *Curr-block-depth) -28933 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") -28934 { -28935 (string-equal? %edx "eax") # => eax -28936 3d/compare-eax-and 0/imm32/false -28937 75/break-if-!= break/disp8 -28938 (emit-indent *(ebp+8) *Curr-block-depth) -28939 (write-buffered *(ebp+8) "89/<- %") -28940 (write-buffered *(ebp+8) %edx) -28941 (write-buffered *(ebp+8) " 0/r32/eax\n") +28574 (emit-array-data-initialization *(ebp+8) %edx) +28575 e9/jump $emit-subx-var-def:end/disp32 +28576 } +28577 # another special-case for initializing streams +28578 # a stream is an array with 2 extra pointers +28579 { +28580 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +28581 (mu-stream? %eax) # => eax +28582 3d/compare-eax-and 0/imm32/false +28583 0f 84/jump-if-= break/disp32 +28584 # var array-size-without-size/edx: int = n-12 +28585 81 5/subop/subtract %edx 0xc/imm32 +28586 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +28587 (emit-stream-data-initialization *(ebp+8) %edx %eax *(ebp+0x10) *(ebp+0x14)) +28588 # emit read and write pointers +28589 (emit-indent *(ebp+8) *Curr-block-depth) +28590 (write-buffered *(ebp+8) "68/push 0/imm32\n") +28591 (emit-indent *(ebp+8) *Curr-block-depth) +28592 (write-buffered *(ebp+8) "68/push 0/imm32\n") +28593 # +28594 eb/jump $emit-subx-var-def:end/disp8 +28595 } +28596 # while n > 0 +28597 { +28598 81 7/subop/compare %edx 0/imm32 +28599 7e/jump-if-<= break/disp8 +28600 (emit-indent *(ebp+8) *Curr-block-depth) +28601 (write-buffered *(ebp+8) "68/push 0/imm32\n") +28602 # n -= 4 +28603 81 5/subop/subtract %edx 4/imm32 +28604 # +28605 eb/jump loop/disp8 +28606 } +28607 $emit-subx-var-def:end: +28608 # . restore registers +28609 5a/pop-to-edx +28610 59/pop-to-ecx +28611 58/pop-to-eax +28612 # . epilogue +28613 89/<- %esp 5/r32/ebp +28614 5d/pop-to-ebp +28615 c3/return +28616 +28617 emit-array-data-initialization: # out: (addr buffered-file), n: int +28618 # . prologue +28619 55/push-ebp +28620 89/<- %ebp 4/r32/esp +28621 # +28622 (emit-indent *(ebp+8) *Curr-block-depth) +28623 (write-buffered *(ebp+8) "(push-n-zero-bytes ") +28624 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) +28625 (write-buffered *(ebp+8) ")\n") +28626 (emit-indent *(ebp+8) *Curr-block-depth) +28627 (write-buffered *(ebp+8) "68/push ") +28628 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) +28629 (write-buffered *(ebp+8) "/imm32\n") +28630 $emit-array-data-initialization:end: +28631 # . epilogue +28632 89/<- %esp 5/r32/ebp +28633 5d/pop-to-ebp +28634 c3/return +28635 +28636 emit-stream-data-initialization: # out: (addr buffered-file), n: int, type: (addr type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) +28637 # . prologue +28638 55/push-ebp +28639 89/<- %ebp 4/r32/esp +28640 # . save registers +28641 50/push-eax +28642 # Optimization: if it's a stream of bytes, don't initialize. +28643 # +28644 # We often construct large temporary streams on the stack for 'trace' +28645 # statements. Initializing such streams can significantly slow programs +28646 # down. +28647 # +28648 # Mu doesn't really depend on initializing stream contents for type- or +28649 # memory-safety; we're mostly doing so to make it easy to debug unsafe +28650 # SubX code that misuses stream objects by manipulating read/write +28651 # pointers. But you can't _really_ protect from unsafe SubX, so I think we +28652 # don't give up much safety or security here. +28653 { +28654 (stream-element-type-id *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) # => eax +28655 3d/compare-eax-and 8/imm32/byte +28656 75/jump-if-!= break/disp8 +28657 (emit-indent *(ebp+8) *Curr-block-depth) +28658 (write-buffered *(ebp+8) "81 5/subop/subtract %esp ") +28659 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) +28660 (write-buffered *(ebp+8) "/imm32\n") +28661 eb/jump $emit-stream-data-initialization:emit-length/disp8 +28662 } +28663 (emit-indent *(ebp+8) *Curr-block-depth) +28664 (write-buffered *(ebp+8) "(push-n-zero-bytes ") +28665 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) +28666 (write-buffered *(ebp+8) ")\n") +28667 $emit-stream-data-initialization:emit-length: +28668 (emit-indent *(ebp+8) *Curr-block-depth) +28669 (write-buffered *(ebp+8) "68/push ") +28670 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc)) +28671 (write-buffered *(ebp+8) "/imm32\n") +28672 $emit-stream-data-initialization:end: +28673 # . restore registers +28674 58/pop-to-eax +28675 # . epilogue +28676 89/<- %esp 5/r32/ebp +28677 5d/pop-to-ebp +28678 c3/return +28679 +28680 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +28681 # . prologue +28682 55/push-ebp +28683 89/<- %ebp 4/r32/esp +28684 # . save registers +28685 50/push-eax +28686 51/push-ecx +28687 # - some special-case primitives that don't actually use the 'primitives' data structure +28688 # var op/ecx: (addr array byte) = lookup(stmt->operation) +28689 8b/-> *(ebp+0xc) 1/r32/ecx +28690 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +28691 89/<- %ecx 0/r32/eax +28692 # copy byte (can be a primitive except we need to emit a second instruction) +28693 { +28694 # if (!string-equal?(stmt->operation, "copy-byte")) break +28695 (string-equal? %ecx "copy-byte") # => eax +28696 3d/compare-eax-and 0/imm32/false +28697 0f 84/jump-if-= break/disp32 +28698 (translate-mu-copy-byte-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28699 e9/jump $emit-subx-stmt:end/disp32 +28700 } +28701 # copy-byte-to can be a primitive; writes to memory don't need to clear surrounding bytes +28702 # array size +28703 { +28704 # if (!string-equal?(stmt->operation, "length")) break +28705 (string-equal? %ecx "length") # => eax +28706 3d/compare-eax-and 0/imm32/false +28707 0f 84/jump-if-= break/disp32 +28708 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28709 e9/jump $emit-subx-stmt:end/disp32 +28710 } +28711 # index into array +28712 { +28713 # if (!string-equal?(stmt->operation, "index")) break +28714 (string-equal? %ecx "index") # => eax +28715 3d/compare-eax-and 0/imm32/false +28716 0f 84/jump-if-= break/disp32 +28717 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +28718 e9/jump $emit-subx-stmt:end/disp32 +28719 } +28720 # compute-offset for index into array +28721 { +28722 # if (!string-equal?(stmt->operation, "compute-offset")) break +28723 (string-equal? %ecx "compute-offset") # => eax +28724 3d/compare-eax-and 0/imm32/false +28725 0f 84/jump-if-= break/disp32 +28726 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28727 e9/jump $emit-subx-stmt:end/disp32 +28728 } +28729 # get field from record +28730 { +28731 # if (!string-equal?(stmt->operation, "get")) break +28732 (string-equal? %ecx "get") # => eax +28733 3d/compare-eax-and 0/imm32/false +28734 0f 84/jump-if-= break/disp32 +28735 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) +28736 e9/jump $emit-subx-stmt:end/disp32 +28737 } +28738 # allocate scalar +28739 { +28740 # if (!string-equal?(stmt->operation, "allocate")) break +28741 (string-equal? %ecx "allocate") # => eax +28742 3d/compare-eax-and 0/imm32/false +28743 0f 84/jump-if-= break/disp32 +28744 (translate-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28745 e9/jump $emit-subx-stmt:end/disp32 +28746 } +28747 # copy-object +28748 { +28749 # if (!string-equal?(stmt->operation, "copy-object")) break +28750 (string-equal? %ecx "copy-object") # => eax +28751 3d/compare-eax-and 0/imm32/false +28752 0f 84/jump-if-= break/disp32 +28753 (translate-mu-copy-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28754 e9/jump $emit-subx-stmt:end/disp32 +28755 } +28756 # clear-object +28757 { +28758 # if (!string-equal?(stmt->operation, "clear-object")) break +28759 (string-equal? %ecx "clear-object") # => eax +28760 3d/compare-eax-and 0/imm32/false +28761 0f 84/jump-if-= break/disp32 +28762 (translate-mu-clear-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28763 e9/jump $emit-subx-stmt:end/disp32 +28764 } +28765 # allocate array +28766 { +28767 # if (!string-equal?(stmt->operation, "populate")) break +28768 (string-equal? %ecx "populate") # => eax +28769 3d/compare-eax-and 0/imm32/false +28770 0f 84/jump-if-= break/disp32 +28771 (translate-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28772 e9/jump $emit-subx-stmt:end/disp32 +28773 } +28774 # allocate stream +28775 { +28776 # if (!string-equal?(stmt->operation, "populate-stream")) break +28777 (string-equal? %ecx "populate-stream") # => eax +28778 3d/compare-eax-and 0/imm32/false +28779 0f 84/jump-if-= break/disp32 +28780 (translate-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28781 e9/jump $emit-subx-stmt:end/disp32 +28782 } +28783 # read from stream +28784 { +28785 # if (!string-equal?(stmt->operation, "read-from-stream")) break +28786 (string-equal? %ecx "read-from-stream") # => eax +28787 3d/compare-eax-and 0/imm32/false +28788 0f 84/jump-if-= break/disp32 +28789 (translate-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28790 e9/jump $emit-subx-stmt:end/disp32 +28791 } +28792 # write to stream +28793 { +28794 # if (!string-equal?(stmt->operation, "write-to-stream")) break +28795 (string-equal? %ecx "write-to-stream") # => eax +28796 3d/compare-eax-and 0/imm32/false +28797 0f 84/jump-if-= break/disp32 +28798 (translate-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +28799 e9/jump $emit-subx-stmt:end/disp32 +28800 } +28801 # - optimizations +28802 # if copy instruction has same register in source and destination, emit nothing +28803 (redundant-copy? *(ebp+0xc)) # => eax +28804 3d/compare-eax-and 0/imm32/false +28805 75/jump-if-!= $emit-subx-stmt:end/disp8 +28806 # - if stmt matches a primitive, emit it +28807 { +28808 $emit-subx-stmt:check-for-primitive: +28809 # var curr/eax: (addr primitive) +28810 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax +28811 3d/compare-eax-and 0/imm32 +28812 74/jump-if-= break/disp8 +28813 $emit-subx-stmt:primitive: +28814 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr +28815 e9/jump $emit-subx-stmt:end/disp32 +28816 } +28817 # - otherwise emit a call +28818 $emit-subx-stmt:call: +28819 (emit-call *(ebp+8) *(ebp+0xc)) +28820 $emit-subx-stmt:end: +28821 # . restore registers +28822 59/pop-to-ecx +28823 58/pop-to-eax +28824 # . epilogue +28825 89/<- %esp 5/r32/ebp +28826 5d/pop-to-ebp +28827 c3/return +28828 +28829 redundant-copy?: # stmt: (addr stmt) -> result/eax: boolean +28830 # . prologue +28831 55/push-ebp +28832 89/<- %ebp 4/r32/esp +28833 # . save registers +28834 56/push-esi +28835 57/push-edi +28836 # esi = stmt +28837 8b/-> *(ebp+8) 6/r32/esi +28838 # if stmt->operation != "copy" return false +28839 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +28840 (string-equal? %eax "copy") # => eax +28841 3d/compare-eax-and 0/imm32/false +28842 0f 84/jump-if-= $redundant-copy?:end/disp32 +28843 # var output-reg/edi: (addr stmt-var) = stmt->outputs->value->register +28844 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +28845 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +28846 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +28847 # . if output-reg == null, return false +28848 3d/compare-eax-and 0/imm32 +28849 74/jump-if-= $redundant-copy?:end/disp8 +28850 89/<- %edi 0/r32/eax +28851 # return (inout->value->register == output->value->register) +28852 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +28853 # . if inout->is-deref return false +28854 81 7/subop/compare *(eax+0x10) 0/imm32/false # Stmt-var-is-deref +28855 { +28856 74/jump-if-= break/disp8 +28857 b8/copy-to-eax 0/imm32/false +28858 e9/jump $redundant-copy?:end/disp32 +28859 } +28860 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +28861 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +28862 # . if inout-reg == null, return false +28863 3d/compare-eax-and 0/imm32 +28864 74/jump-if-= $redundant-copy?:end/disp8 +28865 (string-equal? %eax %edi) # => eax +28866 $redundant-copy?:end: +28867 # . restore registers +28868 5f/pop-to-edi +28869 5e/pop-to-esi +28870 # . epilogue +28871 89/<- %esp 5/r32/ebp +28872 5d/pop-to-ebp +28873 c3/return +28874 +28875 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +28876 # . prologue +28877 55/push-ebp +28878 89/<- %ebp 4/r32/esp +28879 # . save registers +28880 50/push-eax +28881 51/push-ecx +28882 52/push-edx +28883 53/push-ebx +28884 56/push-esi +28885 # esi = stmt +28886 8b/-> *(ebp+0xc) 6/r32/esi +28887 # var base/ebx: (addr var) = stmt->inouts[0]->value +28888 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +28889 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +28890 89/<- %ebx 0/r32/eax +28891 # var elemsize/ecx: int = array-element-size(base) +28892 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +28893 89/<- %ecx 0/r32/eax +28894 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register +28895 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +28896 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +28897 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +28898 89/<- %edx 0/r32/eax +28899 # if elemsize == 1 +28900 { +28901 81 7/subop/compare %ecx 1/imm32 +28902 75/jump-if-!= break/disp8 +28903 $translate-mu-length-stmt:size-1: +28904 (emit-save-size-to *(ebp+8) %ebx %edx) +28905 e9/jump $translate-mu-length-stmt:end/disp32 +28906 } +28907 # if elemsize is a power of 2 less than 256 +28908 { +28909 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +28910 3d/compare-eax-and 0/imm32/false +28911 74/jump-if-= break/disp8 +28912 81 7/subop/compare %ecx 0xff/imm32 +28913 7f/jump-if-> break/disp8 +28914 $translate-mu-length-stmt:size-power-of-2: +28915 (emit-save-size-to *(ebp+8) %ebx %edx) +28916 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) +28917 e9/jump $translate-mu-length-stmt:end/disp32 +28918 } +28919 # otherwise, the complex case +28920 # . emit register spills +28921 { +28922 $translate-mu-length-stmt:complex: +28923 (string-equal? %edx "eax") # => eax +28924 3d/compare-eax-and 0/imm32/false +28925 75/break-if-!= break/disp8 +28926 (emit-indent *(ebp+8) *Curr-block-depth) +28927 (write-buffered *(ebp+8) "50/push-eax\n") +28928 } +28929 { +28930 (string-equal? %edx "ecx") # => eax +28931 3d/compare-eax-and 0/imm32/false +28932 75/break-if-!= break/disp8 +28933 (emit-indent *(ebp+8) *Curr-block-depth) +28934 (write-buffered *(ebp+8) "51/push-ecx\n") +28935 } +28936 { +28937 (string-equal? %edx "edx") # => eax +28938 3d/compare-eax-and 0/imm32/false +28939 75/break-if-!= break/disp8 +28940 (emit-indent *(ebp+8) *Curr-block-depth) +28941 (write-buffered *(ebp+8) "52/push-edx\n") 28942 } -28943 # . emit register restores -28944 { -28945 (string-equal? %edx "edx") # => eax -28946 3d/compare-eax-and 0/imm32/false -28947 75/break-if-!= break/disp8 -28948 (emit-indent *(ebp+8) *Curr-block-depth) -28949 (write-buffered *(ebp+8) "5a/pop-to-edx\n") -28950 } -28951 { -28952 (string-equal? %edx "ecx") # => eax -28953 3d/compare-eax-and 0/imm32/false -28954 75/break-if-!= break/disp8 -28955 (emit-indent *(ebp+8) *Curr-block-depth) -28956 (write-buffered *(ebp+8) "59/pop-to-ecx\n") -28957 } -28958 { -28959 (string-equal? %edx "eax") # => eax -28960 3d/compare-eax-and 0/imm32/false -28961 75/break-if-!= break/disp8 -28962 (emit-indent *(ebp+8) *Curr-block-depth) -28963 (write-buffered *(ebp+8) "58/pop-to-eax\n") -28964 } -28965 $translate-mu-length-stmt:end: -28966 # . restore registers -28967 5e/pop-to-esi -28968 5b/pop-to-ebx -28969 5a/pop-to-edx -28970 59/pop-to-ecx -28971 58/pop-to-eax -28972 # . epilogue -28973 89/<- %esp 5/r32/ebp -28974 5d/pop-to-ebp -28975 c3/return -28976 -28977 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -28978 # . prologue -28979 55/push-ebp -28980 89/<- %ebp 4/r32/esp -28981 # -28982 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax -28983 (size-of-type-id-as-array-element %eax) # => eax -28984 $array-element-size:end: -28985 # . epilogue -28986 89/<- %esp 5/r32/ebp -28987 5d/pop-to-ebp -28988 c3/return -28989 -28990 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id -28991 # precondition: n is positive -28992 # . prologue -28993 55/push-ebp -28994 89/<- %ebp 4/r32/esp -28995 # -28996 8b/-> *(ebp+8) 0/r32/eax -28997 # var t/eax: (addr type-tree) -28998 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -28999 # if t == 0 abort -29000 3d/compare-eax-with 0/imm32 -29001 0f 84/jump-if-== $array-element-type-id:error0/disp32 -29002 # if t->is-atom? abort -29003 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29004 0f 85/jump-if-!= $array-element-type-id:error1/disp32 -29005 # if (t->left == addr) t = t->right -29006 { -29007 50/push-eax -29008 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29009 (simple-mu-type? %eax 2) # addr => eax -29010 3d/compare-eax-with 0/imm32/false -29011 58/pop-to-eax -29012 74/jump-if-= break/disp8 -29013 $array-element-type-id:skip-addr: -29014 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -29015 } -29016 # if t == 0 abort -29017 3d/compare-eax-with 0/imm32 -29018 0f 84/jump-if-= $array-element-type-id:error2/disp32 -29019 # if t->is-atom? abort -29020 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29021 0f 85/jump-if-!= $array-element-type-id:error2/disp32 -29022 # if t->left != array abort -29023 { -29024 50/push-eax -29025 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29026 (simple-mu-type? %eax 3) # array => eax -29027 3d/compare-eax-with 0/imm32/false -29028 58/pop-to-eax -29029 $array-element-type-id:no-array: -29030 0f 84/jump-if-= $array-element-type-id:error2/disp32 -29031 } -29032 $array-element-type-id:skip-array: -29033 # t = t->right -29034 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +28943 # . +28944 (emit-save-size-to *(ebp+8) %ebx "eax") +28945 (emit-indent *(ebp+8) *Curr-block-depth) +28946 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") +28947 (emit-indent *(ebp+8) *Curr-block-depth) +28948 (write-buffered *(ebp+8) "b9/copy-to-ecx ") +28949 (write-int32-hex-buffered *(ebp+8) %ecx) +28950 (write-buffered *(ebp+8) "/imm32\n") +28951 (emit-indent *(ebp+8) *Curr-block-depth) +28952 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") +28953 { +28954 (string-equal? %edx "eax") # => eax +28955 3d/compare-eax-and 0/imm32/false +28956 75/break-if-!= break/disp8 +28957 (emit-indent *(ebp+8) *Curr-block-depth) +28958 (write-buffered *(ebp+8) "89/<- %") +28959 (write-buffered *(ebp+8) %edx) +28960 (write-buffered *(ebp+8) " 0/r32/eax\n") +28961 } +28962 # . emit register restores +28963 { +28964 (string-equal? %edx "edx") # => eax +28965 3d/compare-eax-and 0/imm32/false +28966 75/break-if-!= break/disp8 +28967 (emit-indent *(ebp+8) *Curr-block-depth) +28968 (write-buffered *(ebp+8) "5a/pop-to-edx\n") +28969 } +28970 { +28971 (string-equal? %edx "ecx") # => eax +28972 3d/compare-eax-and 0/imm32/false +28973 75/break-if-!= break/disp8 +28974 (emit-indent *(ebp+8) *Curr-block-depth) +28975 (write-buffered *(ebp+8) "59/pop-to-ecx\n") +28976 } +28977 { +28978 (string-equal? %edx "eax") # => eax +28979 3d/compare-eax-and 0/imm32/false +28980 75/break-if-!= break/disp8 +28981 (emit-indent *(ebp+8) *Curr-block-depth) +28982 (write-buffered *(ebp+8) "58/pop-to-eax\n") +28983 } +28984 $translate-mu-length-stmt:end: +28985 # . restore registers +28986 5e/pop-to-esi +28987 5b/pop-to-ebx +28988 5a/pop-to-edx +28989 59/pop-to-ecx +28990 58/pop-to-eax +28991 # . epilogue +28992 89/<- %esp 5/r32/ebp +28993 5d/pop-to-ebp +28994 c3/return +28995 +28996 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +28997 # . prologue +28998 55/push-ebp +28999 89/<- %ebp 4/r32/esp +29000 # +29001 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax +29002 (size-of-type-id-as-array-element %eax) # => eax +29003 $array-element-size:end: +29004 # . epilogue +29005 89/<- %esp 5/r32/ebp +29006 5d/pop-to-ebp +29007 c3/return +29008 +29009 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id +29010 # precondition: n is positive +29011 # . prologue +29012 55/push-ebp +29013 89/<- %ebp 4/r32/esp +29014 # +29015 8b/-> *(ebp+8) 0/r32/eax +29016 # var t/eax: (addr type-tree) +29017 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +29018 # if t == 0 abort +29019 3d/compare-eax-with 0/imm32 +29020 0f 84/jump-if-== $array-element-type-id:error0/disp32 +29021 # if t->is-atom? abort +29022 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29023 0f 85/jump-if-!= $array-element-type-id:error1/disp32 +29024 # if (t->left == addr) t = t->right +29025 { +29026 50/push-eax +29027 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29028 (simple-mu-type? %eax 2) # addr => eax +29029 3d/compare-eax-with 0/imm32/false +29030 58/pop-to-eax +29031 74/jump-if-= break/disp8 +29032 $array-element-type-id:skip-addr: +29033 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +29034 } 29035 # if t == 0 abort 29036 3d/compare-eax-with 0/imm32 29037 0f 84/jump-if-= $array-element-type-id:error2/disp32 29038 # if t->is-atom? abort 29039 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom 29040 0f 85/jump-if-!= $array-element-type-id:error2/disp32 -29041 # t = t->left -29042 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29043 # if (!t->is-atom?) t = t->left # TODO: assumes array element size can be determined from just first word of array element type -29044 # if (t->is-atom == false) t = lookup(t->left) -29045 { -29046 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29047 75/jump-if-!= break/disp8 -29048 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29049 } -29050 # return t->value -29051 8b/-> *(eax+4) 0/r32/eax # Type-tree-value -29052 $array-element-type-id:end: -29053 # . epilogue -29054 89/<- %esp 5/r32/ebp -29055 5d/pop-to-ebp -29056 c3/return -29057 -29058 $array-element-type-id:error0: -29059 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -29060 50/push-eax -29061 8b/-> *(ebp+8) 0/r32/eax -29062 (lookup *eax *(eax+4)) # Var-name Var-name => eax -29063 (write-buffered *(ebp+0xc) %eax) -29064 58/pop-to-eax -29065 (write-buffered *(ebp+0xc) "' has no type\n") -29066 (flush *(ebp+0xc)) -29067 (stop *(ebp+0x10) 1) -29068 # never gets here -29069 -29070 $array-element-type-id:error1: -29071 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -29072 50/push-eax -29073 8b/-> *(ebp+8) 0/r32/eax -29074 (lookup *eax *(eax+4)) # Var-name Var-name => eax -29075 (write-buffered *(ebp+0xc) %eax) -29076 58/pop-to-eax -29077 (write-buffered *(ebp+0xc) "' has atomic type ") -29078 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value -29079 (write-buffered *(ebp+0xc) Newline) -29080 (flush *(ebp+0xc)) -29081 (stop *(ebp+0x10) 1) -29082 # never gets here -29083 -29084 $array-element-type-id:error2: -29085 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -29086 50/push-eax -29087 8b/-> *(ebp+8) 0/r32/eax -29088 (lookup *eax *(eax+4)) # Var-name Var-name => eax -29089 (write-buffered *(ebp+0xc) %eax) -29090 58/pop-to-eax -29091 (write-buffered *(ebp+0xc) "' has non-array type\n") -29092 (flush *(ebp+0xc)) -29093 (stop *(ebp+0x10) 1) -29094 # never gets here -29095 -29096 size-of-type-id-as-array-element: # t: type-id -> result/eax: int -29097 # . prologue -29098 55/push-ebp -29099 89/<- %ebp 4/r32/esp -29100 # eax = t -29101 8b/-> *(ebp+8) 0/r32/eax -29102 # if t is 'byte', size is 1 -29103 3d/compare-eax-and 8/imm32/byte -29104 { -29105 75/jump-if-!= break/disp8 -29106 b8/copy-to-eax 1/imm32 -29107 eb/jump $size-of-type-id-as-array-element:end/disp8 -29108 } -29109 # otherwise proceed as usual -29110 (size-of-type-id %eax) # => eax -29111 $size-of-type-id-as-array-element:end: -29112 # . epilogue -29113 89/<- %esp 5/r32/ebp -29114 5d/pop-to-ebp -29115 c3/return -29116 -29117 stream-element-type-id: # type: (addr type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id -29118 # precondition: n is positive -29119 # . prologue -29120 55/push-ebp -29121 89/<- %ebp 4/r32/esp -29122 # eax = type -29123 8b/-> *(ebp+8) 0/r32/eax -29124 # if type == 0 abort -29125 3d/compare-eax-with 0/imm32 -29126 0f 84/jump-if-== $stream-element-type-id:error0/disp32 -29127 # if type->is-atom? abort -29128 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29129 0f 85/jump-if-!= $stream-element-type-id:error1/disp32 -29130 # if (type->left == addr) type = type->right -29131 { -29132 50/push-eax -29133 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29134 (simple-mu-type? %eax 2) # addr => eax -29135 3d/compare-eax-with 0/imm32/false -29136 58/pop-to-eax -29137 74/jump-if-= break/disp8 -29138 $stream-element-type-id:skip-addr: -29139 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -29140 } -29141 # if type == 0 abort -29142 3d/compare-eax-with 0/imm32 -29143 0f 84/jump-if-= $stream-element-type-id:error2/disp32 -29144 # if type->is-atom? abort -29145 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29146 0f 85/jump-if-!= $stream-element-type-id:error2/disp32 -29147 # if type->left != stream abort -29148 { -29149 50/push-eax -29150 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29151 (simple-mu-type? %eax 0xb) # stream => eax -29152 3d/compare-eax-with 0/imm32/false -29153 58/pop-to-eax -29154 $stream-element-type-id:no-stream: -29155 0f 84/jump-if-= $stream-element-type-id:error2/disp32 -29156 } -29157 $stream-element-type-id:skip-stream: -29158 # type = type->right -29159 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +29041 # if t->left != array abort +29042 { +29043 50/push-eax +29044 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29045 (simple-mu-type? %eax 3) # array => eax +29046 3d/compare-eax-with 0/imm32/false +29047 58/pop-to-eax +29048 $array-element-type-id:no-array: +29049 0f 84/jump-if-= $array-element-type-id:error2/disp32 +29050 } +29051 $array-element-type-id:skip-array: +29052 # t = t->right +29053 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +29054 # if t == 0 abort +29055 3d/compare-eax-with 0/imm32 +29056 0f 84/jump-if-= $array-element-type-id:error2/disp32 +29057 # if t->is-atom? abort +29058 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29059 0f 85/jump-if-!= $array-element-type-id:error2/disp32 +29060 # t = t->left +29061 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29062 # if (!t->is-atom?) t = t->left # TODO: assumes array element size can be determined from just first word of array element type +29063 # if (t->is-atom == false) t = lookup(t->left) +29064 { +29065 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29066 75/jump-if-!= break/disp8 +29067 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29068 } +29069 # return t->value +29070 8b/-> *(eax+4) 0/r32/eax # Type-tree-value +29071 $array-element-type-id:end: +29072 # . epilogue +29073 89/<- %esp 5/r32/ebp +29074 5d/pop-to-ebp +29075 c3/return +29076 +29077 $array-element-type-id:error0: +29078 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +29079 50/push-eax +29080 8b/-> *(ebp+8) 0/r32/eax +29081 (lookup *eax *(eax+4)) # Var-name Var-name => eax +29082 (write-buffered *(ebp+0xc) %eax) +29083 58/pop-to-eax +29084 (write-buffered *(ebp+0xc) "' has no type\n") +29085 (flush *(ebp+0xc)) +29086 (stop *(ebp+0x10) 1) +29087 # never gets here +29088 +29089 $array-element-type-id:error1: +29090 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +29091 50/push-eax +29092 8b/-> *(ebp+8) 0/r32/eax +29093 (lookup *eax *(eax+4)) # Var-name Var-name => eax +29094 (write-buffered *(ebp+0xc) %eax) +29095 58/pop-to-eax +29096 (write-buffered *(ebp+0xc) "' has atomic type ") +29097 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value +29098 (write-buffered *(ebp+0xc) Newline) +29099 (flush *(ebp+0xc)) +29100 (stop *(ebp+0x10) 1) +29101 # never gets here +29102 +29103 $array-element-type-id:error2: +29104 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +29105 50/push-eax +29106 8b/-> *(ebp+8) 0/r32/eax +29107 (lookup *eax *(eax+4)) # Var-name Var-name => eax +29108 (write-buffered *(ebp+0xc) %eax) +29109 58/pop-to-eax +29110 (write-buffered *(ebp+0xc) "' has non-array type\n") +29111 (flush *(ebp+0xc)) +29112 (stop *(ebp+0x10) 1) +29113 # never gets here +29114 +29115 size-of-type-id-as-array-element: # t: type-id -> result/eax: int +29116 # . prologue +29117 55/push-ebp +29118 89/<- %ebp 4/r32/esp +29119 # eax = t +29120 8b/-> *(ebp+8) 0/r32/eax +29121 # if t is 'byte', size is 1 +29122 3d/compare-eax-and 8/imm32/byte +29123 { +29124 75/jump-if-!= break/disp8 +29125 b8/copy-to-eax 1/imm32 +29126 eb/jump $size-of-type-id-as-array-element:end/disp8 +29127 } +29128 # otherwise proceed as usual +29129 (size-of-type-id %eax) # => eax +29130 $size-of-type-id-as-array-element:end: +29131 # . epilogue +29132 89/<- %esp 5/r32/ebp +29133 5d/pop-to-ebp +29134 c3/return +29135 +29136 stream-element-type-id: # type: (addr type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id +29137 # precondition: n is positive +29138 # . prologue +29139 55/push-ebp +29140 89/<- %ebp 4/r32/esp +29141 # eax = type +29142 8b/-> *(ebp+8) 0/r32/eax +29143 # if type == 0 abort +29144 3d/compare-eax-with 0/imm32 +29145 0f 84/jump-if-== $stream-element-type-id:error0/disp32 +29146 # if type->is-atom? abort +29147 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29148 0f 85/jump-if-!= $stream-element-type-id:error1/disp32 +29149 # if (type->left == addr) type = type->right +29150 { +29151 50/push-eax +29152 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29153 (simple-mu-type? %eax 2) # addr => eax +29154 3d/compare-eax-with 0/imm32/false +29155 58/pop-to-eax +29156 74/jump-if-= break/disp8 +29157 $stream-element-type-id:skip-addr: +29158 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +29159 } 29160 # if type == 0 abort 29161 3d/compare-eax-with 0/imm32 29162 0f 84/jump-if-= $stream-element-type-id:error2/disp32 29163 # if type->is-atom? abort 29164 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom 29165 0f 85/jump-if-!= $stream-element-type-id:error2/disp32 -29166 # t = type->left -29167 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29168 # if (!type->is-atom?) type = type->left # TODO: assumes stream element size can be determined from just first word of stream element type -29169 { -29170 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29171 75/jump-if-!= break/disp8 -29172 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29173 } -29174 # return type->value -29175 8b/-> *(eax+4) 0/r32/eax # Type-tree-value -29176 $stream-element-type-id:end: -29177 # . epilogue -29178 89/<- %esp 5/r32/ebp -29179 5d/pop-to-ebp -29180 c3/return -29181 -29182 $stream-element-type-id:error0: -29183 (write-buffered *(ebp+0xc) "stream-element-type-id: var '") -29184 50/push-eax -29185 8b/-> *(ebp+8) 0/r32/eax -29186 (lookup *eax *(eax+4)) # Var-name Var-name => eax -29187 (write-buffered *(ebp+0xc) %eax) -29188 58/pop-to-eax -29189 (write-buffered *(ebp+0xc) "' has no type\n") -29190 (flush *(ebp+0xc)) -29191 (stop *(ebp+0x10) 1) -29192 # never gets here -29193 -29194 $stream-element-type-id:error1: -29195 (write-buffered *(ebp+0xc) "stream-element-type-id: var '") -29196 50/push-eax -29197 8b/-> *(ebp+8) 0/r32/eax -29198 (lookup *eax *(eax+4)) # Var-name Var-name => eax -29199 (write-buffered *(ebp+0xc) %eax) -29200 58/pop-to-eax -29201 (write-buffered *(ebp+0xc) "' has atomic type ") -29202 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value -29203 (write-buffered *(ebp+0xc) Newline) -29204 (flush *(ebp+0xc)) -29205 (stop *(ebp+0x10) 1) -29206 # never gets here -29207 -29208 $stream-element-type-id:error2: -29209 (write-buffered *(ebp+0xc) "stream-element-type-id: var '") -29210 50/push-eax -29211 8b/-> *(ebp+8) 0/r32/eax -29212 (lookup *eax *(eax+4)) # Var-name Var-name => eax -29213 (write-buffered *(ebp+0xc) %eax) -29214 58/pop-to-eax -29215 (write-buffered *(ebp+0xc) "' has non-stream type\n") -29216 (flush *(ebp+0xc)) -29217 (stop *(ebp+0x10) 1) -29218 # never gets here -29219 -29220 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) -29221 # . prologue -29222 55/push-ebp -29223 89/<- %ebp 4/r32/esp -29224 # . save registers -29225 50/push-eax -29226 53/push-ebx -29227 # ebx = base -29228 8b/-> *(ebp+0xc) 3/r32/ebx -29229 (emit-indent *(ebp+8) *Curr-block-depth) -29230 (write-buffered *(ebp+8) "8b/-> *") -29231 # if base is an (addr array ...) in a register -29232 { -29233 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register -29234 74/jump-if-= break/disp8 -29235 $emit-save-size-to:emit-base-from-register: -29236 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -29237 (write-buffered *(ebp+8) %eax) -29238 eb/jump $emit-save-size-to:emit-output/disp8 -29239 } -29240 # otherwise if base is an (array ...) on the stack -29241 { -29242 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset -29243 74/jump-if-= break/disp8 -29244 $emit-save-size-to:emit-base-from-stack: -29245 (write-buffered *(ebp+8) "(ebp+") -29246 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset -29247 (write-buffered *(ebp+8) ")") -29248 } -29249 $emit-save-size-to:emit-output: -29250 (write-buffered *(ebp+8) " ") -29251 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax -29252 (write-int32-hex-buffered *(ebp+8) *eax) -29253 (write-buffered *(ebp+8) "/r32\n") -29254 $emit-save-size-to:end: -29255 # . restore registers -29256 5b/pop-to-ebx -29257 58/pop-to-eax -29258 # . epilogue -29259 89/<- %esp 5/r32/ebp -29260 5d/pop-to-ebp -29261 c3/return -29262 -29263 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int -29264 # . prologue -29265 55/push-ebp -29266 89/<- %ebp 4/r32/esp -29267 # . save registers -29268 50/push-eax -29269 # -29270 (emit-indent *(ebp+8) *Curr-block-depth) -29271 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") -29272 (write-buffered *(ebp+8) *(ebp+0xc)) -29273 (write-buffered *(ebp+8) Space) -29274 (num-shift-rights *(ebp+0x10)) # => eax -29275 (write-int32-hex-buffered *(ebp+8) %eax) -29276 (write-buffered *(ebp+8) "/imm8\n") -29277 $emit-divide-by-shift-right:end: -29278 # . restore registers -29279 58/pop-to-eax -29280 # . epilogue -29281 89/<- %esp 5/r32/ebp -29282 5d/pop-to-ebp -29283 c3/return -29284 -29285 translate-mu-copy-byte-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -29286 # . prologue -29287 55/push-ebp -29288 89/<- %ebp 4/r32/esp -29289 # . save registers -29290 50/push-eax -29291 56/push-esi -29292 # esi = stmt -29293 8b/-> *(ebp+0xc) 6/r32/esi -29294 # -29295 (emit-indent *(ebp+8) *Curr-block-depth) -29296 (write-buffered *(ebp+8) "8a/byte->") -29297 # emit stmt->inouts[0] -29298 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29299 (emit-subx-var-as-rm32 *(ebp+8) %eax) -29300 # emit /r32 for stmt->outputs[0]->register -29301 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -29302 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29303 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -29304 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) -29305 (write-buffered *(ebp+8) Space) -29306 (write-int32-hex-buffered *(ebp+8) *eax) -29307 (write-buffered *(ebp+8) "/r32\n") -29308 # clear rest of register -29309 (emit-indent *(ebp+8) *Curr-block-depth) -29310 (write-buffered *(ebp+8) "81 4/subop/and %") -29311 8b/-> *(ebp+0xc) 0/r32/eax -29312 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -29313 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29314 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -29315 (write-buffered *(ebp+8) %eax) -29316 (write-buffered *(ebp+8) " 0xff/imm32\n") -29317 $translate-mu-copy-byte-stmt:end: -29318 # . restore registers -29319 5e/pop-to-esi -29320 58/pop-to-eax -29321 # . epilogue -29322 89/<- %esp 5/r32/ebp -29323 5d/pop-to-ebp -29324 c3/return -29325 -29326 # a little different from other translate- functions; notice the extra 'fn' argument -29327 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -29328 # . prologue -29329 55/push-ebp -29330 89/<- %ebp 4/r32/esp -29331 # . save registers -29332 53/push-ebx -29333 # ebx = stmt -29334 8b/-> *(ebp+0xc) 3/r32/ebx -29335 # var base/ebx: (addr var) = stmt->inouts[0] -29336 (lookup *(ebx+0xc) *(ebx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29337 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29338 89/<- %ebx 0/r32/eax -29339 # emit bounds-check -29340 (emit-mu-index-bounds-check *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) -29341 # if (var->register) do one thing -29342 { -29343 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -29344 74/jump-if-= break/disp8 -29345 # TODO: ensure there's no dereference -29346 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -29347 eb/jump $translate-mu-index-stmt:end/disp8 -29348 } -29349 # if (var->offset) do a different thing -29350 { -29351 81 7/subop/compare *(ebx+0x14) 0/imm32 # Var-offset -29352 74/jump-if-= break/disp8 -29353 # TODO: ensure there's no dereference -29354 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -29355 eb/jump $translate-mu-index-stmt:end/disp8 -29356 } -29357 $translate-mu-index-stmt:end: -29358 # . restore registers -29359 5b/pop-to-ebx -29360 # . epilogue -29361 89/<- %esp 5/r32/ebp -29362 5d/pop-to-ebp -29363 c3/return -29364 -29365 $translate-mu-index-stmt:error1: -29366 (write-buffered *(ebp+0x14) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") -29367 (flush *(ebp+0x14)) -29368 (stop *(ebp+0x18) 1) -29369 # never gets here -29370 -29371 $translate-mu-index-stmt:error2: -29372 (write-buffered *(ebp+0x14) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") -29373 (flush *(ebp+0x14)) -29374 (stop *(ebp+0x18) 1) -29375 # never gets here -29376 -29377 emit-mu-index-bounds-check: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -29378 # . prologue -29379 55/push-ebp -29380 89/<- %ebp 4/r32/esp -29381 # . save registers -29382 50/push-eax -29383 51/push-ecx -29384 52/push-edx -29385 53/push-ebx -29386 # ecx = stmt -29387 8b/-> *(ebp+0xc) 1/r32/ecx -29388 # -29389 (emit-indent *(ebp+8) *Curr-block-depth) -29390 (write-buffered *(ebp+8) "(__check-mu-array-bounds ") -29391 $emit-mu-index-bounds-check:compute-base: -29392 # var base/ebx: (addr var) = inouts[0] -29393 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29394 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29395 89/<- %ebx 0/r32/eax -29396 $emit-mu-index-bounds-check:emit-index: -29397 # var index/edx: (addr var) = inouts[1] -29398 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29399 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -29400 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29401 89/<- %edx 0/r32/eax -29402 # if index->register, print its code -29403 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -29404 { -29405 0f 84/jump-if-= break/disp32 -29406 $emit-mu-index-bounds-check:emit-register-index: -29407 (write-buffered *(ebp+8) "%") -29408 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -29409 (write-buffered *(ebp+8) %eax) -29410 eb/jump $emit-mu-index-bounds-check:index-done/disp8 -29411 } -29412 # otherwise if index is a literal, print it -29413 $emit-mu-index-bounds-check:emit-literal-index: -29414 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29415 (simple-mu-type? %eax 0) # => eax -29416 3d/compare-eax-and 0/imm32/false -29417 { -29418 0f 84/jump-if-= break/disp32 -29419 (lookup *edx *(edx+4)) # Var-name Var-name => eax -29420 (write-buffered *(ebp+8) %eax) -29421 } -29422 $emit-mu-index-bounds-check:index-done: -29423 (write-buffered *(ebp+8) " ") -29424 $emit-mu-index-bounds-check:emit-element-size: -29425 # if index is a literal or int, print size of array element -29426 { -29427 { -29428 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29429 (simple-mu-type? %eax 0) # literal => eax -29430 3d/compare-eax-and 0/imm32/false -29431 75/jump-if-!= break/disp8 -29432 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29433 (simple-mu-type? %eax 1) # int => eax -29434 3d/compare-eax-and 0/imm32/false -29435 75/jump-if-!= break/disp8 -29436 eb/jump $emit-mu-index-bounds-check:emit-element-size-offset/disp8 -29437 } -29438 $emit-mu-index-bounds-check:emit-int-register-index: -29439 (array-element-size %ebx *(ebp+0x14) *(ebp+0x18)) # => eax -29440 (write-int32-hex-buffered *(ebp+8) %eax) -29441 e9/jump $emit-mu-index-bounds-check:emit-base/disp32 -29442 } -29443 $emit-mu-index-bounds-check:emit-element-size-offset: -29444 # if index has type (offset ...), print "1" -29445 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29446 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29447 { -29448 75/jump-if-!= break/disp8 -29449 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29450 (simple-mu-type? %eax 7) # => eax -29451 3d/compare-eax-and 0/imm32/false -29452 { -29453 0f 84/jump-if-= break/disp32 -29454 $emit-mu-index-bounds-check:emit-offset-register-index: -29455 (write-buffered *(ebp+8) "1") +29166 # if type->left != stream abort +29167 { +29168 50/push-eax +29169 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29170 (simple-mu-type? %eax 0xb) # stream => eax +29171 3d/compare-eax-with 0/imm32/false +29172 58/pop-to-eax +29173 $stream-element-type-id:no-stream: +29174 0f 84/jump-if-= $stream-element-type-id:error2/disp32 +29175 } +29176 $stream-element-type-id:skip-stream: +29177 # type = type->right +29178 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +29179 # if type == 0 abort +29180 3d/compare-eax-with 0/imm32 +29181 0f 84/jump-if-= $stream-element-type-id:error2/disp32 +29182 # if type->is-atom? abort +29183 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29184 0f 85/jump-if-!= $stream-element-type-id:error2/disp32 +29185 # t = type->left +29186 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29187 # if (!type->is-atom?) type = type->left # TODO: assumes stream element size can be determined from just first word of stream element type +29188 { +29189 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29190 75/jump-if-!= break/disp8 +29191 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29192 } +29193 # return type->value +29194 8b/-> *(eax+4) 0/r32/eax # Type-tree-value +29195 $stream-element-type-id:end: +29196 # . epilogue +29197 89/<- %esp 5/r32/ebp +29198 5d/pop-to-ebp +29199 c3/return +29200 +29201 $stream-element-type-id:error0: +29202 (write-buffered *(ebp+0xc) "stream-element-type-id: var '") +29203 50/push-eax +29204 8b/-> *(ebp+8) 0/r32/eax +29205 (lookup *eax *(eax+4)) # Var-name Var-name => eax +29206 (write-buffered *(ebp+0xc) %eax) +29207 58/pop-to-eax +29208 (write-buffered *(ebp+0xc) "' has no type\n") +29209 (flush *(ebp+0xc)) +29210 (stop *(ebp+0x10) 1) +29211 # never gets here +29212 +29213 $stream-element-type-id:error1: +29214 (write-buffered *(ebp+0xc) "stream-element-type-id: var '") +29215 50/push-eax +29216 8b/-> *(ebp+8) 0/r32/eax +29217 (lookup *eax *(eax+4)) # Var-name Var-name => eax +29218 (write-buffered *(ebp+0xc) %eax) +29219 58/pop-to-eax +29220 (write-buffered *(ebp+0xc) "' has atomic type ") +29221 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value +29222 (write-buffered *(ebp+0xc) Newline) +29223 (flush *(ebp+0xc)) +29224 (stop *(ebp+0x10) 1) +29225 # never gets here +29226 +29227 $stream-element-type-id:error2: +29228 (write-buffered *(ebp+0xc) "stream-element-type-id: var '") +29229 50/push-eax +29230 8b/-> *(ebp+8) 0/r32/eax +29231 (lookup *eax *(eax+4)) # Var-name Var-name => eax +29232 (write-buffered *(ebp+0xc) %eax) +29233 58/pop-to-eax +29234 (write-buffered *(ebp+0xc) "' has non-stream type\n") +29235 (flush *(ebp+0xc)) +29236 (stop *(ebp+0x10) 1) +29237 # never gets here +29238 +29239 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) +29240 # . prologue +29241 55/push-ebp +29242 89/<- %ebp 4/r32/esp +29243 # . save registers +29244 50/push-eax +29245 53/push-ebx +29246 # ebx = base +29247 8b/-> *(ebp+0xc) 3/r32/ebx +29248 (emit-indent *(ebp+8) *Curr-block-depth) +29249 (write-buffered *(ebp+8) "8b/-> *") +29250 # if base is an (addr array ...) in a register +29251 { +29252 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register +29253 74/jump-if-= break/disp8 +29254 $emit-save-size-to:emit-base-from-register: +29255 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +29256 (write-buffered *(ebp+8) %eax) +29257 eb/jump $emit-save-size-to:emit-output/disp8 +29258 } +29259 # otherwise if base is an (array ...) on the stack +29260 { +29261 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset +29262 74/jump-if-= break/disp8 +29263 $emit-save-size-to:emit-base-from-stack: +29264 (write-buffered *(ebp+8) "(ebp+") +29265 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset +29266 (write-buffered *(ebp+8) ")") +29267 } +29268 $emit-save-size-to:emit-output: +29269 (write-buffered *(ebp+8) " ") +29270 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax +29271 (write-int32-hex-buffered *(ebp+8) *eax) +29272 (write-buffered *(ebp+8) "/r32\n") +29273 $emit-save-size-to:end: +29274 # . restore registers +29275 5b/pop-to-ebx +29276 58/pop-to-eax +29277 # . epilogue +29278 89/<- %esp 5/r32/ebp +29279 5d/pop-to-ebp +29280 c3/return +29281 +29282 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int +29283 # . prologue +29284 55/push-ebp +29285 89/<- %ebp 4/r32/esp +29286 # . save registers +29287 50/push-eax +29288 # +29289 (emit-indent *(ebp+8) *Curr-block-depth) +29290 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") +29291 (write-buffered *(ebp+8) *(ebp+0xc)) +29292 (write-buffered *(ebp+8) Space) +29293 (num-shift-rights *(ebp+0x10)) # => eax +29294 (write-int32-hex-buffered *(ebp+8) %eax) +29295 (write-buffered *(ebp+8) "/imm8\n") +29296 $emit-divide-by-shift-right:end: +29297 # . restore registers +29298 58/pop-to-eax +29299 # . epilogue +29300 89/<- %esp 5/r32/ebp +29301 5d/pop-to-ebp +29302 c3/return +29303 +29304 translate-mu-copy-byte-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +29305 # . prologue +29306 55/push-ebp +29307 89/<- %ebp 4/r32/esp +29308 # . save registers +29309 50/push-eax +29310 56/push-esi +29311 # esi = stmt +29312 8b/-> *(ebp+0xc) 6/r32/esi +29313 # +29314 (emit-indent *(ebp+8) *Curr-block-depth) +29315 (write-buffered *(ebp+8) "8a/byte->") +29316 # emit stmt->inouts[0] +29317 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29318 (emit-subx-var-as-rm32 *(ebp+8) %eax) +29319 # emit /r32 for stmt->outputs[0]->register +29320 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +29321 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29322 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +29323 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) +29324 (write-buffered *(ebp+8) Space) +29325 (write-int32-hex-buffered *(ebp+8) *eax) +29326 (write-buffered *(ebp+8) "/r32\n") +29327 # clear rest of register +29328 (emit-indent *(ebp+8) *Curr-block-depth) +29329 (write-buffered *(ebp+8) "81 4/subop/and %") +29330 8b/-> *(ebp+0xc) 0/r32/eax +29331 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +29332 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29333 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +29334 (write-buffered *(ebp+8) %eax) +29335 (write-buffered *(ebp+8) " 0xff/imm32\n") +29336 $translate-mu-copy-byte-stmt:end: +29337 # . restore registers +29338 5e/pop-to-esi +29339 58/pop-to-eax +29340 # . epilogue +29341 89/<- %esp 5/r32/ebp +29342 5d/pop-to-ebp +29343 c3/return +29344 +29345 # a little different from other translate- functions; notice the extra 'fn' argument +29346 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +29347 # . prologue +29348 55/push-ebp +29349 89/<- %ebp 4/r32/esp +29350 # . save registers +29351 53/push-ebx +29352 # ebx = stmt +29353 8b/-> *(ebp+0xc) 3/r32/ebx +29354 # var base/ebx: (addr var) = stmt->inouts[0] +29355 (lookup *(ebx+0xc) *(ebx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29356 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29357 89/<- %ebx 0/r32/eax +29358 # emit bounds-check +29359 (emit-mu-index-bounds-check *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) +29360 # if (var->register) do one thing +29361 { +29362 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +29363 74/jump-if-= break/disp8 +29364 # TODO: ensure there's no dereference +29365 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +29366 eb/jump $translate-mu-index-stmt:end/disp8 +29367 } +29368 # if (var->offset) do a different thing +29369 { +29370 81 7/subop/compare *(ebx+0x14) 0/imm32 # Var-offset +29371 74/jump-if-= break/disp8 +29372 # TODO: ensure there's no dereference +29373 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +29374 eb/jump $translate-mu-index-stmt:end/disp8 +29375 } +29376 $translate-mu-index-stmt:end: +29377 # . restore registers +29378 5b/pop-to-ebx +29379 # . epilogue +29380 89/<- %esp 5/r32/ebp +29381 5d/pop-to-ebp +29382 c3/return +29383 +29384 $translate-mu-index-stmt:error1: +29385 (write-buffered *(ebp+0x14) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") +29386 (flush *(ebp+0x14)) +29387 (stop *(ebp+0x18) 1) +29388 # never gets here +29389 +29390 $translate-mu-index-stmt:error2: +29391 (write-buffered *(ebp+0x14) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") +29392 (flush *(ebp+0x14)) +29393 (stop *(ebp+0x18) 1) +29394 # never gets here +29395 +29396 emit-mu-index-bounds-check: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +29397 # . prologue +29398 55/push-ebp +29399 89/<- %ebp 4/r32/esp +29400 # . save registers +29401 50/push-eax +29402 51/push-ecx +29403 52/push-edx +29404 53/push-ebx +29405 # ecx = stmt +29406 8b/-> *(ebp+0xc) 1/r32/ecx +29407 # +29408 (emit-indent *(ebp+8) *Curr-block-depth) +29409 (write-buffered *(ebp+8) "(__check-mu-array-bounds ") +29410 $emit-mu-index-bounds-check:compute-base: +29411 # var base/ebx: (addr var) = inouts[0] +29412 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29413 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29414 89/<- %ebx 0/r32/eax +29415 $emit-mu-index-bounds-check:emit-index: +29416 # var index/edx: (addr var) = inouts[1] +29417 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29418 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +29419 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29420 89/<- %edx 0/r32/eax +29421 # if index->register, print its code +29422 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +29423 { +29424 0f 84/jump-if-= break/disp32 +29425 $emit-mu-index-bounds-check:emit-register-index: +29426 (write-buffered *(ebp+8) "%") +29427 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +29428 (write-buffered *(ebp+8) %eax) +29429 eb/jump $emit-mu-index-bounds-check:index-done/disp8 +29430 } +29431 # otherwise if index is a literal, print it +29432 $emit-mu-index-bounds-check:emit-literal-index: +29433 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29434 (simple-mu-type? %eax 0) # => eax +29435 3d/compare-eax-and 0/imm32/false +29436 { +29437 0f 84/jump-if-= break/disp32 +29438 (lookup *edx *(edx+4)) # Var-name Var-name => eax +29439 (write-buffered *(ebp+8) %eax) +29440 } +29441 $emit-mu-index-bounds-check:index-done: +29442 (write-buffered *(ebp+8) " ") +29443 $emit-mu-index-bounds-check:emit-element-size: +29444 # if index is a literal or int, print size of array element +29445 { +29446 { +29447 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29448 (simple-mu-type? %eax 0) # literal => eax +29449 3d/compare-eax-and 0/imm32/false +29450 75/jump-if-!= break/disp8 +29451 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29452 (simple-mu-type? %eax 1) # int => eax +29453 3d/compare-eax-and 0/imm32/false +29454 75/jump-if-!= break/disp8 +29455 eb/jump $emit-mu-index-bounds-check:emit-element-size-offset/disp8 29456 } -29457 } -29458 $emit-mu-index-bounds-check:emit-base: -29459 # if base is in a register, print " *" base->register -29460 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -29461 { -29462 74/jump-if-= break/disp8 -29463 (write-buffered *(ebp+8) " *") -29464 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -29465 (write-buffered *(ebp+8) %eax) -29466 e9/jump $emit-mu-index-bounds-check:emit-function-name/disp32 -29467 } -29468 # otherwise print " *(ebp+" base->offset ")" -29469 (write-buffered *(ebp+8) " *(ebp+") -29470 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset -29471 (write-buffered *(ebp+8) ")") -29472 $emit-mu-index-bounds-check:emit-function-name: -29473 # " \"" function-name "\"" -29474 (write-buffered *(ebp+8) " \"") -29475 8b/-> *(ebp+0x10) 1/r32/ecx -29476 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -29477 (write-buffered *(ebp+8) %eax) -29478 (write-buffered *(ebp+8) "\"") -29479 $emit-mu-index-bounds-check:emit-array-name: -29480 # " \"" base->name "\"" -29481 (write-buffered *(ebp+8) " \"") -29482 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -29483 (write-buffered *(ebp+8) %eax) -29484 (write-buffered *(ebp+8) "\")\n") -29485 $emit-mu-index-bounds-check:end: -29486 # . restore registers -29487 5b/pop-to-ebx -29488 5a/pop-to-edx -29489 59/pop-to-ecx -29490 58/pop-to-eax -29491 # . epilogue -29492 89/<- %esp 5/r32/ebp -29493 5d/pop-to-ebp -29494 c3/return -29495 -29496 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -29497 # . prologue -29498 55/push-ebp -29499 89/<- %ebp 4/r32/esp -29500 # . save registers -29501 50/push-eax -29502 51/push-ecx -29503 52/push-edx -29504 53/push-ebx -29505 # ecx = stmt -29506 8b/-> *(ebp+0xc) 1/r32/ecx -29507 # var base/ebx: (addr var) = inouts[0] -29508 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29509 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29510 89/<- %ebx 0/r32/eax -29511 # emit null check -29512 (emit-indent *(ebp+8) *Curr-block-depth) -29513 (write-buffered *(ebp+8) "81 7/subop/compare %") -29514 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -29515 (write-buffered *(ebp+8) %eax) -29516 (write-buffered *(ebp+8) " 0/imm32\n") -29517 (emit-indent *(ebp+8) *Curr-block-depth) -29518 (write-buffered *(ebp+8) "0f 84/jump-if-= __mu-abort-null-index-base-address/disp32\n") -29519 # -29520 (emit-indent *(ebp+8) *Curr-block-depth) -29521 (write-buffered *(ebp+8) "8d/copy-address *(") -29522 # TODO: ensure inouts[0] is in a register and not dereferenced -29523 $translate-mu-index-stmt-with-array-in-register:emit-base: -29524 # print base->register " + " -29525 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -29526 (write-buffered *(ebp+8) %eax) -29527 (write-buffered *(ebp+8) " + ") -29528 # var index/edx: (addr var) = inouts[1] -29529 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29530 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -29531 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29532 89/<- %edx 0/r32/eax -29533 # if index->register -29534 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -29535 { -29536 0f 84/jump-if-= break/disp32 -29537 $translate-mu-index-stmt-with-array-in-register:emit-register-index: -29538 # if index is an int -29539 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29540 (simple-mu-type? %eax 1) # int => eax -29541 3d/compare-eax-and 0/imm32/false -29542 { -29543 0f 84/jump-if-= break/disp32 -29544 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: -29545 # print index->register "<<" log2(array-element-size(base)) " + 4) " -29546 # . index->register "<<" -29547 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -29548 (write-buffered *(ebp+8) %eax) -29549 (write-buffered *(ebp+8) "<<") -29550 # . log2(array-element-size(base->type)) -29551 # we know size is a power of 2 -29552 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -29553 (num-shift-rights %eax) # => eax -29554 (write-int32-hex-buffered *(ebp+8) %eax) -29555 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 -29556 } -29557 # if index->type is any other atom, abort +29457 $emit-mu-index-bounds-check:emit-int-register-index: +29458 (array-element-size %ebx *(ebp+0x14) *(ebp+0x18)) # => eax +29459 (write-int32-hex-buffered *(ebp+8) %eax) +29460 e9/jump $emit-mu-index-bounds-check:emit-base/disp32 +29461 } +29462 $emit-mu-index-bounds-check:emit-element-size-offset: +29463 # if index has type (offset ...), print "1" +29464 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29465 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29466 { +29467 75/jump-if-!= break/disp8 +29468 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29469 (simple-mu-type? %eax 7) # => eax +29470 3d/compare-eax-and 0/imm32/false +29471 { +29472 0f 84/jump-if-= break/disp32 +29473 $emit-mu-index-bounds-check:emit-offset-register-index: +29474 (write-buffered *(ebp+8) "1") +29475 } +29476 } +29477 $emit-mu-index-bounds-check:emit-base: +29478 # if base is in a register, print " *" base->register +29479 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +29480 { +29481 74/jump-if-= break/disp8 +29482 (write-buffered *(ebp+8) " *") +29483 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +29484 (write-buffered *(ebp+8) %eax) +29485 e9/jump $emit-mu-index-bounds-check:emit-function-name/disp32 +29486 } +29487 # otherwise print " *(ebp+" base->offset ")" +29488 (write-buffered *(ebp+8) " *(ebp+") +29489 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset +29490 (write-buffered *(ebp+8) ")") +29491 $emit-mu-index-bounds-check:emit-function-name: +29492 # " \"" function-name "\"" +29493 (write-buffered *(ebp+8) " \"") +29494 8b/-> *(ebp+0x10) 1/r32/ecx +29495 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +29496 (write-buffered *(ebp+8) %eax) +29497 (write-buffered *(ebp+8) "\"") +29498 $emit-mu-index-bounds-check:emit-array-name: +29499 # " \"" base->name "\"" +29500 (write-buffered *(ebp+8) " \"") +29501 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +29502 (write-buffered *(ebp+8) %eax) +29503 (write-buffered *(ebp+8) "\")\n") +29504 $emit-mu-index-bounds-check:end: +29505 # . restore registers +29506 5b/pop-to-ebx +29507 5a/pop-to-edx +29508 59/pop-to-ecx +29509 58/pop-to-eax +29510 # . epilogue +29511 89/<- %esp 5/r32/ebp +29512 5d/pop-to-ebp +29513 c3/return +29514 +29515 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +29516 # . prologue +29517 55/push-ebp +29518 89/<- %ebp 4/r32/esp +29519 # . save registers +29520 50/push-eax +29521 51/push-ecx +29522 52/push-edx +29523 53/push-ebx +29524 # ecx = stmt +29525 8b/-> *(ebp+0xc) 1/r32/ecx +29526 # var base/ebx: (addr var) = inouts[0] +29527 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29528 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29529 89/<- %ebx 0/r32/eax +29530 # emit null check +29531 (emit-indent *(ebp+8) *Curr-block-depth) +29532 (write-buffered *(ebp+8) "81 7/subop/compare %") +29533 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +29534 (write-buffered *(ebp+8) %eax) +29535 (write-buffered *(ebp+8) " 0/imm32\n") +29536 (emit-indent *(ebp+8) *Curr-block-depth) +29537 (write-buffered *(ebp+8) "0f 84/jump-if-= __mu-abort-null-index-base-address/disp32\n") +29538 # +29539 (emit-indent *(ebp+8) *Curr-block-depth) +29540 (write-buffered *(ebp+8) "8d/copy-address *(") +29541 # TODO: ensure inouts[0] is in a register and not dereferenced +29542 $translate-mu-index-stmt-with-array-in-register:emit-base: +29543 # print base->register " + " +29544 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +29545 (write-buffered *(ebp+8) %eax) +29546 (write-buffered *(ebp+8) " + ") +29547 # var index/edx: (addr var) = inouts[1] +29548 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29549 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +29550 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29551 89/<- %edx 0/r32/eax +29552 # if index->register +29553 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +29554 { +29555 0f 84/jump-if-= break/disp32 +29556 $translate-mu-index-stmt-with-array-in-register:emit-register-index: +29557 # if index is an int 29558 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29559 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29560 0f 85/jump-if-!= $translate-mu-index-stmt:error2/disp32 -29561 # if index has type (offset ...) -29562 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29563 (simple-mu-type? %eax 7) # => eax -29564 3d/compare-eax-and 0/imm32/false -29565 { -29566 0f 84/jump-if-= break/disp32 -29567 # print index->register -29568 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: -29569 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -29570 (write-buffered *(ebp+8) %eax) -29571 } -29572 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: -29573 (write-buffered *(ebp+8) " + 4) ") -29574 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 -29575 } -29576 # otherwise if index is a literal -29577 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29578 (simple-mu-type? %eax 0) # => eax -29579 3d/compare-eax-and 0/imm32/false -29580 { -29581 0f 84/jump-if-= break/disp32 -29582 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: -29583 # var index-value/edx: int = parse-hex-int(index->name) -29584 (lookup *edx *(edx+4)) # Var-name Var-name => eax -29585 (parse-hex-int %eax) # => eax -29586 89/<- %edx 0/r32/eax -29587 # offset = idx-value * array-element-size(base->type) -29588 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -29589 f7 4/subop/multiply-into-edx-eax %edx # clobbers edx -29590 # offset += 4 for array size -29591 05/add-to-eax 4/imm32 -29592 # TODO: check edx for overflow -29593 # print offset -29594 (write-int32-hex-buffered *(ebp+8) %eax) -29595 (write-buffered *(ebp+8) ") ") -29596 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 -29597 } -29598 # otherwise abort -29599 e9/jump $translate-mu-index-stmt:error1/disp32 -29600 $translate-mu-index-stmt-with-array-in-register:emit-output: -29601 # outputs[0] "/r32" -29602 8b/-> *(ebp+0xc) 1/r32/ecx -29603 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -29604 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29605 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -29606 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -29607 (write-int32-hex-buffered *(ebp+8) *eax) -29608 (write-buffered *(ebp+8) "/r32\n") -29609 $translate-mu-index-stmt-with-array-in-register:end: -29610 # . restore registers -29611 5b/pop-to-ebx -29612 5a/pop-to-edx -29613 59/pop-to-ecx -29614 58/pop-to-eax -29615 # . epilogue -29616 89/<- %esp 5/r32/ebp -29617 5d/pop-to-ebp -29618 c3/return -29619 -29620 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -29621 # . prologue -29622 55/push-ebp -29623 89/<- %ebp 4/r32/esp -29624 # . save registers -29625 50/push-eax -29626 51/push-ecx -29627 52/push-edx -29628 53/push-ebx -29629 # -29630 (emit-indent *(ebp+8) *Curr-block-depth) -29631 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") -29632 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) -29633 8b/-> *(ebp+0xc) 0/r32/eax -29634 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29635 89/<- %edx 0/r32/eax -29636 # var base/ecx: (addr var) = lookup(curr->value) -29637 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29638 89/<- %ecx 0/r32/eax -29639 # var curr2/eax: (addr stmt-var) = lookup(curr->next) -29640 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax -29641 # var index/edx: (handle var) = curr2->value -29642 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29643 89/<- %edx 0/r32/eax -29644 # if index->register -29645 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -29646 { -29647 0f 84/jump-if-= break/disp32 -29648 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: -29649 # if index is an int -29650 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29651 (simple-mu-type? %eax 1) # int => eax -29652 3d/compare-eax-and 0/imm32/false -29653 { -29654 0f 84/jump-if-= break/disp32 -29655 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: -29656 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4 -29657 # . inouts[1]->register "<<" -29658 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -29659 (write-buffered *(ebp+8) %eax) -29660 (write-buffered *(ebp+8) "<<") -29661 # . log2(array-element-size(base)) -29662 # TODO: ensure size is a power of 2 -29663 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -29664 (num-shift-rights %eax) # => eax -29665 (write-int32-hex-buffered *(ebp+8) %eax) -29666 # -29667 (write-buffered *(ebp+8) " + ") -29668 # -29669 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset -29670 05/add-to-eax 4/imm32 # for array length -29671 (write-int32-hex-buffered *(ebp+8) %eax) -29672 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 -29673 } -29674 # if index->type is any other atom, abort -29675 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29676 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -29677 0f 85/jump-if-!= $translate-mu-index-stmt:error2/disp32 -29678 # if index has type (offset ...) -29679 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29680 (simple-mu-type? %eax 7) # => eax -29681 3d/compare-eax-and 0/imm32/false -29682 { -29683 0f 84/jump-if-= break/disp32 -29684 # print index->register -29685 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: -29686 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -29687 (write-buffered *(ebp+8) %eax) -29688 } -29689 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: -29690 (write-buffered *(ebp+8) ") ") -29691 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 -29692 } -29693 # otherwise if index is a literal -29694 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -29695 (simple-mu-type? %eax 0) # => eax -29696 3d/compare-eax-and 0/imm32/false -29697 { -29698 0f 84/jump-if-= break/disp32 -29699 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: -29700 # var idx-value/edx: int = parse-hex-int(index->name) -29701 (lookup *edx *(edx+4)) # Var-name Var-name => eax -29702 (parse-hex-int %eax) # Var-name => eax -29703 89/<- %edx 0/r32/eax -29704 # offset = idx-value * array-element-size(base) -29705 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -29706 f7 4/subop/multiply-into-edx-eax %edx # clobbers edx -29707 # offset += base->offset -29708 03/add *(ecx+0x14) 0/r32/eax # Var-offset -29709 # offset += 4 for array size -29710 05/add-to-eax 4/imm32 -29711 # TODO: check edx for overflow -29712 # print offset -29713 (write-int32-hex-buffered *(ebp+8) %eax) -29714 (write-buffered *(ebp+8) ") ") -29715 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 -29716 } -29717 # otherwise abort -29718 e9/jump $translate-mu-index-stmt:error1/disp32 -29719 $translate-mu-index-stmt-with-array-on-stack:emit-output: -29720 # outputs[0] "/r32" -29721 8b/-> *(ebp+0xc) 0/r32/eax -29722 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax -29723 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29724 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -29725 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -29726 (write-int32-hex-buffered *(ebp+8) *eax) -29727 (write-buffered *(ebp+8) "/r32\n") -29728 $translate-mu-index-stmt-with-array-on-stack:end: -29729 # . restore registers -29730 5b/pop-to-ebx -29731 5a/pop-to-edx -29732 59/pop-to-ecx -29733 58/pop-to-eax -29734 # . epilogue -29735 89/<- %esp 5/r32/ebp -29736 5d/pop-to-ebp -29737 c3/return -29738 -29739 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -29740 # . prologue -29741 55/push-ebp -29742 89/<- %ebp 4/r32/esp -29743 # . save registers -29744 50/push-eax -29745 51/push-ecx -29746 52/push-edx -29747 53/push-ebx -29748 # -29749 (emit-indent *(ebp+8) *Curr-block-depth) -29750 (write-buffered *(ebp+8) "69/multiply") -29751 # ecx = stmt -29752 8b/-> *(ebp+0xc) 1/r32/ecx -29753 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] -29754 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29755 89/<- %ebx 0/r32/eax -29756 $translate-mu-compute-index-stmt:emit-index: -29757 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax -29758 (emit-subx-var-as-rm32 *(ebp+8) %eax) -29759 (write-buffered *(ebp+8) Space) -29760 $translate-mu-compute-index-stmt:emit-elem-size: -29761 # var base/ebx: (addr var) -29762 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax -29763 89/<- %ebx 0/r32/eax -29764 # print array-element-size(base) -29765 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -29766 (write-int32-hex-buffered *(ebp+8) %eax) -29767 (write-buffered *(ebp+8) "/imm32 ") -29768 $translate-mu-compute-index-stmt:emit-output: -29769 # outputs[0] "/r32" -29770 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -29771 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29772 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -29773 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -29774 (write-int32-hex-buffered *(ebp+8) *eax) -29775 (write-buffered *(ebp+8) "/r32\n") -29776 $translate-mu-compute-index-stmt:end: -29777 # . restore registers -29778 5b/pop-to-ebx -29779 5a/pop-to-edx -29780 59/pop-to-ecx -29781 58/pop-to-eax -29782 # . epilogue -29783 89/<- %esp 5/r32/ebp -29784 5d/pop-to-ebp -29785 c3/return -29786 -29787 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) -29788 # . prologue -29789 55/push-ebp -29790 89/<- %ebp 4/r32/esp -29791 # . save registers -29792 50/push-eax -29793 51/push-ecx -29794 52/push-edx -29795 # ecx = stmt -29796 8b/-> *(ebp+0xc) 1/r32/ecx -29797 # var base/eax: (addr var) = stmt->inouts->value -29798 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29799 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29800 # if base is in a register, insert a null check -29801 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -29802 { -29803 0f 84/jump-if-= break/disp32 -29804 $translate-mu-get-stmt:emit-null-check-for-register-input: -29805 # emit "81 7/subop/compare %" base->register " 0/imm32\n" -29806 (emit-indent *(ebp+8) *Curr-block-depth) -29807 (write-buffered *(ebp+8) "81 7/subop/compare %") -29808 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -29809 (write-buffered *(ebp+8) %eax) -29810 (write-buffered *(ebp+8) " 0/imm32\n") -29811 # -29812 (emit-indent *(ebp+8) *Curr-block-depth) -29813 (write-buffered *(ebp+8) "0f 84/jump-if-= __mu-abort-null-get-base-address/disp32\n") -29814 } -29815 # var offset/edx: int = get offset of stmt -29816 (mu-get-offset %ecx) # => eax -29817 89/<- %edx 0/r32/eax -29818 # var base/eax: (addr var) = stmt->inouts->value -29819 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29820 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29821 # -29822 (emit-indent *(ebp+8) *Curr-block-depth) -29823 (write-buffered *(ebp+8) "8d/copy-address ") -29824 # if base is in a register -29825 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -29826 { -29827 0f 84/jump-if-= break/disp32 -29828 $translate-mu-get-stmt:emit-register-input: -29829 # emit "*(" base->register " + " offset ") " -29830 (write-buffered *(ebp+8) "*(") -29831 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -29832 (write-buffered *(ebp+8) %eax) -29833 (write-buffered *(ebp+8) " + ") -29834 (write-int32-hex-buffered *(ebp+8) %edx) -29835 (write-buffered *(ebp+8) ") ") -29836 e9/jump $translate-mu-get-stmt:emit-output/disp32 -29837 } -29838 # otherwise base is on the stack -29839 { -29840 $translate-mu-get-stmt:emit-stack-input: -29841 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " -29842 (write-buffered *(ebp+8) "*(ebp+") -29843 03/add *(eax+0x14) 2/r32/edx # Var-offset -29844 (write-int32-hex-buffered *(ebp+8) %edx) -29845 (write-buffered *(ebp+8) ") ") -29846 eb/jump $translate-mu-get-stmt:emit-output/disp8 -29847 } -29848 $translate-mu-get-stmt:emit-output: -29849 # var output/eax: (addr var) = stmt->outputs->value -29850 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -29851 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29852 # emit offset->register "/r32" -29853 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -29854 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -29855 (write-int32-hex-buffered *(ebp+8) *eax) -29856 (write-buffered *(ebp+8) "/r32\n") -29857 $translate-mu-get-stmt:end: -29858 # . restore registers -29859 5a/pop-to-edx -29860 59/pop-to-ecx -29861 58/pop-to-eax -29862 # . epilogue -29863 89/<- %esp 5/r32/ebp -29864 5d/pop-to-ebp -29865 c3/return -29866 -29867 translate-mu-copy-object-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -29868 # . prologue -29869 55/push-ebp -29870 89/<- %ebp 4/r32/esp -29871 # . save registers -29872 50/push-eax -29873 # -29874 (emit-indent *(ebp+8) *Curr-block-depth) -29875 (write-buffered *(ebp+8) "(copy-bytes") -29876 # eax = stmt -29877 8b/-> *(ebp+0xc) 0/r32/eax -29878 # var first-inout/eax: (addr stmt-var) = stmt->inouts[0] -29879 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29880 (emit-subx-call-operand *(ebp+8) %eax) -29881 # var second-inout/eax: (addr stmt-var) = stmt->inouts[1] -29882 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -29883 (emit-subx-call-operand *(ebp+8) %eax) -29884 # emit size of inouts -29885 (write-buffered *(ebp+8) Space) -29886 (addr-payload-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax -29887 (write-int32-hex-buffered *(ebp+8) %eax) -29888 (write-buffered *(ebp+8) ")\n") -29889 $translate-mu-copy-object-stmt:end: -29890 # . restore registers -29891 58/pop-to-eax -29892 # . epilogue -29893 89/<- %esp 5/r32/ebp -29894 5d/pop-to-ebp -29895 c3/return -29896 -29897 translate-mu-clear-object-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -29898 # . prologue -29899 55/push-ebp -29900 89/<- %ebp 4/r32/esp -29901 # . save registers -29902 50/push-eax -29903 # -29904 (emit-indent *(ebp+8) *Curr-block-depth) -29905 (write-buffered *(ebp+8) "(zero-out") -29906 # eax = stmt -29907 8b/-> *(ebp+0xc) 0/r32/eax -29908 # var dest/eax: (addr stmt-var) = stmt->inouts[0] -29909 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29910 # -29911 (emit-subx-call-operand *(ebp+8) %eax) -29912 (write-buffered *(ebp+8) Space) -29913 (addr-payload-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax -29914 (write-int32-hex-buffered *(ebp+8) %eax) -29915 (write-buffered *(ebp+8) ")\n") -29916 $translate-mu-clear-object-stmt:end: -29917 # . restore registers -29918 58/pop-to-eax -29919 # . epilogue -29920 89/<- %esp 5/r32/ebp -29921 5d/pop-to-ebp -29922 c3/return -29923 -29924 translate-mu-allocate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -29925 # . prologue -29926 55/push-ebp -29927 89/<- %ebp 4/r32/esp -29928 # . save registers -29929 50/push-eax -29930 56/push-esi -29931 57/push-edi -29932 # esi = stmt -29933 8b/-> *(ebp+0xc) 6/r32/esi -29934 # var target/edi: (addr stmt-var) = stmt->inouts[0] -29935 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -29936 89/<- %edi 0/r32/eax -29937 # -29938 (emit-indent *(ebp+8) *Curr-block-depth) -29939 (write-buffered *(ebp+8) "(allocate Heap ") -29940 (addr-handle-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -29941 (write-int32-hex-buffered *(ebp+8) %eax) -29942 (emit-subx-call-operand *(ebp+8) %edi) -29943 (write-buffered *(ebp+8) ")\n") -29944 $translate-mu-allocate-stmt:end: -29945 # . restore registers -29946 5f/pop-to-edi -29947 5e/pop-to-esi -29948 58/pop-to-eax -29949 # . epilogue -29950 89/<- %esp 5/r32/ebp -29951 5d/pop-to-ebp -29952 c3/return -29953 -29954 addr-handle-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -29955 # . prologue -29956 55/push-ebp -29957 89/<- %ebp 4/r32/esp -29958 # var t/eax: (addr type-tree) = s->value->type -29959 8b/-> *(ebp+8) 0/r32/eax -29960 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29961 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -29962 # TODO: check eax != 0 -29963 # TODO: check !t->is-atom? -29964 # TODO: check t->left == addr -29965 # t = t->right -29966 $addr-handle-payload-size:skip-addr: -29967 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -29968 # TODO: check eax != 0 -29969 # TODO: check !t->is-atom? -29970 # TODO: check t->left == handle -29971 # t = t->right -29972 $addr-handle-payload-size:skip-handle: -29973 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -29974 # TODO: check eax != 0 -29975 # if !t->is-atom? t = t->left -29976 81 7/subop/compare *eax 0/imm32/false -29977 { -29978 75/jump-if-!= break/disp8 -29979 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -29980 } -29981 # TODO: check t->is-atom? -29982 # return size(t->value) -29983 (size-of-type-id *(eax+4)) # Type-tree-value => eax -29984 $addr-handle-payload-size:end: -29985 # . epilogue -29986 89/<- %esp 5/r32/ebp -29987 5d/pop-to-ebp -29988 c3/return -29989 -29990 addr-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -29991 # . prologue -29992 55/push-ebp -29993 89/<- %ebp 4/r32/esp -29994 # var t/eax: (addr type-tree) = s->value->type -29995 8b/-> *(ebp+8) 0/r32/eax -29996 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -29997 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -29998 # TODO: check eax != 0 -29999 # TODO: check !t->is-atom? -30000 # TODO: check t->left == addr -30001 # t = t->right -30002 $addr-payload-size:skip-addr: -30003 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -30004 # TODO: check eax != 0 -30005 # if !t->is-atom? t = t->left -30006 81 7/subop/compare *eax 0/imm32/false -30007 { -30008 75/jump-if-!= break/disp8 -30009 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -30010 } -30011 # TODO: check t->is-atom? -30012 # return size(t->value) -30013 (size-of-type-id *(eax+4)) # Type-tree-value => eax -30014 $addr-payload-size:end: -30015 # . epilogue -30016 89/<- %esp 5/r32/ebp -30017 5d/pop-to-ebp -30018 c3/return -30019 -30020 translate-mu-populate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -30021 # . prologue -30022 55/push-ebp -30023 89/<- %ebp 4/r32/esp -30024 # . save registers -30025 50/push-eax -30026 51/push-ecx -30027 56/push-esi -30028 57/push-edi -30029 # esi = stmt -30030 8b/-> *(ebp+0xc) 6/r32/esi -30031 # var target/edi: (addr stmt-var) = stmt->inouts[0] -30032 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -30033 89/<- %edi 0/r32/eax -30034 # var len/ecx: (addr stmt-var) = stmt->inouts[1] -30035 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -30036 89/<- %ecx 0/r32/eax -30037 # -30038 (emit-indent *(ebp+8) *Curr-block-depth) -30039 (write-buffered *(ebp+8) "(allocate-array2 Heap ") -30040 (addr-handle-array-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -30041 (write-int32-hex-buffered *(ebp+8) %eax) -30042 (emit-subx-call-operand *(ebp+8) %ecx) -30043 (emit-subx-call-operand *(ebp+8) %edi) -30044 (write-buffered *(ebp+8) ")\n") -30045 $translate-mu-populate-stmt:end: -30046 # . restore registers -30047 5f/pop-to-edi -30048 5e/pop-to-esi -30049 59/pop-to-ecx -30050 58/pop-to-eax -30051 # . epilogue -30052 89/<- %esp 5/r32/ebp -30053 5d/pop-to-ebp -30054 c3/return -30055 -30056 translate-mu-populate-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -30057 # . prologue -30058 55/push-ebp -30059 89/<- %ebp 4/r32/esp -30060 # . save registers -30061 50/push-eax -30062 51/push-ecx -30063 56/push-esi -30064 57/push-edi -30065 # esi = stmt -30066 8b/-> *(ebp+0xc) 6/r32/esi -30067 # var target/edi: (addr stmt-var) = stmt->inouts[0] -30068 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -30069 89/<- %edi 0/r32/eax -30070 # var len/ecx: (addr stmt-var) = stmt->inouts[1] -30071 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax -30072 89/<- %ecx 0/r32/eax -30073 # -30074 (emit-indent *(ebp+8) *Curr-block-depth) -30075 (write-buffered *(ebp+8) "(new-stream Heap ") -30076 (addr-handle-stream-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -30077 (write-int32-hex-buffered *(ebp+8) %eax) -30078 (emit-subx-call-operand *(ebp+8) %ecx) -30079 (emit-subx-call-operand *(ebp+8) %edi) -30080 (write-buffered *(ebp+8) ")\n") -30081 $translate-mu-populate-stream-stmt:end: -30082 # . restore registers -30083 5f/pop-to-edi -30084 5e/pop-to-esi -30085 59/pop-to-ecx -30086 58/pop-to-eax -30087 # . epilogue -30088 89/<- %esp 5/r32/ebp -30089 5d/pop-to-ebp -30090 c3/return -30091 -30092 translate-mu-read-from-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -30093 # . prologue -30094 55/push-ebp -30095 89/<- %ebp 4/r32/esp -30096 # . save registers -30097 50/push-eax -30098 51/push-ecx -30099 56/push-esi -30100 57/push-edi -30101 # esi = stmt -30102 8b/-> *(ebp+0xc) 6/r32/esi -30103 # var stream/ecx: (addr stmt-var) = stmt->inouts[0] -30104 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -30105 89/<- %ecx 0/r32/eax -30106 # var target/edi: (addr stmt-var) = stmt->inouts[1] -30107 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -30108 89/<- %edi 0/r32/eax -30109 # -30110 (emit-indent *(ebp+8) *Curr-block-depth) -30111 (write-buffered *(ebp+8) "(read-from-stream") -30112 (emit-subx-call-operand *(ebp+8) %ecx) -30113 (emit-subx-call-operand *(ebp+8) %edi) -30114 (write-buffered *(ebp+8) Space) -30115 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -30116 (write-int32-hex-buffered *(ebp+8) %eax) -30117 (write-buffered *(ebp+8) ")\n") -30118 $translate-mu-read-from-stream-stmt:end: -30119 # . restore registers -30120 5f/pop-to-edi -30121 5e/pop-to-esi -30122 59/pop-to-ecx -30123 58/pop-to-eax -30124 # . epilogue -30125 89/<- %esp 5/r32/ebp -30126 5d/pop-to-ebp -30127 c3/return -30128 -30129 translate-mu-write-to-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -30130 # . prologue -30131 55/push-ebp -30132 89/<- %ebp 4/r32/esp -30133 # . save registers -30134 50/push-eax -30135 51/push-ecx -30136 56/push-esi -30137 57/push-edi -30138 # esi = stmt -30139 8b/-> *(ebp+0xc) 6/r32/esi -30140 # var stream/ecx: (addr stmt-var) = stmt->inouts[0] -30141 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -30142 89/<- %ecx 0/r32/eax -30143 # var target/edi: (addr stmt-var) = stmt->inouts[1] -30144 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -30145 89/<- %edi 0/r32/eax -30146 # -30147 (emit-indent *(ebp+8) *Curr-block-depth) -30148 (write-buffered *(ebp+8) "(write-to-stream") -30149 (emit-subx-call-operand *(ebp+8) %ecx) -30150 (flush *(ebp+8)) -30151 (emit-subx-call-operand *(ebp+8) %edi) -30152 (flush *(ebp+8)) -30153 (write-buffered *(ebp+8) Space) -30154 (flush *(ebp+8)) -30155 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax -30156 (write-int32-hex-buffered *(ebp+8) %eax) -30157 (write-buffered *(ebp+8) ")\n") -30158 $translate-mu-write-to-stream-stmt:end: -30159 # . restore registers -30160 5f/pop-to-edi -30161 5e/pop-to-esi -30162 59/pop-to-ecx -30163 58/pop-to-eax -30164 # . epilogue -30165 89/<- %esp 5/r32/ebp -30166 5d/pop-to-ebp -30167 c3/return -30168 -30169 addr-handle-array-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -30170 # . prologue -30171 55/push-ebp -30172 89/<- %ebp 4/r32/esp -30173 # var t/eax: (addr type-tree) = s->value->type -30174 8b/-> *(ebp+8) 0/r32/eax -30175 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -30176 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -30177 # TODO: check eax != 0 -30178 # TODO: check !t->is-atom? -30179 # TODO: check t->left == addr -30180 # t = t->right -30181 $addr-handle-array-payload-size:skip-addr: -30182 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -30183 # TODO: check eax != 0 -30184 # TODO: check !t->is-atom? -30185 # TODO: check t->left == handle -30186 # t = t->right -30187 $addr-handle-array-payload-size:skip-handle: -30188 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -30189 # TODO: check eax != 0 -30190 # TODO: check !t->is-atom? -30191 # TODO: check t->left == array -30192 # t = t->right -30193 $addr-handle-array-payload-size:skip-array: -30194 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -30195 # TODO: check eax != 0 -30196 # if !t->is-atom? t = t->left -30197 81 7/subop/compare *eax 0/imm32/false -30198 { -30199 75/jump-if-!= break/disp8 -30200 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -30201 } -30202 $addr-handle-array-payload-size:compute-size: -30203 # TODO: check t->is-atom? -30204 # return size(t->value) -30205 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax -30206 $addr-handle-array-payload-size:end: -30207 # . epilogue -30208 89/<- %esp 5/r32/ebp -30209 5d/pop-to-ebp -30210 c3/return -30211 -30212 addr-handle-stream-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -30213 # . prologue -30214 55/push-ebp -30215 89/<- %ebp 4/r32/esp -30216 # var t/eax: (addr type-tree) = s->value->type -30217 8b/-> *(ebp+8) 0/r32/eax -30218 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -30219 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -30220 # TODO: check eax != 0 -30221 # TODO: check !t->is-atom? -30222 # TODO: check t->left == addr -30223 # t = t->right -30224 $addr-handle-stream-payload-size:skip-addr: -30225 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -30226 # TODO: check eax != 0 -30227 # TODO: check !t->is-atom? -30228 # TODO: check t->left == handle -30229 # t = t->right -30230 $addr-handle-stream-payload-size:skip-handle: -30231 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -30232 # TODO: check eax != 0 -30233 # TODO: check !t->is-atom? -30234 # TODO: check t->left == stream -30235 # t = t->right -30236 $addr-handle-stream-payload-size:skip-stream: -30237 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -30238 # TODO: check eax != 0 -30239 # if !t->is-atom? t = t->left -30240 81 7/subop/compare *eax 0/imm32/false -30241 { -30242 75/jump-if-!= break/disp8 -30243 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -30244 } -30245 $addr-handle-stream-payload-size:compute-size: -30246 # TODO: check t->is-atom? -30247 # return size(t->value) -30248 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax -30249 $addr-handle-stream-payload-size:end: -30250 # . epilogue -30251 89/<- %esp 5/r32/ebp -30252 5d/pop-to-ebp -30253 c3/return -30254 -30255 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean -30256 # precondition: n is positive -30257 # . prologue -30258 55/push-ebp -30259 89/<- %ebp 4/r32/esp -30260 # eax = n -30261 8b/-> *(ebp+8) 0/r32/eax -30262 # if (n < 0) abort -30263 3d/compare-eax-with 0/imm32 -30264 0f 8c/jump-if-< $power-of-2?:abort/disp32 -30265 # var tmp/eax: int = n-1 -30266 48/decrement-eax -30267 # var tmp2/eax: int = n & tmp -30268 23/and-> *(ebp+8) 0/r32/eax -30269 # return (tmp2 == 0) -30270 3d/compare-eax-and 0/imm32 -30271 0f 94/set-byte-if-= %al -30272 25/and-eax-with 0xff/imm32 -30273 $power-of-2?:end: -30274 # . epilogue -30275 89/<- %esp 5/r32/ebp -30276 5d/pop-to-ebp -30277 c3/return -30278 -30279 $power-of-2?:abort: -30280 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n") -30281 (flush *(ebp+0xc)) -30282 (stop *(ebp+0x10) 1) -30283 # never gets here -30284 -30285 num-shift-rights: # n: int -> result/eax: int -30286 # precondition: n is a positive power of 2 -30287 # . prologue -30288 55/push-ebp -30289 89/<- %ebp 4/r32/esp -30290 # . save registers -30291 51/push-ecx -30292 # var curr/ecx: int = n -30293 8b/-> *(ebp+8) 1/r32/ecx -30294 # result = 0 -30295 b8/copy-to-eax 0/imm32 -30296 { -30297 # if (curr <= 1) break -30298 81 7/subop/compare %ecx 1/imm32 -30299 7e/jump-if-<= break/disp8 -30300 40/increment-eax -30301 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 -30302 eb/jump loop/disp8 -30303 } -30304 $num-shift-rights:end: -30305 # . restore registers -30306 59/pop-to-ecx -30307 # . epilogue -30308 89/<- %esp 5/r32/ebp -30309 5d/pop-to-ebp -30310 c3/return -30311 -30312 mu-get-offset: # stmt: (addr stmt) -> result/eax: int -30313 # . prologue -30314 55/push-ebp -30315 89/<- %ebp 4/r32/esp -30316 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next -30317 8b/-> *(ebp+8) 0/r32/eax -30318 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -30319 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -30320 # var output-var/eax: (addr var) = second-inout->value -30321 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -30322 #? (write-buffered Stderr "mu-get-offset: ") -30323 #? (write-int32-hex-buffered Stderr %eax) -30324 #? (write-buffered Stderr " name: ") -30325 #? 50/push-eax -30326 #? (lookup *eax *(eax+4)) # Var-name -30327 #? (write-buffered Stderr %eax) -30328 #? 58/pop-to-eax -30329 #? (write-buffered Stderr Newline) -30330 #? (flush Stderr) -30331 # return output-var->stack-offset -30332 8b/-> *(eax+0x14) 0/r32/eax # Var-offset -30333 #? (write-buffered Stderr "=> ") -30334 #? (write-int32-hex-buffered Stderr %eax) -30335 #? (write-buffered Stderr Newline) -30336 #? (flush Stderr) -30337 $emit-get-offset:end: -30338 # . epilogue -30339 89/<- %esp 5/r32/ebp -30340 5d/pop-to-ebp -30341 c3/return -30342 -30343 emit-subx-block: # out: (addr buffered-file), block: (addr block), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -30344 # . prologue -30345 55/push-ebp -30346 89/<- %ebp 4/r32/esp -30347 # . save registers -30348 50/push-eax -30349 51/push-ecx -30350 56/push-esi -30351 # esi = block -30352 8b/-> *(ebp+0xc) 6/r32/esi -30353 # block->var->block-depth = *Curr-block-depth -30354 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax -30355 8b/-> *Curr-block-depth 1/r32/ecx -30356 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth -30357 # var stmts/eax: (addr list stmt) = lookup(block->statements) -30358 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax -30359 # -30360 { -30361 $emit-subx-block:check-empty: -30362 3d/compare-eax-and 0/imm32 -30363 0f 84/jump-if-= break/disp32 -30364 (emit-indent *(ebp+8) *Curr-block-depth) -30365 (write-buffered *(ebp+8) "{\n") -30366 # var v/ecx: (addr var) = lookup(block->var) -30367 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax -30368 89/<- %ecx 0/r32/eax -30369 # -30370 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -30371 (write-buffered *(ebp+8) %eax) -30372 (write-buffered *(ebp+8) ":loop:\n") -30373 ff 0/subop/increment *Curr-block-depth -30374 (push *(ebp+0x10) *(esi+0xc)) # Block-var -30375 (push *(ebp+0x10) *(esi+0x10)) # Block-var -30376 (push *(ebp+0x10) 0) # false -30377 # emit block->statements -30378 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax -30379 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -30380 (pop *(ebp+0x10)) # => eax -30381 (pop *(ebp+0x10)) # => eax -30382 (pop *(ebp+0x10)) # => eax -30383 ff 1/subop/decrement *Curr-block-depth -30384 (emit-indent *(ebp+8) *Curr-block-depth) -30385 (write-buffered *(ebp+8) "}\n") -30386 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -30387 (write-buffered *(ebp+8) %eax) -30388 (write-buffered *(ebp+8) ":break:\n") -30389 } -30390 $emit-subx-block:end: -30391 # . restore registers -30392 5e/pop-to-esi -30393 59/pop-to-ecx -30394 58/pop-to-eax -30395 # . epilogue -30396 89/<- %esp 5/r32/ebp -30397 5d/pop-to-ebp -30398 c3/return -30399 -30400 # Primitives supported -30401 # See mu_instructions for a summary of this linked-list data structure. -30402 # -30403 # For each operation, put variants with hard-coded registers before flexible ones. -30404 # -30405 # Unfortunately, our restrictions on addresses require that various fields in -30406 # primitives be handles, which complicates these definitions. -30407 # - we need to insert dummy fields all over the place for fake alloc-ids -30408 # - we can't use our syntax sugar of quoted literals for string fields -30409 # -30410 # Fake alloc-ids are needed because our type definitions up top require -30411 # handles but it's clearer to statically allocate these long-lived objects. -30412 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. -30413 # -30414 # Every 'object' below starts with a fake alloc-id. It may also contain other -30415 # fake alloc-ids for various handle fields. -30416 # -30417 # I think of objects starting with a fake alloc-id as having type 'payload'. -30418 # It's not really intended to be created dynamically; for that use `allocate` -30419 # as usual. -30420 # -30421 # Idea for a notation to simplify such definitions: -30422 # _Primitive-increment-eax: # (payload primitive) -30423 # 0x11/alloc-id:fake:payload -30424 # 0x11 @(0x11 "increment") # name -30425 # 0 0 # inouts -30426 # 0x11 @(0x11/payload -30427 # 0x11 @(0x11/payload # List-value -30428 # 0 0 # Var-name -30429 # 0x11 @(0x11 # Var-type -30430 # 1/is-atom -30431 # 1/value 0/unused # Type-tree-left -30432 # 0 0 # Type-tree-right -30433 # ) -30434 # 1 # block-depth -30435 # 0 # stack-offset -30436 # 0x11 @(0x11 "eax") # Var-register -30437 # ) -30438 # 0 0) # List-next -30439 # ... -30440 # _Primitive-increment-ecx/imm32/next -30441 # ... -30442 # Awfully complex and non-obvious. But also clearly signals there's something -30443 # to learn here, so may be worth trying. -30444 # -30445 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " -30446 # -30447 # For now we'll continue to just use comments and manually ensure they stay up -30448 # to date. -30449 == data -30450 Primitives: # (addr primitive) -30451 # - increment/decrement -30452 _Primitive-increment-eax: # (addr primitive) -30453 # var/eax <- increment => 40/increment-eax -30454 0x11/imm32/alloc-id:fake -30455 _string-increment/imm32/name -30456 0/imm32/no-inouts -30457 0/imm32/no-inouts -30458 0x11/imm32/alloc-id:fake -30459 Single-int-var-in-eax/imm32/outputs -30460 0x11/imm32/alloc-id:fake -30461 _string_40_increment_eax/imm32/subx-name -30462 0/imm32/no-rm32 -30463 0/imm32/no-r32 -30464 0/imm32/no-imm32 -30465 0/imm32/no-imm8 -30466 0/imm32/no-disp32 -30467 0/imm32/no-xm32 -30468 0/imm32/no-x32 -30469 0x11/imm32/alloc-id:fake -30470 _Primitive-increment-ecx/imm32/next -30471 _Primitive-increment-ecx: # (payload primitive) -30472 0x11/imm32/alloc-id:fake:payload -30473 # var/ecx <- increment => 41/increment-ecx -30474 0x11/imm32/alloc-id:fake -30475 _string-increment/imm32/name +29559 (simple-mu-type? %eax 1) # int => eax +29560 3d/compare-eax-and 0/imm32/false +29561 { +29562 0f 84/jump-if-= break/disp32 +29563 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: +29564 # print index->register "<<" log2(array-element-size(base)) " + 4) " +29565 # . index->register "<<" +29566 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +29567 (write-buffered *(ebp+8) %eax) +29568 (write-buffered *(ebp+8) "<<") +29569 # . log2(array-element-size(base->type)) +29570 # we know size is a power of 2 +29571 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +29572 (num-shift-rights %eax) # => eax +29573 (write-int32-hex-buffered *(ebp+8) %eax) +29574 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 +29575 } +29576 # if index->type is any other atom, abort +29577 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29578 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29579 0f 85/jump-if-!= $translate-mu-index-stmt:error2/disp32 +29580 # if index has type (offset ...) +29581 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29582 (simple-mu-type? %eax 7) # => eax +29583 3d/compare-eax-and 0/imm32/false +29584 { +29585 0f 84/jump-if-= break/disp32 +29586 # print index->register +29587 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: +29588 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +29589 (write-buffered *(ebp+8) %eax) +29590 } +29591 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: +29592 (write-buffered *(ebp+8) " + 4) ") +29593 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 +29594 } +29595 # otherwise if index is a literal +29596 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29597 (simple-mu-type? %eax 0) # => eax +29598 3d/compare-eax-and 0/imm32/false +29599 { +29600 0f 84/jump-if-= break/disp32 +29601 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: +29602 # var index-value/edx: int = parse-hex-int(index->name) +29603 (lookup *edx *(edx+4)) # Var-name Var-name => eax +29604 (parse-hex-int %eax) # => eax +29605 89/<- %edx 0/r32/eax +29606 # offset = idx-value * array-element-size(base->type) +29607 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +29608 f7 4/subop/multiply-into-edx-eax %edx # clobbers edx +29609 # offset += 4 for array size +29610 05/add-to-eax 4/imm32 +29611 # TODO: check edx for overflow +29612 # print offset +29613 (write-int32-hex-buffered *(ebp+8) %eax) +29614 (write-buffered *(ebp+8) ") ") +29615 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 +29616 } +29617 # otherwise abort +29618 e9/jump $translate-mu-index-stmt:error1/disp32 +29619 $translate-mu-index-stmt-with-array-in-register:emit-output: +29620 # outputs[0] "/r32" +29621 8b/-> *(ebp+0xc) 1/r32/ecx +29622 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +29623 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29624 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +29625 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +29626 (write-int32-hex-buffered *(ebp+8) *eax) +29627 (write-buffered *(ebp+8) "/r32\n") +29628 $translate-mu-index-stmt-with-array-in-register:end: +29629 # . restore registers +29630 5b/pop-to-ebx +29631 5a/pop-to-edx +29632 59/pop-to-ecx +29633 58/pop-to-eax +29634 # . epilogue +29635 89/<- %esp 5/r32/ebp +29636 5d/pop-to-ebp +29637 c3/return +29638 +29639 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +29640 # . prologue +29641 55/push-ebp +29642 89/<- %ebp 4/r32/esp +29643 # . save registers +29644 50/push-eax +29645 51/push-ecx +29646 52/push-edx +29647 53/push-ebx +29648 # +29649 (emit-indent *(ebp+8) *Curr-block-depth) +29650 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") +29651 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) +29652 8b/-> *(ebp+0xc) 0/r32/eax +29653 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29654 89/<- %edx 0/r32/eax +29655 # var base/ecx: (addr var) = lookup(curr->value) +29656 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29657 89/<- %ecx 0/r32/eax +29658 # var curr2/eax: (addr stmt-var) = lookup(curr->next) +29659 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax +29660 # var index/edx: (handle var) = curr2->value +29661 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29662 89/<- %edx 0/r32/eax +29663 # if index->register +29664 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +29665 { +29666 0f 84/jump-if-= break/disp32 +29667 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: +29668 # if index is an int +29669 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29670 (simple-mu-type? %eax 1) # int => eax +29671 3d/compare-eax-and 0/imm32/false +29672 { +29673 0f 84/jump-if-= break/disp32 +29674 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: +29675 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4 +29676 # . inouts[1]->register "<<" +29677 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +29678 (write-buffered *(ebp+8) %eax) +29679 (write-buffered *(ebp+8) "<<") +29680 # . log2(array-element-size(base)) +29681 # TODO: ensure size is a power of 2 +29682 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +29683 (num-shift-rights %eax) # => eax +29684 (write-int32-hex-buffered *(ebp+8) %eax) +29685 # +29686 (write-buffered *(ebp+8) " + ") +29687 # +29688 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset +29689 05/add-to-eax 4/imm32 # for array length +29690 (write-int32-hex-buffered *(ebp+8) %eax) +29691 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 +29692 } +29693 # if index->type is any other atom, abort +29694 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29695 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +29696 0f 85/jump-if-!= $translate-mu-index-stmt:error2/disp32 +29697 # if index has type (offset ...) +29698 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29699 (simple-mu-type? %eax 7) # => eax +29700 3d/compare-eax-and 0/imm32/false +29701 { +29702 0f 84/jump-if-= break/disp32 +29703 # print index->register +29704 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: +29705 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +29706 (write-buffered *(ebp+8) %eax) +29707 } +29708 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: +29709 (write-buffered *(ebp+8) ") ") +29710 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 +29711 } +29712 # otherwise if index is a literal +29713 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +29714 (simple-mu-type? %eax 0) # => eax +29715 3d/compare-eax-and 0/imm32/false +29716 { +29717 0f 84/jump-if-= break/disp32 +29718 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: +29719 # var idx-value/edx: int = parse-hex-int(index->name) +29720 (lookup *edx *(edx+4)) # Var-name Var-name => eax +29721 (parse-hex-int %eax) # Var-name => eax +29722 89/<- %edx 0/r32/eax +29723 # offset = idx-value * array-element-size(base) +29724 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +29725 f7 4/subop/multiply-into-edx-eax %edx # clobbers edx +29726 # offset += base->offset +29727 03/add *(ecx+0x14) 0/r32/eax # Var-offset +29728 # offset += 4 for array size +29729 05/add-to-eax 4/imm32 +29730 # TODO: check edx for overflow +29731 # print offset +29732 (write-int32-hex-buffered *(ebp+8) %eax) +29733 (write-buffered *(ebp+8) ") ") +29734 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 +29735 } +29736 # otherwise abort +29737 e9/jump $translate-mu-index-stmt:error1/disp32 +29738 $translate-mu-index-stmt-with-array-on-stack:emit-output: +29739 # outputs[0] "/r32" +29740 8b/-> *(ebp+0xc) 0/r32/eax +29741 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax +29742 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29743 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +29744 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +29745 (write-int32-hex-buffered *(ebp+8) *eax) +29746 (write-buffered *(ebp+8) "/r32\n") +29747 $translate-mu-index-stmt-with-array-on-stack:end: +29748 # . restore registers +29749 5b/pop-to-ebx +29750 5a/pop-to-edx +29751 59/pop-to-ecx +29752 58/pop-to-eax +29753 # . epilogue +29754 89/<- %esp 5/r32/ebp +29755 5d/pop-to-ebp +29756 c3/return +29757 +29758 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +29759 # . prologue +29760 55/push-ebp +29761 89/<- %ebp 4/r32/esp +29762 # . save registers +29763 50/push-eax +29764 51/push-ecx +29765 52/push-edx +29766 53/push-ebx +29767 # +29768 (emit-indent *(ebp+8) *Curr-block-depth) +29769 (write-buffered *(ebp+8) "69/multiply") +29770 # ecx = stmt +29771 8b/-> *(ebp+0xc) 1/r32/ecx +29772 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] +29773 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29774 89/<- %ebx 0/r32/eax +29775 $translate-mu-compute-index-stmt:emit-index: +29776 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax +29777 (emit-subx-var-as-rm32 *(ebp+8) %eax) +29778 (write-buffered *(ebp+8) Space) +29779 $translate-mu-compute-index-stmt:emit-elem-size: +29780 # var base/ebx: (addr var) +29781 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax +29782 89/<- %ebx 0/r32/eax +29783 # print array-element-size(base) +29784 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +29785 (write-int32-hex-buffered *(ebp+8) %eax) +29786 (write-buffered *(ebp+8) "/imm32 ") +29787 $translate-mu-compute-index-stmt:emit-output: +29788 # outputs[0] "/r32" +29789 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +29790 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29791 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +29792 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +29793 (write-int32-hex-buffered *(ebp+8) *eax) +29794 (write-buffered *(ebp+8) "/r32\n") +29795 $translate-mu-compute-index-stmt:end: +29796 # . restore registers +29797 5b/pop-to-ebx +29798 5a/pop-to-edx +29799 59/pop-to-ecx +29800 58/pop-to-eax +29801 # . epilogue +29802 89/<- %esp 5/r32/ebp +29803 5d/pop-to-ebp +29804 c3/return +29805 +29806 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) +29807 # . prologue +29808 55/push-ebp +29809 89/<- %ebp 4/r32/esp +29810 # . save registers +29811 50/push-eax +29812 51/push-ecx +29813 52/push-edx +29814 # ecx = stmt +29815 8b/-> *(ebp+0xc) 1/r32/ecx +29816 # var base/eax: (addr var) = stmt->inouts->value +29817 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29818 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29819 # if base is in a register, insert a null check +29820 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +29821 { +29822 0f 84/jump-if-= break/disp32 +29823 $translate-mu-get-stmt:emit-null-check-for-register-input: +29824 # emit "81 7/subop/compare %" base->register " 0/imm32\n" +29825 (emit-indent *(ebp+8) *Curr-block-depth) +29826 (write-buffered *(ebp+8) "81 7/subop/compare %") +29827 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +29828 (write-buffered *(ebp+8) %eax) +29829 (write-buffered *(ebp+8) " 0/imm32\n") +29830 # +29831 (emit-indent *(ebp+8) *Curr-block-depth) +29832 (write-buffered *(ebp+8) "0f 84/jump-if-= __mu-abort-null-get-base-address/disp32\n") +29833 } +29834 # var offset/edx: int = get offset of stmt +29835 (mu-get-offset %ecx) # => eax +29836 89/<- %edx 0/r32/eax +29837 # var base/eax: (addr var) = stmt->inouts->value +29838 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29839 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29840 # +29841 (emit-indent *(ebp+8) *Curr-block-depth) +29842 (write-buffered *(ebp+8) "8d/copy-address ") +29843 # if base is in a register +29844 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +29845 { +29846 0f 84/jump-if-= break/disp32 +29847 $translate-mu-get-stmt:emit-register-input: +29848 # emit "*(" base->register " + " offset ") " +29849 (write-buffered *(ebp+8) "*(") +29850 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +29851 (write-buffered *(ebp+8) %eax) +29852 (write-buffered *(ebp+8) " + ") +29853 (write-int32-hex-buffered *(ebp+8) %edx) +29854 (write-buffered *(ebp+8) ") ") +29855 e9/jump $translate-mu-get-stmt:emit-output/disp32 +29856 } +29857 # otherwise base is on the stack +29858 { +29859 $translate-mu-get-stmt:emit-stack-input: +29860 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " +29861 (write-buffered *(ebp+8) "*(ebp+") +29862 03/add *(eax+0x14) 2/r32/edx # Var-offset +29863 (write-int32-hex-buffered *(ebp+8) %edx) +29864 (write-buffered *(ebp+8) ") ") +29865 eb/jump $translate-mu-get-stmt:emit-output/disp8 +29866 } +29867 $translate-mu-get-stmt:emit-output: +29868 # var output/eax: (addr var) = stmt->outputs->value +29869 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +29870 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29871 # emit offset->register "/r32" +29872 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +29873 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +29874 (write-int32-hex-buffered *(ebp+8) *eax) +29875 (write-buffered *(ebp+8) "/r32\n") +29876 $translate-mu-get-stmt:end: +29877 # . restore registers +29878 5a/pop-to-edx +29879 59/pop-to-ecx +29880 58/pop-to-eax +29881 # . epilogue +29882 89/<- %esp 5/r32/ebp +29883 5d/pop-to-ebp +29884 c3/return +29885 +29886 translate-mu-copy-object-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +29887 # . prologue +29888 55/push-ebp +29889 89/<- %ebp 4/r32/esp +29890 # . save registers +29891 50/push-eax +29892 # +29893 (emit-indent *(ebp+8) *Curr-block-depth) +29894 (write-buffered *(ebp+8) "(copy-bytes") +29895 # eax = stmt +29896 8b/-> *(ebp+0xc) 0/r32/eax +29897 # var first-inout/eax: (addr stmt-var) = stmt->inouts[0] +29898 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29899 (emit-subx-call-operand *(ebp+8) %eax) +29900 # var second-inout/eax: (addr stmt-var) = stmt->inouts[1] +29901 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +29902 (emit-subx-call-operand *(ebp+8) %eax) +29903 # emit size of inouts +29904 (write-buffered *(ebp+8) Space) +29905 (addr-payload-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax +29906 (write-int32-hex-buffered *(ebp+8) %eax) +29907 (write-buffered *(ebp+8) ")\n") +29908 $translate-mu-copy-object-stmt:end: +29909 # . restore registers +29910 58/pop-to-eax +29911 # . epilogue +29912 89/<- %esp 5/r32/ebp +29913 5d/pop-to-ebp +29914 c3/return +29915 +29916 translate-mu-clear-object-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +29917 # . prologue +29918 55/push-ebp +29919 89/<- %ebp 4/r32/esp +29920 # . save registers +29921 50/push-eax +29922 # +29923 (emit-indent *(ebp+8) *Curr-block-depth) +29924 (write-buffered *(ebp+8) "(zero-out") +29925 # eax = stmt +29926 8b/-> *(ebp+0xc) 0/r32/eax +29927 # var dest/eax: (addr stmt-var) = stmt->inouts[0] +29928 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29929 # +29930 (emit-subx-call-operand *(ebp+8) %eax) +29931 (write-buffered *(ebp+8) Space) +29932 (addr-payload-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax +29933 (write-int32-hex-buffered *(ebp+8) %eax) +29934 (write-buffered *(ebp+8) ")\n") +29935 $translate-mu-clear-object-stmt:end: +29936 # . restore registers +29937 58/pop-to-eax +29938 # . epilogue +29939 89/<- %esp 5/r32/ebp +29940 5d/pop-to-ebp +29941 c3/return +29942 +29943 translate-mu-allocate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +29944 # . prologue +29945 55/push-ebp +29946 89/<- %ebp 4/r32/esp +29947 # . save registers +29948 50/push-eax +29949 56/push-esi +29950 57/push-edi +29951 # esi = stmt +29952 8b/-> *(ebp+0xc) 6/r32/esi +29953 # var target/edi: (addr stmt-var) = stmt->inouts[0] +29954 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +29955 89/<- %edi 0/r32/eax +29956 # +29957 (emit-indent *(ebp+8) *Curr-block-depth) +29958 (write-buffered *(ebp+8) "(allocate Heap ") +29959 (addr-handle-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +29960 (write-int32-hex-buffered *(ebp+8) %eax) +29961 (emit-subx-call-operand *(ebp+8) %edi) +29962 (write-buffered *(ebp+8) ")\n") +29963 $translate-mu-allocate-stmt:end: +29964 # . restore registers +29965 5f/pop-to-edi +29966 5e/pop-to-esi +29967 58/pop-to-eax +29968 # . epilogue +29969 89/<- %esp 5/r32/ebp +29970 5d/pop-to-ebp +29971 c3/return +29972 +29973 addr-handle-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +29974 # . prologue +29975 55/push-ebp +29976 89/<- %ebp 4/r32/esp +29977 # var t/eax: (addr type-tree) = s->value->type +29978 8b/-> *(ebp+8) 0/r32/eax +29979 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +29980 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +29981 # TODO: check eax != 0 +29982 # TODO: check !t->is-atom? +29983 # TODO: check t->left == addr +29984 # t = t->right +29985 $addr-handle-payload-size:skip-addr: +29986 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +29987 # TODO: check eax != 0 +29988 # TODO: check !t->is-atom? +29989 # TODO: check t->left == handle +29990 # t = t->right +29991 $addr-handle-payload-size:skip-handle: +29992 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +29993 # TODO: check eax != 0 +29994 # if !t->is-atom? t = t->left +29995 81 7/subop/compare *eax 0/imm32/false +29996 { +29997 75/jump-if-!= break/disp8 +29998 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +29999 } +30000 # TODO: check t->is-atom? +30001 # return size(t->value) +30002 (size-of-type-id *(eax+4)) # Type-tree-value => eax +30003 $addr-handle-payload-size:end: +30004 # . epilogue +30005 89/<- %esp 5/r32/ebp +30006 5d/pop-to-ebp +30007 c3/return +30008 +30009 addr-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +30010 # . prologue +30011 55/push-ebp +30012 89/<- %ebp 4/r32/esp +30013 # var t/eax: (addr type-tree) = s->value->type +30014 8b/-> *(ebp+8) 0/r32/eax +30015 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +30016 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +30017 # TODO: check eax != 0 +30018 # TODO: check !t->is-atom? +30019 # TODO: check t->left == addr +30020 # t = t->right +30021 $addr-payload-size:skip-addr: +30022 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +30023 # TODO: check eax != 0 +30024 # if !t->is-atom? t = t->left +30025 81 7/subop/compare *eax 0/imm32/false +30026 { +30027 75/jump-if-!= break/disp8 +30028 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +30029 } +30030 # TODO: check t->is-atom? +30031 # return size(t->value) +30032 (size-of-type-id *(eax+4)) # Type-tree-value => eax +30033 $addr-payload-size:end: +30034 # . epilogue +30035 89/<- %esp 5/r32/ebp +30036 5d/pop-to-ebp +30037 c3/return +30038 +30039 translate-mu-populate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +30040 # . prologue +30041 55/push-ebp +30042 89/<- %ebp 4/r32/esp +30043 # . save registers +30044 50/push-eax +30045 51/push-ecx +30046 56/push-esi +30047 57/push-edi +30048 # esi = stmt +30049 8b/-> *(ebp+0xc) 6/r32/esi +30050 # var target/edi: (addr stmt-var) = stmt->inouts[0] +30051 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +30052 89/<- %edi 0/r32/eax +30053 # var len/ecx: (addr stmt-var) = stmt->inouts[1] +30054 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +30055 89/<- %ecx 0/r32/eax +30056 # +30057 (emit-indent *(ebp+8) *Curr-block-depth) +30058 (write-buffered *(ebp+8) "(allocate-array2 Heap ") +30059 (addr-handle-array-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +30060 (write-int32-hex-buffered *(ebp+8) %eax) +30061 (emit-subx-call-operand *(ebp+8) %ecx) +30062 (emit-subx-call-operand *(ebp+8) %edi) +30063 (write-buffered *(ebp+8) ")\n") +30064 $translate-mu-populate-stmt:end: +30065 # . restore registers +30066 5f/pop-to-edi +30067 5e/pop-to-esi +30068 59/pop-to-ecx +30069 58/pop-to-eax +30070 # . epilogue +30071 89/<- %esp 5/r32/ebp +30072 5d/pop-to-ebp +30073 c3/return +30074 +30075 translate-mu-populate-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +30076 # . prologue +30077 55/push-ebp +30078 89/<- %ebp 4/r32/esp +30079 # . save registers +30080 50/push-eax +30081 51/push-ecx +30082 56/push-esi +30083 57/push-edi +30084 # esi = stmt +30085 8b/-> *(ebp+0xc) 6/r32/esi +30086 # var target/edi: (addr stmt-var) = stmt->inouts[0] +30087 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +30088 89/<- %edi 0/r32/eax +30089 # var len/ecx: (addr stmt-var) = stmt->inouts[1] +30090 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +30091 89/<- %ecx 0/r32/eax +30092 # +30093 (emit-indent *(ebp+8) *Curr-block-depth) +30094 (write-buffered *(ebp+8) "(new-stream Heap ") +30095 (addr-handle-stream-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +30096 (write-int32-hex-buffered *(ebp+8) %eax) +30097 (emit-subx-call-operand *(ebp+8) %ecx) +30098 (emit-subx-call-operand *(ebp+8) %edi) +30099 (write-buffered *(ebp+8) ")\n") +30100 $translate-mu-populate-stream-stmt:end: +30101 # . restore registers +30102 5f/pop-to-edi +30103 5e/pop-to-esi +30104 59/pop-to-ecx +30105 58/pop-to-eax +30106 # . epilogue +30107 89/<- %esp 5/r32/ebp +30108 5d/pop-to-ebp +30109 c3/return +30110 +30111 translate-mu-read-from-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +30112 # . prologue +30113 55/push-ebp +30114 89/<- %ebp 4/r32/esp +30115 # . save registers +30116 50/push-eax +30117 51/push-ecx +30118 56/push-esi +30119 57/push-edi +30120 # esi = stmt +30121 8b/-> *(ebp+0xc) 6/r32/esi +30122 # var stream/ecx: (addr stmt-var) = stmt->inouts[0] +30123 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +30124 89/<- %ecx 0/r32/eax +30125 # var target/edi: (addr stmt-var) = stmt->inouts[1] +30126 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +30127 89/<- %edi 0/r32/eax +30128 # +30129 (emit-indent *(ebp+8) *Curr-block-depth) +30130 (write-buffered *(ebp+8) "(read-from-stream") +30131 (emit-subx-call-operand *(ebp+8) %ecx) +30132 (emit-subx-call-operand *(ebp+8) %edi) +30133 (write-buffered *(ebp+8) Space) +30134 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +30135 (write-int32-hex-buffered *(ebp+8) %eax) +30136 (write-buffered *(ebp+8) ")\n") +30137 $translate-mu-read-from-stream-stmt:end: +30138 # . restore registers +30139 5f/pop-to-edi +30140 5e/pop-to-esi +30141 59/pop-to-ecx +30142 58/pop-to-eax +30143 # . epilogue +30144 89/<- %esp 5/r32/ebp +30145 5d/pop-to-ebp +30146 c3/return +30147 +30148 translate-mu-write-to-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +30149 # . prologue +30150 55/push-ebp +30151 89/<- %ebp 4/r32/esp +30152 # . save registers +30153 50/push-eax +30154 51/push-ecx +30155 56/push-esi +30156 57/push-edi +30157 # esi = stmt +30158 8b/-> *(ebp+0xc) 6/r32/esi +30159 # var stream/ecx: (addr stmt-var) = stmt->inouts[0] +30160 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +30161 89/<- %ecx 0/r32/eax +30162 # var target/edi: (addr stmt-var) = stmt->inouts[1] +30163 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +30164 89/<- %edi 0/r32/eax +30165 # +30166 (emit-indent *(ebp+8) *Curr-block-depth) +30167 (write-buffered *(ebp+8) "(write-to-stream") +30168 (emit-subx-call-operand *(ebp+8) %ecx) +30169 (flush *(ebp+8)) +30170 (emit-subx-call-operand *(ebp+8) %edi) +30171 (flush *(ebp+8)) +30172 (write-buffered *(ebp+8) Space) +30173 (flush *(ebp+8)) +30174 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +30175 (write-int32-hex-buffered *(ebp+8) %eax) +30176 (write-buffered *(ebp+8) ")\n") +30177 $translate-mu-write-to-stream-stmt:end: +30178 # . restore registers +30179 5f/pop-to-edi +30180 5e/pop-to-esi +30181 59/pop-to-ecx +30182 58/pop-to-eax +30183 # . epilogue +30184 89/<- %esp 5/r32/ebp +30185 5d/pop-to-ebp +30186 c3/return +30187 +30188 addr-handle-array-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +30189 # . prologue +30190 55/push-ebp +30191 89/<- %ebp 4/r32/esp +30192 # var t/eax: (addr type-tree) = s->value->type +30193 8b/-> *(ebp+8) 0/r32/eax +30194 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +30195 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +30196 # TODO: check eax != 0 +30197 # TODO: check !t->is-atom? +30198 # TODO: check t->left == addr +30199 # t = t->right +30200 $addr-handle-array-payload-size:skip-addr: +30201 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +30202 # TODO: check eax != 0 +30203 # TODO: check !t->is-atom? +30204 # TODO: check t->left == handle +30205 # t = t->right +30206 $addr-handle-array-payload-size:skip-handle: +30207 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +30208 # TODO: check eax != 0 +30209 # TODO: check !t->is-atom? +30210 # TODO: check t->left == array +30211 # t = t->right +30212 $addr-handle-array-payload-size:skip-array: +30213 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +30214 # TODO: check eax != 0 +30215 # if !t->is-atom? t = t->left +30216 81 7/subop/compare *eax 0/imm32/false +30217 { +30218 75/jump-if-!= break/disp8 +30219 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +30220 } +30221 $addr-handle-array-payload-size:compute-size: +30222 # TODO: check t->is-atom? +30223 # return size(t->value) +30224 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax +30225 $addr-handle-array-payload-size:end: +30226 # . epilogue +30227 89/<- %esp 5/r32/ebp +30228 5d/pop-to-ebp +30229 c3/return +30230 +30231 addr-handle-stream-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +30232 # . prologue +30233 55/push-ebp +30234 89/<- %ebp 4/r32/esp +30235 # var t/eax: (addr type-tree) = s->value->type +30236 8b/-> *(ebp+8) 0/r32/eax +30237 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +30238 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +30239 # TODO: check eax != 0 +30240 # TODO: check !t->is-atom? +30241 # TODO: check t->left == addr +30242 # t = t->right +30243 $addr-handle-stream-payload-size:skip-addr: +30244 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +30245 # TODO: check eax != 0 +30246 # TODO: check !t->is-atom? +30247 # TODO: check t->left == handle +30248 # t = t->right +30249 $addr-handle-stream-payload-size:skip-handle: +30250 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +30251 # TODO: check eax != 0 +30252 # TODO: check !t->is-atom? +30253 # TODO: check t->left == stream +30254 # t = t->right +30255 $addr-handle-stream-payload-size:skip-stream: +30256 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +30257 # TODO: check eax != 0 +30258 # if !t->is-atom? t = t->left +30259 81 7/subop/compare *eax 0/imm32/false +30260 { +30261 75/jump-if-!= break/disp8 +30262 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +30263 } +30264 $addr-handle-stream-payload-size:compute-size: +30265 # TODO: check t->is-atom? +30266 # return size(t->value) +30267 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax +30268 $addr-handle-stream-payload-size:end: +30269 # . epilogue +30270 89/<- %esp 5/r32/ebp +30271 5d/pop-to-ebp +30272 c3/return +30273 +30274 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean +30275 # precondition: n is positive +30276 # . prologue +30277 55/push-ebp +30278 89/<- %ebp 4/r32/esp +30279 # eax = n +30280 8b/-> *(ebp+8) 0/r32/eax +30281 # if (n < 0) abort +30282 3d/compare-eax-with 0/imm32 +30283 0f 8c/jump-if-< $power-of-2?:abort/disp32 +30284 # var tmp/eax: int = n-1 +30285 48/decrement-eax +30286 # var tmp2/eax: int = n & tmp +30287 23/and-> *(ebp+8) 0/r32/eax +30288 # return (tmp2 == 0) +30289 3d/compare-eax-and 0/imm32 +30290 0f 94/set-byte-if-= %al +30291 25/and-eax-with 0xff/imm32 +30292 $power-of-2?:end: +30293 # . epilogue +30294 89/<- %esp 5/r32/ebp +30295 5d/pop-to-ebp +30296 c3/return +30297 +30298 $power-of-2?:abort: +30299 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n") +30300 (flush *(ebp+0xc)) +30301 (stop *(ebp+0x10) 1) +30302 # never gets here +30303 +30304 num-shift-rights: # n: int -> result/eax: int +30305 # precondition: n is a positive power of 2 +30306 # . prologue +30307 55/push-ebp +30308 89/<- %ebp 4/r32/esp +30309 # . save registers +30310 51/push-ecx +30311 # var curr/ecx: int = n +30312 8b/-> *(ebp+8) 1/r32/ecx +30313 # result = 0 +30314 b8/copy-to-eax 0/imm32 +30315 { +30316 # if (curr <= 1) break +30317 81 7/subop/compare %ecx 1/imm32 +30318 7e/jump-if-<= break/disp8 +30319 40/increment-eax +30320 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 +30321 eb/jump loop/disp8 +30322 } +30323 $num-shift-rights:end: +30324 # . restore registers +30325 59/pop-to-ecx +30326 # . epilogue +30327 89/<- %esp 5/r32/ebp +30328 5d/pop-to-ebp +30329 c3/return +30330 +30331 mu-get-offset: # stmt: (addr stmt) -> result/eax: int +30332 # . prologue +30333 55/push-ebp +30334 89/<- %ebp 4/r32/esp +30335 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next +30336 8b/-> *(ebp+8) 0/r32/eax +30337 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +30338 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +30339 # var output-var/eax: (addr var) = second-inout->value +30340 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +30341 #? (write-buffered Stderr "mu-get-offset: ") +30342 #? (write-int32-hex-buffered Stderr %eax) +30343 #? (write-buffered Stderr " name: ") +30344 #? 50/push-eax +30345 #? (lookup *eax *(eax+4)) # Var-name +30346 #? (write-buffered Stderr %eax) +30347 #? 58/pop-to-eax +30348 #? (write-buffered Stderr Newline) +30349 #? (flush Stderr) +30350 # return output-var->stack-offset +30351 8b/-> *(eax+0x14) 0/r32/eax # Var-offset +30352 #? (write-buffered Stderr "=> ") +30353 #? (write-int32-hex-buffered Stderr %eax) +30354 #? (write-buffered Stderr Newline) +30355 #? (flush Stderr) +30356 $emit-get-offset:end: +30357 # . epilogue +30358 89/<- %esp 5/r32/ebp +30359 5d/pop-to-ebp +30360 c3/return +30361 +30362 emit-subx-block: # out: (addr buffered-file), block: (addr block), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +30363 # . prologue +30364 55/push-ebp +30365 89/<- %ebp 4/r32/esp +30366 # . save registers +30367 50/push-eax +30368 51/push-ecx +30369 56/push-esi +30370 # esi = block +30371 8b/-> *(ebp+0xc) 6/r32/esi +30372 # block->var->block-depth = *Curr-block-depth +30373 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +30374 8b/-> *Curr-block-depth 1/r32/ecx +30375 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth +30376 # var stmts/eax: (addr list stmt) = lookup(block->statements) +30377 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +30378 # +30379 { +30380 $emit-subx-block:check-empty: +30381 3d/compare-eax-and 0/imm32 +30382 0f 84/jump-if-= break/disp32 +30383 (emit-indent *(ebp+8) *Curr-block-depth) +30384 (write-buffered *(ebp+8) "{\n") +30385 # var v/ecx: (addr var) = lookup(block->var) +30386 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +30387 89/<- %ecx 0/r32/eax +30388 # +30389 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +30390 (write-buffered *(ebp+8) %eax) +30391 (write-buffered *(ebp+8) ":loop:\n") +30392 ff 0/subop/increment *Curr-block-depth +30393 (push *(ebp+0x10) *(esi+0xc)) # Block-var +30394 (push *(ebp+0x10) *(esi+0x10)) # Block-var +30395 (push *(ebp+0x10) 0) # false +30396 # emit block->statements +30397 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +30398 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +30399 (pop *(ebp+0x10)) # => eax +30400 (pop *(ebp+0x10)) # => eax +30401 (pop *(ebp+0x10)) # => eax +30402 ff 1/subop/decrement *Curr-block-depth +30403 (emit-indent *(ebp+8) *Curr-block-depth) +30404 (write-buffered *(ebp+8) "}\n") +30405 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +30406 (write-buffered *(ebp+8) %eax) +30407 (write-buffered *(ebp+8) ":break:\n") +30408 } +30409 $emit-subx-block:end: +30410 # . restore registers +30411 5e/pop-to-esi +30412 59/pop-to-ecx +30413 58/pop-to-eax +30414 # . epilogue +30415 89/<- %esp 5/r32/ebp +30416 5d/pop-to-ebp +30417 c3/return +30418 +30419 # Primitives supported +30420 # See mu_instructions for a summary of this linked-list data structure. +30421 # +30422 # For each operation, put variants with hard-coded registers before flexible ones. +30423 # +30424 # Unfortunately, our restrictions on addresses require that various fields in +30425 # primitives be handles, which complicates these definitions. +30426 # - we need to insert dummy fields all over the place for fake alloc-ids +30427 # - we can't use our syntax sugar of quoted literals for string fields +30428 # +30429 # Fake alloc-ids are needed because our type definitions up top require +30430 # handles but it's clearer to statically allocate these long-lived objects. +30431 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. +30432 # +30433 # Every 'object' below starts with a fake alloc-id. It may also contain other +30434 # fake alloc-ids for various handle fields. +30435 # +30436 # I think of objects starting with a fake alloc-id as having type 'payload'. +30437 # It's not really intended to be created dynamically; for that use `allocate` +30438 # as usual. +30439 # +30440 # Idea for a notation to simplify such definitions: +30441 # _Primitive-increment-eax: # (payload primitive) +30442 # 0x11/alloc-id:fake:payload +30443 # 0x11 @(0x11 "increment") # name +30444 # 0 0 # inouts +30445 # 0x11 @(0x11/payload +30446 # 0x11 @(0x11/payload # List-value +30447 # 0 0 # Var-name +30448 # 0x11 @(0x11 # Var-type +30449 # 1/is-atom +30450 # 1/value 0/unused # Type-tree-left +30451 # 0 0 # Type-tree-right +30452 # ) +30453 # 1 # block-depth +30454 # 0 # stack-offset +30455 # 0x11 @(0x11 "eax") # Var-register +30456 # ) +30457 # 0 0) # List-next +30458 # ... +30459 # _Primitive-increment-ecx/imm32/next +30460 # ... +30461 # Awfully complex and non-obvious. But also clearly signals there's something +30462 # to learn here, so may be worth trying. +30463 # +30464 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " +30465 # +30466 # For now we'll continue to just use comments and manually ensure they stay up +30467 # to date. +30468 == data +30469 Primitives: # (addr primitive) +30470 # - increment/decrement +30471 _Primitive-increment-eax: # (addr primitive) +30472 # var/eax <- increment => 40/increment-eax +30473 0x11/imm32/alloc-id:fake +30474 _string-increment/imm32/name +30475 0/imm32/no-inouts 30476 0/imm32/no-inouts -30477 0/imm32/no-inouts -30478 0x11/imm32/alloc-id:fake -30479 Single-int-var-in-ecx/imm32/outputs -30480 0x11/imm32/alloc-id:fake -30481 _string_41_increment_ecx/imm32/subx-name -30482 0/imm32/no-rm32 -30483 0/imm32/no-r32 -30484 0/imm32/no-imm32 -30485 0/imm32/no-imm8 -30486 0/imm32/no-disp32 -30487 0/imm32/no-xm32 -30488 0/imm32/no-x32 -30489 0x11/imm32/alloc-id:fake -30490 _Primitive-increment-edx/imm32/next -30491 _Primitive-increment-edx: # (payload primitive) -30492 0x11/imm32/alloc-id:fake:payload -30493 # var/edx <- increment => 42/increment-edx -30494 0x11/imm32/alloc-id:fake -30495 _string-increment/imm32/name +30477 0x11/imm32/alloc-id:fake +30478 Single-int-var-in-eax/imm32/outputs +30479 0x11/imm32/alloc-id:fake +30480 _string_40_increment_eax/imm32/subx-name +30481 0/imm32/no-rm32 +30482 0/imm32/no-r32 +30483 0/imm32/no-imm32 +30484 0/imm32/no-imm8 +30485 0/imm32/no-disp32 +30486 0/imm32/no-xm32 +30487 0/imm32/no-x32 +30488 0x11/imm32/alloc-id:fake +30489 _Primitive-increment-ecx/imm32/next +30490 _Primitive-increment-ecx: # (payload primitive) +30491 0x11/imm32/alloc-id:fake:payload +30492 # var/ecx <- increment => 41/increment-ecx +30493 0x11/imm32/alloc-id:fake +30494 _string-increment/imm32/name +30495 0/imm32/no-inouts 30496 0/imm32/no-inouts -30497 0/imm32/no-inouts -30498 0x11/imm32/alloc-id:fake -30499 Single-int-var-in-edx/imm32/outputs -30500 0x11/imm32/alloc-id:fake -30501 _string_42_increment_edx/imm32/subx-name -30502 0/imm32/no-rm32 -30503 0/imm32/no-r32 -30504 0/imm32/no-imm32 -30505 0/imm32/no-imm8 -30506 0/imm32/no-disp32 -30507 0/imm32/no-xm32 -30508 0/imm32/no-x32 -30509 0x11/imm32/alloc-id:fake -30510 _Primitive-increment-ebx/imm32/next -30511 _Primitive-increment-ebx: # (payload primitive) -30512 0x11/imm32/alloc-id:fake:payload -30513 # var/ebx <- increment => 43/increment-ebx -30514 0x11/imm32/alloc-id:fake -30515 _string-increment/imm32/name +30497 0x11/imm32/alloc-id:fake +30498 Single-int-var-in-ecx/imm32/outputs +30499 0x11/imm32/alloc-id:fake +30500 _string_41_increment_ecx/imm32/subx-name +30501 0/imm32/no-rm32 +30502 0/imm32/no-r32 +30503 0/imm32/no-imm32 +30504 0/imm32/no-imm8 +30505 0/imm32/no-disp32 +30506 0/imm32/no-xm32 +30507 0/imm32/no-x32 +30508 0x11/imm32/alloc-id:fake +30509 _Primitive-increment-edx/imm32/next +30510 _Primitive-increment-edx: # (payload primitive) +30511 0x11/imm32/alloc-id:fake:payload +30512 # var/edx <- increment => 42/increment-edx +30513 0x11/imm32/alloc-id:fake +30514 _string-increment/imm32/name +30515 0/imm32/no-inouts 30516 0/imm32/no-inouts -30517 0/imm32/no-inouts -30518 0x11/imm32/alloc-id:fake -30519 Single-int-var-in-ebx/imm32/outputs -30520 0x11/imm32/alloc-id:fake -30521 _string_43_increment_ebx/imm32/subx-name -30522 0/imm32/no-rm32 -30523 0/imm32/no-r32 -30524 0/imm32/no-imm32 -30525 0/imm32/no-imm8 -30526 0/imm32/no-disp32 -30527 0/imm32/no-xm32 -30528 0/imm32/no-x32 -30529 0x11/imm32/alloc-id:fake -30530 _Primitive-increment-esi/imm32/next -30531 _Primitive-increment-esi: # (payload primitive) -30532 0x11/imm32/alloc-id:fake:payload -30533 # var/esi <- increment => 46/increment-esi -30534 0x11/imm32/alloc-id:fake -30535 _string-increment/imm32/name +30517 0x11/imm32/alloc-id:fake +30518 Single-int-var-in-edx/imm32/outputs +30519 0x11/imm32/alloc-id:fake +30520 _string_42_increment_edx/imm32/subx-name +30521 0/imm32/no-rm32 +30522 0/imm32/no-r32 +30523 0/imm32/no-imm32 +30524 0/imm32/no-imm8 +30525 0/imm32/no-disp32 +30526 0/imm32/no-xm32 +30527 0/imm32/no-x32 +30528 0x11/imm32/alloc-id:fake +30529 _Primitive-increment-ebx/imm32/next +30530 _Primitive-increment-ebx: # (payload primitive) +30531 0x11/imm32/alloc-id:fake:payload +30532 # var/ebx <- increment => 43/increment-ebx +30533 0x11/imm32/alloc-id:fake +30534 _string-increment/imm32/name +30535 0/imm32/no-inouts 30536 0/imm32/no-inouts -30537 0/imm32/no-inouts -30538 0x11/imm32/alloc-id:fake -30539 Single-int-var-in-esi/imm32/outputs -30540 0x11/imm32/alloc-id:fake -30541 _string_46_increment_esi/imm32/subx-name -30542 0/imm32/no-rm32 -30543 0/imm32/no-r32 -30544 0/imm32/no-imm32 -30545 0/imm32/no-imm8 -30546 0/imm32/no-disp32 -30547 0/imm32/no-xm32 -30548 0/imm32/no-x32 -30549 0x11/imm32/alloc-id:fake -30550 _Primitive-increment-edi/imm32/next -30551 _Primitive-increment-edi: # (payload primitive) -30552 0x11/imm32/alloc-id:fake:payload -30553 # var/edi <- increment => 47/increment-edi -30554 0x11/imm32/alloc-id:fake -30555 _string-increment/imm32/name +30537 0x11/imm32/alloc-id:fake +30538 Single-int-var-in-ebx/imm32/outputs +30539 0x11/imm32/alloc-id:fake +30540 _string_43_increment_ebx/imm32/subx-name +30541 0/imm32/no-rm32 +30542 0/imm32/no-r32 +30543 0/imm32/no-imm32 +30544 0/imm32/no-imm8 +30545 0/imm32/no-disp32 +30546 0/imm32/no-xm32 +30547 0/imm32/no-x32 +30548 0x11/imm32/alloc-id:fake +30549 _Primitive-increment-esi/imm32/next +30550 _Primitive-increment-esi: # (payload primitive) +30551 0x11/imm32/alloc-id:fake:payload +30552 # var/esi <- increment => 46/increment-esi +30553 0x11/imm32/alloc-id:fake +30554 _string-increment/imm32/name +30555 0/imm32/no-inouts 30556 0/imm32/no-inouts -30557 0/imm32/no-inouts -30558 0x11/imm32/alloc-id:fake -30559 Single-int-var-in-edi/imm32/outputs -30560 0x11/imm32/alloc-id:fake -30561 _string_47_increment_edi/imm32/subx-name -30562 0/imm32/no-rm32 -30563 0/imm32/no-r32 -30564 0/imm32/no-imm32 -30565 0/imm32/no-imm8 -30566 0/imm32/no-disp32 -30567 0/imm32/no-xm32 -30568 0/imm32/no-x32 -30569 0x11/imm32/alloc-id:fake -30570 _Primitive-decrement-eax/imm32/next -30571 _Primitive-decrement-eax: # (payload primitive) -30572 0x11/imm32/alloc-id:fake:payload -30573 # var/eax <- decrement => 48/decrement-eax -30574 0x11/imm32/alloc-id:fake -30575 _string-decrement/imm32/name +30557 0x11/imm32/alloc-id:fake +30558 Single-int-var-in-esi/imm32/outputs +30559 0x11/imm32/alloc-id:fake +30560 _string_46_increment_esi/imm32/subx-name +30561 0/imm32/no-rm32 +30562 0/imm32/no-r32 +30563 0/imm32/no-imm32 +30564 0/imm32/no-imm8 +30565 0/imm32/no-disp32 +30566 0/imm32/no-xm32 +30567 0/imm32/no-x32 +30568 0x11/imm32/alloc-id:fake +30569 _Primitive-increment-edi/imm32/next +30570 _Primitive-increment-edi: # (payload primitive) +30571 0x11/imm32/alloc-id:fake:payload +30572 # var/edi <- increment => 47/increment-edi +30573 0x11/imm32/alloc-id:fake +30574 _string-increment/imm32/name +30575 0/imm32/no-inouts 30576 0/imm32/no-inouts -30577 0/imm32/no-inouts -30578 0x11/imm32/alloc-id:fake -30579 Single-int-var-in-eax/imm32/outputs -30580 0x11/imm32/alloc-id:fake -30581 _string_48_decrement_eax/imm32/subx-name -30582 0/imm32/no-rm32 -30583 0/imm32/no-r32 -30584 0/imm32/no-imm32 -30585 0/imm32/no-imm8 -30586 0/imm32/no-disp32 -30587 0/imm32/no-xm32 -30588 0/imm32/no-x32 -30589 0x11/imm32/alloc-id:fake -30590 _Primitive-decrement-ecx/imm32/next -30591 _Primitive-decrement-ecx: # (payload primitive) -30592 0x11/imm32/alloc-id:fake:payload -30593 # var/ecx <- decrement => 49/decrement-ecx -30594 0x11/imm32/alloc-id:fake -30595 _string-decrement/imm32/name +30577 0x11/imm32/alloc-id:fake +30578 Single-int-var-in-edi/imm32/outputs +30579 0x11/imm32/alloc-id:fake +30580 _string_47_increment_edi/imm32/subx-name +30581 0/imm32/no-rm32 +30582 0/imm32/no-r32 +30583 0/imm32/no-imm32 +30584 0/imm32/no-imm8 +30585 0/imm32/no-disp32 +30586 0/imm32/no-xm32 +30587 0/imm32/no-x32 +30588 0x11/imm32/alloc-id:fake +30589 _Primitive-decrement-eax/imm32/next +30590 _Primitive-decrement-eax: # (payload primitive) +30591 0x11/imm32/alloc-id:fake:payload +30592 # var/eax <- decrement => 48/decrement-eax +30593 0x11/imm32/alloc-id:fake +30594 _string-decrement/imm32/name +30595 0/imm32/no-inouts 30596 0/imm32/no-inouts -30597 0/imm32/no-inouts -30598 0x11/imm32/alloc-id:fake -30599 Single-int-var-in-ecx/imm32/outputs -30600 0x11/imm32/alloc-id:fake -30601 _string_49_decrement_ecx/imm32/subx-name -30602 0/imm32/no-rm32 -30603 0/imm32/no-r32 -30604 0/imm32/no-imm32 -30605 0/imm32/no-imm8 -30606 0/imm32/no-disp32 -30607 0/imm32/no-xm32 -30608 0/imm32/no-x32 -30609 0x11/imm32/alloc-id:fake -30610 _Primitive-decrement-edx/imm32/next -30611 _Primitive-decrement-edx: # (payload primitive) -30612 0x11/imm32/alloc-id:fake:payload -30613 # var/edx <- decrement => 4a/decrement-edx -30614 0x11/imm32/alloc-id:fake -30615 _string-decrement/imm32/name +30597 0x11/imm32/alloc-id:fake +30598 Single-int-var-in-eax/imm32/outputs +30599 0x11/imm32/alloc-id:fake +30600 _string_48_decrement_eax/imm32/subx-name +30601 0/imm32/no-rm32 +30602 0/imm32/no-r32 +30603 0/imm32/no-imm32 +30604 0/imm32/no-imm8 +30605 0/imm32/no-disp32 +30606 0/imm32/no-xm32 +30607 0/imm32/no-x32 +30608 0x11/imm32/alloc-id:fake +30609 _Primitive-decrement-ecx/imm32/next +30610 _Primitive-decrement-ecx: # (payload primitive) +30611 0x11/imm32/alloc-id:fake:payload +30612 # var/ecx <- decrement => 49/decrement-ecx +30613 0x11/imm32/alloc-id:fake +30614 _string-decrement/imm32/name +30615 0/imm32/no-inouts 30616 0/imm32/no-inouts -30617 0/imm32/no-inouts -30618 0x11/imm32/alloc-id:fake -30619 Single-int-var-in-edx/imm32/outputs -30620 0x11/imm32/alloc-id:fake -30621 _string_4a_decrement_edx/imm32/subx-name -30622 0/imm32/no-rm32 -30623 0/imm32/no-r32 -30624 0/imm32/no-imm32 -30625 0/imm32/no-imm8 -30626 0/imm32/no-disp32 -30627 0/imm32/no-xm32 -30628 0/imm32/no-x32 -30629 0x11/imm32/alloc-id:fake -30630 _Primitive-decrement-ebx/imm32/next -30631 _Primitive-decrement-ebx: # (payload primitive) -30632 0x11/imm32/alloc-id:fake:payload -30633 # var/ebx <- decrement => 4b/decrement-ebx -30634 0x11/imm32/alloc-id:fake -30635 _string-decrement/imm32/name +30617 0x11/imm32/alloc-id:fake +30618 Single-int-var-in-ecx/imm32/outputs +30619 0x11/imm32/alloc-id:fake +30620 _string_49_decrement_ecx/imm32/subx-name +30621 0/imm32/no-rm32 +30622 0/imm32/no-r32 +30623 0/imm32/no-imm32 +30624 0/imm32/no-imm8 +30625 0/imm32/no-disp32 +30626 0/imm32/no-xm32 +30627 0/imm32/no-x32 +30628 0x11/imm32/alloc-id:fake +30629 _Primitive-decrement-edx/imm32/next +30630 _Primitive-decrement-edx: # (payload primitive) +30631 0x11/imm32/alloc-id:fake:payload +30632 # var/edx <- decrement => 4a/decrement-edx +30633 0x11/imm32/alloc-id:fake +30634 _string-decrement/imm32/name +30635 0/imm32/no-inouts 30636 0/imm32/no-inouts -30637 0/imm32/no-inouts -30638 0x11/imm32/alloc-id:fake -30639 Single-int-var-in-ebx/imm32/outputs -30640 0x11/imm32/alloc-id:fake -30641 _string_4b_decrement_ebx/imm32/subx-name -30642 0/imm32/no-rm32 -30643 0/imm32/no-r32 -30644 0/imm32/no-imm32 -30645 0/imm32/no-imm8 -30646 0/imm32/no-disp32 -30647 0/imm32/no-xm32 -30648 0/imm32/no-x32 -30649 0x11/imm32/alloc-id:fake -30650 _Primitive-decrement-esi/imm32/next -30651 _Primitive-decrement-esi: # (payload primitive) -30652 0x11/imm32/alloc-id:fake:payload -30653 # var/esi <- decrement => 4e/decrement-esi -30654 0x11/imm32/alloc-id:fake -30655 _string-decrement/imm32/name +30637 0x11/imm32/alloc-id:fake +30638 Single-int-var-in-edx/imm32/outputs +30639 0x11/imm32/alloc-id:fake +30640 _string_4a_decrement_edx/imm32/subx-name +30641 0/imm32/no-rm32 +30642 0/imm32/no-r32 +30643 0/imm32/no-imm32 +30644 0/imm32/no-imm8 +30645 0/imm32/no-disp32 +30646 0/imm32/no-xm32 +30647 0/imm32/no-x32 +30648 0x11/imm32/alloc-id:fake +30649 _Primitive-decrement-ebx/imm32/next +30650 _Primitive-decrement-ebx: # (payload primitive) +30651 0x11/imm32/alloc-id:fake:payload +30652 # var/ebx <- decrement => 4b/decrement-ebx +30653 0x11/imm32/alloc-id:fake +30654 _string-decrement/imm32/name +30655 0/imm32/no-inouts 30656 0/imm32/no-inouts -30657 0/imm32/no-inouts -30658 0x11/imm32/alloc-id:fake -30659 Single-int-var-in-esi/imm32/outputs -30660 0x11/imm32/alloc-id:fake -30661 _string_4e_decrement_esi/imm32/subx-name -30662 0/imm32/no-rm32 -30663 0/imm32/no-r32 -30664 0/imm32/no-imm32 -30665 0/imm32/no-imm8 -30666 0/imm32/no-disp32 -30667 0/imm32/no-xm32 -30668 0/imm32/no-x32 -30669 0x11/imm32/alloc-id:fake -30670 _Primitive-decrement-edi/imm32/next -30671 _Primitive-decrement-edi: # (payload primitive) -30672 0x11/imm32/alloc-id:fake:payload -30673 # var/edi <- decrement => 4f/decrement-edi -30674 0x11/imm32/alloc-id:fake -30675 _string-decrement/imm32/name +30657 0x11/imm32/alloc-id:fake +30658 Single-int-var-in-ebx/imm32/outputs +30659 0x11/imm32/alloc-id:fake +30660 _string_4b_decrement_ebx/imm32/subx-name +30661 0/imm32/no-rm32 +30662 0/imm32/no-r32 +30663 0/imm32/no-imm32 +30664 0/imm32/no-imm8 +30665 0/imm32/no-disp32 +30666 0/imm32/no-xm32 +30667 0/imm32/no-x32 +30668 0x11/imm32/alloc-id:fake +30669 _Primitive-decrement-esi/imm32/next +30670 _Primitive-decrement-esi: # (payload primitive) +30671 0x11/imm32/alloc-id:fake:payload +30672 # var/esi <- decrement => 4e/decrement-esi +30673 0x11/imm32/alloc-id:fake +30674 _string-decrement/imm32/name +30675 0/imm32/no-inouts 30676 0/imm32/no-inouts -30677 0/imm32/no-inouts -30678 0x11/imm32/alloc-id:fake -30679 Single-int-var-in-edi/imm32/outputs -30680 0x11/imm32/alloc-id:fake -30681 _string_4f_decrement_edi/imm32/subx-name -30682 0/imm32/no-rm32 -30683 0/imm32/no-r32 -30684 0/imm32/no-imm32 -30685 0/imm32/no-imm8 -30686 0/imm32/no-disp32 -30687 0/imm32/no-xm32 -30688 0/imm32/no-x32 -30689 0x11/imm32/alloc-id:fake -30690 _Primitive-increment-mem/imm32/next -30691 _Primitive-increment-mem: # (payload primitive) -30692 0x11/imm32/alloc-id:fake:payload -30693 # increment var => ff 0/subop/increment *(ebp+__) -30694 0x11/imm32/alloc-id:fake -30695 _string-increment/imm32/name -30696 0x11/imm32/alloc-id:fake -30697 Single-int-var-in-mem/imm32/inouts -30698 0/imm32/no-outputs -30699 0/imm32/no-outputs -30700 0x11/imm32/alloc-id:fake -30701 _string_ff_subop_increment/imm32/subx-name -30702 1/imm32/rm32-is-first-inout -30703 0/imm32/no-r32 -30704 0/imm32/no-imm32 -30705 0/imm32/no-imm8 -30706 0/imm32/no-disp32 -30707 0/imm32/no-xm32 -30708 0/imm32/no-x32 -30709 0x11/imm32/alloc-id:fake -30710 _Primitive-increment-reg/imm32/next -30711 _Primitive-increment-reg: # (payload primitive) -30712 0x11/imm32/alloc-id:fake:payload -30713 # var/reg <- increment => ff 0/subop/increment %__ -30714 0x11/imm32/alloc-id:fake -30715 _string-increment/imm32/name -30716 0/imm32/no-inouts -30717 0/imm32/no-inouts -30718 0x11/imm32/alloc-id:fake -30719 Single-int-var-in-some-register/imm32/outputs -30720 0x11/imm32/alloc-id:fake -30721 _string_ff_subop_increment/imm32/subx-name -30722 3/imm32/rm32-is-first-output -30723 0/imm32/no-r32 -30724 0/imm32/no-imm32 -30725 0/imm32/no-imm8 -30726 0/imm32/no-disp32 -30727 0/imm32/no-xm32 -30728 0/imm32/no-x32 -30729 0x11/imm32/alloc-id:fake -30730 _Primitive-decrement-mem/imm32/next -30731 _Primitive-decrement-mem: # (payload primitive) -30732 0x11/imm32/alloc-id:fake:payload -30733 # decrement var => ff 1/subop/decrement *(ebp+__) -30734 0x11/imm32/alloc-id:fake -30735 _string-decrement/imm32/name -30736 0x11/imm32/alloc-id:fake -30737 Single-int-var-in-mem/imm32/inouts -30738 0/imm32/no-outputs -30739 0/imm32/no-outputs -30740 0x11/imm32/alloc-id:fake -30741 _string_ff_subop_decrement/imm32/subx-name -30742 1/imm32/rm32-is-first-inout -30743 0/imm32/no-r32 -30744 0/imm32/no-imm32 -30745 0/imm32/no-imm8 -30746 0/imm32/no-disp32 -30747 0/imm32/no-xm32 -30748 0/imm32/no-x32 -30749 0x11/imm32/alloc-id:fake -30750 _Primitive-decrement-reg/imm32/next -30751 _Primitive-decrement-reg: # (payload primitive) -30752 0x11/imm32/alloc-id:fake:payload -30753 # var/reg <- decrement => ff 1/subop/decrement %__ -30754 0x11/imm32/alloc-id:fake -30755 _string-decrement/imm32/name -30756 0/imm32/no-inouts -30757 0/imm32/no-inouts -30758 0x11/imm32/alloc-id:fake -30759 Single-int-var-in-some-register/imm32/outputs -30760 0x11/imm32/alloc-id:fake -30761 _string_ff_subop_decrement/imm32/subx-name -30762 3/imm32/rm32-is-first-output -30763 0/imm32/no-r32 -30764 0/imm32/no-imm32 -30765 0/imm32/no-imm8 -30766 0/imm32/no-disp32 -30767 0/imm32/no-xm32 -30768 0/imm32/no-x32 -30769 0x11/imm32/alloc-id:fake -30770 _Primitive-add-to-eax/imm32/next -30771 # - add -30772 _Primitive-add-to-eax: # (payload primitive) -30773 0x11/imm32/alloc-id:fake:payload -30774 # var/eax <- add lit => 05/add-to-eax lit/imm32 -30775 0x11/imm32/alloc-id:fake -30776 _string-add/imm32/name +30677 0x11/imm32/alloc-id:fake +30678 Single-int-var-in-esi/imm32/outputs +30679 0x11/imm32/alloc-id:fake +30680 _string_4e_decrement_esi/imm32/subx-name +30681 0/imm32/no-rm32 +30682 0/imm32/no-r32 +30683 0/imm32/no-imm32 +30684 0/imm32/no-imm8 +30685 0/imm32/no-disp32 +30686 0/imm32/no-xm32 +30687 0/imm32/no-x32 +30688 0x11/imm32/alloc-id:fake +30689 _Primitive-decrement-edi/imm32/next +30690 _Primitive-decrement-edi: # (payload primitive) +30691 0x11/imm32/alloc-id:fake:payload +30692 # var/edi <- decrement => 4f/decrement-edi +30693 0x11/imm32/alloc-id:fake +30694 _string-decrement/imm32/name +30695 0/imm32/no-inouts +30696 0/imm32/no-inouts +30697 0x11/imm32/alloc-id:fake +30698 Single-int-var-in-edi/imm32/outputs +30699 0x11/imm32/alloc-id:fake +30700 _string_4f_decrement_edi/imm32/subx-name +30701 0/imm32/no-rm32 +30702 0/imm32/no-r32 +30703 0/imm32/no-imm32 +30704 0/imm32/no-imm8 +30705 0/imm32/no-disp32 +30706 0/imm32/no-xm32 +30707 0/imm32/no-x32 +30708 0x11/imm32/alloc-id:fake +30709 _Primitive-increment-mem/imm32/next +30710 _Primitive-increment-mem: # (payload primitive) +30711 0x11/imm32/alloc-id:fake:payload +30712 # increment var => ff 0/subop/increment *(ebp+__) +30713 0x11/imm32/alloc-id:fake +30714 _string-increment/imm32/name +30715 0x11/imm32/alloc-id:fake +30716 Single-int-var-in-mem/imm32/inouts +30717 0/imm32/no-outputs +30718 0/imm32/no-outputs +30719 0x11/imm32/alloc-id:fake +30720 _string_ff_subop_increment/imm32/subx-name +30721 1/imm32/rm32-is-first-inout +30722 0/imm32/no-r32 +30723 0/imm32/no-imm32 +30724 0/imm32/no-imm8 +30725 0/imm32/no-disp32 +30726 0/imm32/no-xm32 +30727 0/imm32/no-x32 +30728 0x11/imm32/alloc-id:fake +30729 _Primitive-increment-reg/imm32/next +30730 _Primitive-increment-reg: # (payload primitive) +30731 0x11/imm32/alloc-id:fake:payload +30732 # var/reg <- increment => ff 0/subop/increment %__ +30733 0x11/imm32/alloc-id:fake +30734 _string-increment/imm32/name +30735 0/imm32/no-inouts +30736 0/imm32/no-inouts +30737 0x11/imm32/alloc-id:fake +30738 Single-int-var-in-some-register/imm32/outputs +30739 0x11/imm32/alloc-id:fake +30740 _string_ff_subop_increment/imm32/subx-name +30741 3/imm32/rm32-is-first-output +30742 0/imm32/no-r32 +30743 0/imm32/no-imm32 +30744 0/imm32/no-imm8 +30745 0/imm32/no-disp32 +30746 0/imm32/no-xm32 +30747 0/imm32/no-x32 +30748 0x11/imm32/alloc-id:fake +30749 _Primitive-decrement-mem/imm32/next +30750 _Primitive-decrement-mem: # (payload primitive) +30751 0x11/imm32/alloc-id:fake:payload +30752 # decrement var => ff 1/subop/decrement *(ebp+__) +30753 0x11/imm32/alloc-id:fake +30754 _string-decrement/imm32/name +30755 0x11/imm32/alloc-id:fake +30756 Single-int-var-in-mem/imm32/inouts +30757 0/imm32/no-outputs +30758 0/imm32/no-outputs +30759 0x11/imm32/alloc-id:fake +30760 _string_ff_subop_decrement/imm32/subx-name +30761 1/imm32/rm32-is-first-inout +30762 0/imm32/no-r32 +30763 0/imm32/no-imm32 +30764 0/imm32/no-imm8 +30765 0/imm32/no-disp32 +30766 0/imm32/no-xm32 +30767 0/imm32/no-x32 +30768 0x11/imm32/alloc-id:fake +30769 _Primitive-decrement-reg/imm32/next +30770 _Primitive-decrement-reg: # (payload primitive) +30771 0x11/imm32/alloc-id:fake:payload +30772 # var/reg <- decrement => ff 1/subop/decrement %__ +30773 0x11/imm32/alloc-id:fake +30774 _string-decrement/imm32/name +30775 0/imm32/no-inouts +30776 0/imm32/no-inouts 30777 0x11/imm32/alloc-id:fake -30778 Single-lit-var/imm32/inouts +30778 Single-int-var-in-some-register/imm32/outputs 30779 0x11/imm32/alloc-id:fake -30780 Single-int-var-in-eax/imm32/outputs -30781 0x11/imm32/alloc-id:fake -30782 _string_05_add_to_eax/imm32/subx-name -30783 0/imm32/no-rm32 -30784 0/imm32/no-r32 -30785 1/imm32/imm32-is-first-inout -30786 0/imm32/no-imm8 -30787 0/imm32/no-disp32 -30788 0/imm32/no-xm32 -30789 0/imm32/no-x32 -30790 0x11/imm32/alloc-id:fake -30791 _Primitive-add-reg-to-reg/imm32/next -30792 _Primitive-add-reg-to-reg: # (payload primitive) -30793 0x11/imm32/alloc-id:fake:payload -30794 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 -30795 0x11/imm32/alloc-id:fake -30796 _string-add/imm32/name -30797 0x11/imm32/alloc-id:fake -30798 Single-int-var-in-some-register/imm32/inouts -30799 0x11/imm32/alloc-id:fake -30800 Single-int-var-in-some-register/imm32/outputs -30801 0x11/imm32/alloc-id:fake -30802 _string_01_add_to/imm32/subx-name -30803 3/imm32/rm32-is-first-output -30804 1/imm32/r32-is-first-inout -30805 0/imm32/no-imm32 -30806 0/imm32/no-imm8 -30807 0/imm32/no-disp32 -30808 0/imm32/no-xm32 -30809 0/imm32/no-x32 -30810 0x11/imm32/alloc-id:fake -30811 _Primitive-add-reg-to-mem/imm32/next -30812 _Primitive-add-reg-to-mem: # (payload primitive) -30813 0x11/imm32/alloc-id:fake:payload -30814 # add-to var1 var2/reg => 01/add-to var1 var2/r32 -30815 0x11/imm32/alloc-id:fake -30816 _string-add-to/imm32/name -30817 0x11/imm32/alloc-id:fake -30818 Two-args-int-stack-int-reg/imm32/inouts -30819 0/imm32/no-outputs -30820 0/imm32/no-outputs -30821 0x11/imm32/alloc-id:fake -30822 _string_01_add_to/imm32/subx-name -30823 1/imm32/rm32-is-first-inout -30824 2/imm32/r32-is-second-inout -30825 0/imm32/no-imm32 -30826 0/imm32/no-imm8 -30827 0/imm32/no-disp32 -30828 0/imm32/no-xm32 -30829 0/imm32/no-x32 -30830 0x11/imm32/alloc-id:fake -30831 _Primitive-add-mem-to-reg/imm32/next -30832 _Primitive-add-mem-to-reg: # (payload primitive) -30833 0x11/imm32/alloc-id:fake:payload -30834 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 -30835 0x11/imm32/alloc-id:fake -30836 _string-add/imm32/name -30837 0x11/imm32/alloc-id:fake -30838 Single-int-var-in-mem/imm32/inouts -30839 0x11/imm32/alloc-id:fake -30840 Single-int-var-in-some-register/imm32/outputs -30841 0x11/imm32/alloc-id:fake -30842 _string_03_add/imm32/subx-name -30843 1/imm32/rm32-is-first-inout -30844 3/imm32/r32-is-first-output -30845 0/imm32/no-imm32 -30846 0/imm32/no-imm8 -30847 0/imm32/no-disp32 -30848 0/imm32/no-xm32 -30849 0/imm32/no-x32 -30850 0x11/imm32/alloc-id:fake -30851 _Primitive-add-lit-to-reg/imm32/next -30852 _Primitive-add-lit-to-reg: # (payload primitive) -30853 0x11/imm32/alloc-id:fake:payload -30854 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 -30855 0x11/imm32/alloc-id:fake -30856 _string-add/imm32/name -30857 0x11/imm32/alloc-id:fake -30858 Single-lit-var/imm32/inouts -30859 0x11/imm32/alloc-id:fake -30860 Single-int-var-in-some-register/imm32/outputs -30861 0x11/imm32/alloc-id:fake -30862 _string_81_subop_add/imm32/subx-name -30863 3/imm32/rm32-is-first-output -30864 0/imm32/no-r32 -30865 1/imm32/imm32-is-first-inout -30866 0/imm32/no-imm8 -30867 0/imm32/no-disp32 -30868 0/imm32/no-xm32 -30869 0/imm32/no-x32 -30870 0x11/imm32/alloc-id:fake -30871 _Primitive-add-lit-to-mem/imm32/next -30872 _Primitive-add-lit-to-mem: # (payload primitive) -30873 0x11/imm32/alloc-id:fake:payload -30874 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 -30875 0x11/imm32/alloc-id:fake -30876 _string-add-to/imm32/name -30877 0x11/imm32/alloc-id:fake -30878 Int-var-and-literal/imm32/inouts -30879 0/imm32/no-outputs -30880 0/imm32/no-outputs -30881 0x11/imm32/alloc-id:fake -30882 _string_81_subop_add/imm32/subx-name -30883 1/imm32/rm32-is-first-inout -30884 0/imm32/no-r32 -30885 2/imm32/imm32-is-second-inout -30886 0/imm32/no-imm8 -30887 0/imm32/no-disp32 -30888 0/imm32/no-xm32 -30889 0/imm32/no-x32 -30890 0x11/imm32/alloc-id:fake -30891 _Primitive-subtract-from-eax/imm32/next -30892 # - subtract -30893 _Primitive-subtract-from-eax: # (payload primitive) -30894 0x11/imm32/alloc-id:fake:payload -30895 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 +30780 _string_ff_subop_decrement/imm32/subx-name +30781 3/imm32/rm32-is-first-output +30782 0/imm32/no-r32 +30783 0/imm32/no-imm32 +30784 0/imm32/no-imm8 +30785 0/imm32/no-disp32 +30786 0/imm32/no-xm32 +30787 0/imm32/no-x32 +30788 0x11/imm32/alloc-id:fake +30789 _Primitive-add-to-eax/imm32/next +30790 # - add +30791 _Primitive-add-to-eax: # (payload primitive) +30792 0x11/imm32/alloc-id:fake:payload +30793 # var/eax <- add lit => 05/add-to-eax lit/imm32 +30794 0x11/imm32/alloc-id:fake +30795 _string-add/imm32/name +30796 0x11/imm32/alloc-id:fake +30797 Single-lit-var/imm32/inouts +30798 0x11/imm32/alloc-id:fake +30799 Single-int-var-in-eax/imm32/outputs +30800 0x11/imm32/alloc-id:fake +30801 _string_05_add_to_eax/imm32/subx-name +30802 0/imm32/no-rm32 +30803 0/imm32/no-r32 +30804 1/imm32/imm32-is-first-inout +30805 0/imm32/no-imm8 +30806 0/imm32/no-disp32 +30807 0/imm32/no-xm32 +30808 0/imm32/no-x32 +30809 0x11/imm32/alloc-id:fake +30810 _Primitive-add-reg-to-reg/imm32/next +30811 _Primitive-add-reg-to-reg: # (payload primitive) +30812 0x11/imm32/alloc-id:fake:payload +30813 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 +30814 0x11/imm32/alloc-id:fake +30815 _string-add/imm32/name +30816 0x11/imm32/alloc-id:fake +30817 Single-int-var-in-some-register/imm32/inouts +30818 0x11/imm32/alloc-id:fake +30819 Single-int-var-in-some-register/imm32/outputs +30820 0x11/imm32/alloc-id:fake +30821 _string_01_add_to/imm32/subx-name +30822 3/imm32/rm32-is-first-output +30823 1/imm32/r32-is-first-inout +30824 0/imm32/no-imm32 +30825 0/imm32/no-imm8 +30826 0/imm32/no-disp32 +30827 0/imm32/no-xm32 +30828 0/imm32/no-x32 +30829 0x11/imm32/alloc-id:fake +30830 _Primitive-add-reg-to-mem/imm32/next +30831 _Primitive-add-reg-to-mem: # (payload primitive) +30832 0x11/imm32/alloc-id:fake:payload +30833 # add-to var1 var2/reg => 01/add-to var1 var2/r32 +30834 0x11/imm32/alloc-id:fake +30835 _string-add-to/imm32/name +30836 0x11/imm32/alloc-id:fake +30837 Two-args-int-stack-int-reg/imm32/inouts +30838 0/imm32/no-outputs +30839 0/imm32/no-outputs +30840 0x11/imm32/alloc-id:fake +30841 _string_01_add_to/imm32/subx-name +30842 1/imm32/rm32-is-first-inout +30843 2/imm32/r32-is-second-inout +30844 0/imm32/no-imm32 +30845 0/imm32/no-imm8 +30846 0/imm32/no-disp32 +30847 0/imm32/no-xm32 +30848 0/imm32/no-x32 +30849 0x11/imm32/alloc-id:fake +30850 _Primitive-add-mem-to-reg/imm32/next +30851 _Primitive-add-mem-to-reg: # (payload primitive) +30852 0x11/imm32/alloc-id:fake:payload +30853 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 +30854 0x11/imm32/alloc-id:fake +30855 _string-add/imm32/name +30856 0x11/imm32/alloc-id:fake +30857 Single-int-var-in-mem/imm32/inouts +30858 0x11/imm32/alloc-id:fake +30859 Single-int-var-in-some-register/imm32/outputs +30860 0x11/imm32/alloc-id:fake +30861 _string_03_add/imm32/subx-name +30862 1/imm32/rm32-is-first-inout +30863 3/imm32/r32-is-first-output +30864 0/imm32/no-imm32 +30865 0/imm32/no-imm8 +30866 0/imm32/no-disp32 +30867 0/imm32/no-xm32 +30868 0/imm32/no-x32 +30869 0x11/imm32/alloc-id:fake +30870 _Primitive-add-lit-to-reg/imm32/next +30871 _Primitive-add-lit-to-reg: # (payload primitive) +30872 0x11/imm32/alloc-id:fake:payload +30873 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 +30874 0x11/imm32/alloc-id:fake +30875 _string-add/imm32/name +30876 0x11/imm32/alloc-id:fake +30877 Single-lit-var/imm32/inouts +30878 0x11/imm32/alloc-id:fake +30879 Single-int-var-in-some-register/imm32/outputs +30880 0x11/imm32/alloc-id:fake +30881 _string_81_subop_add/imm32/subx-name +30882 3/imm32/rm32-is-first-output +30883 0/imm32/no-r32 +30884 1/imm32/imm32-is-first-inout +30885 0/imm32/no-imm8 +30886 0/imm32/no-disp32 +30887 0/imm32/no-xm32 +30888 0/imm32/no-x32 +30889 0x11/imm32/alloc-id:fake +30890 _Primitive-add-lit-to-mem/imm32/next +30891 _Primitive-add-lit-to-mem: # (payload primitive) +30892 0x11/imm32/alloc-id:fake:payload +30893 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 +30894 0x11/imm32/alloc-id:fake +30895 _string-add-to/imm32/name 30896 0x11/imm32/alloc-id:fake -30897 _string-subtract/imm32/name -30898 0x11/imm32/alloc-id:fake -30899 Single-lit-var/imm32/inouts +30897 Int-var-and-literal/imm32/inouts +30898 0/imm32/no-outputs +30899 0/imm32/no-outputs 30900 0x11/imm32/alloc-id:fake -30901 Single-int-var-in-eax/imm32/outputs -30902 0x11/imm32/alloc-id:fake -30903 _string_2d_subtract_from_eax/imm32/subx-name -30904 0/imm32/no-rm32 -30905 0/imm32/no-r32 -30906 1/imm32/imm32-is-first-inout -30907 0/imm32/no-imm8 -30908 0/imm32/no-disp32 -30909 0/imm32/no-xm32 -30910 0/imm32/no-x32 -30911 0x11/imm32/alloc-id:fake -30912 _Primitive-subtract-reg-from-reg/imm32/next -30913 _Primitive-subtract-reg-from-reg: # (payload primitive) -30914 0x11/imm32/alloc-id:fake:payload -30915 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 -30916 0x11/imm32/alloc-id:fake -30917 _string-subtract/imm32/name -30918 0x11/imm32/alloc-id:fake -30919 Single-int-var-in-some-register/imm32/inouts -30920 0x11/imm32/alloc-id:fake -30921 Single-int-var-in-some-register/imm32/outputs -30922 0x11/imm32/alloc-id:fake -30923 _string_29_subtract_from/imm32/subx-name -30924 3/imm32/rm32-is-first-output -30925 1/imm32/r32-is-first-inout -30926 0/imm32/no-imm32 -30927 0/imm32/no-imm8 -30928 0/imm32/no-disp32 -30929 0/imm32/no-xm32 -30930 0/imm32/no-x32 -30931 0x11/imm32/alloc-id:fake -30932 _Primitive-subtract-reg-from-mem/imm32/next -30933 _Primitive-subtract-reg-from-mem: # (payload primitive) -30934 0x11/imm32/alloc-id:fake:payload -30935 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 -30936 0x11/imm32/alloc-id:fake -30937 _string-subtract-from/imm32/name -30938 0x11/imm32/alloc-id:fake -30939 Two-args-int-stack-int-reg/imm32/inouts -30940 0/imm32/no-outputs -30941 0/imm32/no-outputs -30942 0x11/imm32/alloc-id:fake -30943 _string_29_subtract_from/imm32/subx-name -30944 1/imm32/rm32-is-first-inout -30945 2/imm32/r32-is-second-inout -30946 0/imm32/no-imm32 -30947 0/imm32/no-imm8 -30948 0/imm32/no-disp32 -30949 0/imm32/no-xm32 -30950 0/imm32/no-x32 -30951 0x11/imm32/alloc-id:fake -30952 _Primitive-subtract-mem-from-reg/imm32/next -30953 _Primitive-subtract-mem-from-reg: # (payload primitive) -30954 0x11/imm32/alloc-id:fake:payload -30955 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 -30956 0x11/imm32/alloc-id:fake -30957 _string-subtract/imm32/name -30958 0x11/imm32/alloc-id:fake -30959 Single-int-var-in-mem/imm32/inouts -30960 0x11/imm32/alloc-id:fake -30961 Single-int-var-in-some-register/imm32/outputs -30962 0x11/imm32/alloc-id:fake -30963 _string_2b_subtract/imm32/subx-name -30964 1/imm32/rm32-is-first-inout -30965 3/imm32/r32-is-first-output -30966 0/imm32/no-imm32 -30967 0/imm32/no-imm8 -30968 0/imm32/no-disp32 -30969 0/imm32/no-xm32 -30970 0/imm32/no-x32 -30971 0x11/imm32/alloc-id:fake -30972 _Primitive-subtract-lit-from-reg/imm32/next -30973 _Primitive-subtract-lit-from-reg: # (payload primitive) -30974 0x11/imm32/alloc-id:fake:payload -30975 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 -30976 0x11/imm32/alloc-id:fake -30977 _string-subtract/imm32/name -30978 0x11/imm32/alloc-id:fake -30979 Single-lit-var/imm32/inouts -30980 0x11/imm32/alloc-id:fake -30981 Single-int-var-in-some-register/imm32/outputs -30982 0x11/imm32/alloc-id:fake -30983 _string_81_subop_subtract/imm32/subx-name -30984 3/imm32/rm32-is-first-output -30985 0/imm32/no-r32 -30986 1/imm32/imm32-is-first-inout -30987 0/imm32/no-imm8 -30988 0/imm32/no-disp32 -30989 0/imm32/no-xm32 -30990 0/imm32/no-x32 -30991 0x11/imm32/alloc-id:fake -30992 _Primitive-subtract-lit-from-mem/imm32/next -30993 _Primitive-subtract-lit-from-mem: # (payload primitive) -30994 0x11/imm32/alloc-id:fake:payload -30995 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 -30996 0x11/imm32/alloc-id:fake -30997 _string-subtract-from/imm32/name -30998 0x11/imm32/alloc-id:fake -30999 Int-var-and-literal/imm32/inouts -31000 0/imm32/no-outputs -31001 0/imm32/no-outputs -31002 0x11/imm32/alloc-id:fake -31003 _string_81_subop_subtract/imm32/subx-name -31004 1/imm32/rm32-is-first-inout -31005 0/imm32/no-r32 -31006 2/imm32/imm32-is-second-inout -31007 0/imm32/no-imm8 -31008 0/imm32/no-disp32 -31009 0/imm32/no-xm32 -31010 0/imm32/no-x32 -31011 0x11/imm32/alloc-id:fake -31012 _Primitive-and-with-eax/imm32/next -31013 # - and -31014 _Primitive-and-with-eax: # (payload primitive) -31015 0x11/imm32/alloc-id:fake:payload -31016 # var/eax <- and lit => 25/and-with-eax lit/imm32 +30901 _string_81_subop_add/imm32/subx-name +30902 1/imm32/rm32-is-first-inout +30903 0/imm32/no-r32 +30904 2/imm32/imm32-is-second-inout +30905 0/imm32/no-imm8 +30906 0/imm32/no-disp32 +30907 0/imm32/no-xm32 +30908 0/imm32/no-x32 +30909 0x11/imm32/alloc-id:fake +30910 _Primitive-subtract-from-eax/imm32/next +30911 # - subtract +30912 _Primitive-subtract-from-eax: # (payload primitive) +30913 0x11/imm32/alloc-id:fake:payload +30914 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 +30915 0x11/imm32/alloc-id:fake +30916 _string-subtract/imm32/name +30917 0x11/imm32/alloc-id:fake +30918 Single-lit-var/imm32/inouts +30919 0x11/imm32/alloc-id:fake +30920 Single-int-var-in-eax/imm32/outputs +30921 0x11/imm32/alloc-id:fake +30922 _string_2d_subtract_from_eax/imm32/subx-name +30923 0/imm32/no-rm32 +30924 0/imm32/no-r32 +30925 1/imm32/imm32-is-first-inout +30926 0/imm32/no-imm8 +30927 0/imm32/no-disp32 +30928 0/imm32/no-xm32 +30929 0/imm32/no-x32 +30930 0x11/imm32/alloc-id:fake +30931 _Primitive-subtract-reg-from-reg/imm32/next +30932 _Primitive-subtract-reg-from-reg: # (payload primitive) +30933 0x11/imm32/alloc-id:fake:payload +30934 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 +30935 0x11/imm32/alloc-id:fake +30936 _string-subtract/imm32/name +30937 0x11/imm32/alloc-id:fake +30938 Single-int-var-in-some-register/imm32/inouts +30939 0x11/imm32/alloc-id:fake +30940 Single-int-var-in-some-register/imm32/outputs +30941 0x11/imm32/alloc-id:fake +30942 _string_29_subtract_from/imm32/subx-name +30943 3/imm32/rm32-is-first-output +30944 1/imm32/r32-is-first-inout +30945 0/imm32/no-imm32 +30946 0/imm32/no-imm8 +30947 0/imm32/no-disp32 +30948 0/imm32/no-xm32 +30949 0/imm32/no-x32 +30950 0x11/imm32/alloc-id:fake +30951 _Primitive-subtract-reg-from-mem/imm32/next +30952 _Primitive-subtract-reg-from-mem: # (payload primitive) +30953 0x11/imm32/alloc-id:fake:payload +30954 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 +30955 0x11/imm32/alloc-id:fake +30956 _string-subtract-from/imm32/name +30957 0x11/imm32/alloc-id:fake +30958 Two-args-int-stack-int-reg/imm32/inouts +30959 0/imm32/no-outputs +30960 0/imm32/no-outputs +30961 0x11/imm32/alloc-id:fake +30962 _string_29_subtract_from/imm32/subx-name +30963 1/imm32/rm32-is-first-inout +30964 2/imm32/r32-is-second-inout +30965 0/imm32/no-imm32 +30966 0/imm32/no-imm8 +30967 0/imm32/no-disp32 +30968 0/imm32/no-xm32 +30969 0/imm32/no-x32 +30970 0x11/imm32/alloc-id:fake +30971 _Primitive-subtract-mem-from-reg/imm32/next +30972 _Primitive-subtract-mem-from-reg: # (payload primitive) +30973 0x11/imm32/alloc-id:fake:payload +30974 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 +30975 0x11/imm32/alloc-id:fake +30976 _string-subtract/imm32/name +30977 0x11/imm32/alloc-id:fake +30978 Single-int-var-in-mem/imm32/inouts +30979 0x11/imm32/alloc-id:fake +30980 Single-int-var-in-some-register/imm32/outputs +30981 0x11/imm32/alloc-id:fake +30982 _string_2b_subtract/imm32/subx-name +30983 1/imm32/rm32-is-first-inout +30984 3/imm32/r32-is-first-output +30985 0/imm32/no-imm32 +30986 0/imm32/no-imm8 +30987 0/imm32/no-disp32 +30988 0/imm32/no-xm32 +30989 0/imm32/no-x32 +30990 0x11/imm32/alloc-id:fake +30991 _Primitive-subtract-lit-from-reg/imm32/next +30992 _Primitive-subtract-lit-from-reg: # (payload primitive) +30993 0x11/imm32/alloc-id:fake:payload +30994 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 +30995 0x11/imm32/alloc-id:fake +30996 _string-subtract/imm32/name +30997 0x11/imm32/alloc-id:fake +30998 Single-lit-var/imm32/inouts +30999 0x11/imm32/alloc-id:fake +31000 Single-int-var-in-some-register/imm32/outputs +31001 0x11/imm32/alloc-id:fake +31002 _string_81_subop_subtract/imm32/subx-name +31003 3/imm32/rm32-is-first-output +31004 0/imm32/no-r32 +31005 1/imm32/imm32-is-first-inout +31006 0/imm32/no-imm8 +31007 0/imm32/no-disp32 +31008 0/imm32/no-xm32 +31009 0/imm32/no-x32 +31010 0x11/imm32/alloc-id:fake +31011 _Primitive-subtract-lit-from-mem/imm32/next +31012 _Primitive-subtract-lit-from-mem: # (payload primitive) +31013 0x11/imm32/alloc-id:fake:payload +31014 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 +31015 0x11/imm32/alloc-id:fake +31016 _string-subtract-from/imm32/name 31017 0x11/imm32/alloc-id:fake -31018 _string-and/imm32/name -31019 0x11/imm32/alloc-id:fake -31020 Single-lit-var/imm32/inouts +31018 Int-var-and-literal/imm32/inouts +31019 0/imm32/no-outputs +31020 0/imm32/no-outputs 31021 0x11/imm32/alloc-id:fake -31022 Single-int-var-in-eax/imm32/outputs -31023 0x11/imm32/alloc-id:fake -31024 _string_25_and_with_eax/imm32/subx-name -31025 0/imm32/no-rm32 -31026 0/imm32/no-r32 -31027 1/imm32/imm32-is-first-inout -31028 0/imm32/no-imm8 -31029 0/imm32/no-disp32 -31030 0/imm32/no-xm32 -31031 0/imm32/no-x32 -31032 0x11/imm32/alloc-id:fake -31033 _Primitive-and-reg-with-reg/imm32/next -31034 _Primitive-and-reg-with-reg: # (payload primitive) -31035 0x11/imm32/alloc-id:fake:payload -31036 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 -31037 0x11/imm32/alloc-id:fake -31038 _string-and/imm32/name -31039 0x11/imm32/alloc-id:fake -31040 Single-int-var-in-some-register/imm32/inouts -31041 0x11/imm32/alloc-id:fake -31042 Single-int-var-in-some-register/imm32/outputs -31043 0x11/imm32/alloc-id:fake -31044 _string_21_and_with/imm32/subx-name -31045 3/imm32/rm32-is-first-output -31046 1/imm32/r32-is-first-inout -31047 0/imm32/no-imm32 -31048 0/imm32/no-imm8 -31049 0/imm32/no-disp32 -31050 0/imm32/no-xm32 -31051 0/imm32/no-x32 -31052 0x11/imm32/alloc-id:fake -31053 _Primitive-and-reg-with-mem/imm32/next -31054 _Primitive-and-reg-with-mem: # (payload primitive) -31055 0x11/imm32/alloc-id:fake:payload -31056 # and-with var1 var2/reg => 21/and-with var1 var2/r32 -31057 0x11/imm32/alloc-id:fake -31058 _string-and-with/imm32/name -31059 0x11/imm32/alloc-id:fake -31060 Two-args-int-stack-int-reg/imm32/inouts -31061 0/imm32/no-outputs -31062 0/imm32/no-outputs -31063 0x11/imm32/alloc-id:fake -31064 _string_21_and_with/imm32/subx-name -31065 1/imm32/rm32-is-first-inout -31066 2/imm32/r32-is-second-inout -31067 0/imm32/no-imm32 -31068 0/imm32/no-imm8 -31069 0/imm32/no-disp32 -31070 0/imm32/no-xm32 -31071 0/imm32/no-x32 -31072 0x11/imm32/alloc-id:fake -31073 _Primitive-and-mem-with-reg/imm32/next -31074 _Primitive-and-mem-with-reg: # (payload primitive) -31075 0x11/imm32/alloc-id:fake:payload -31076 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 -31077 0x11/imm32/alloc-id:fake -31078 _string-and/imm32/name -31079 0x11/imm32/alloc-id:fake -31080 Single-int-var-in-mem/imm32/inouts -31081 0x11/imm32/alloc-id:fake -31082 Single-int-var-in-some-register/imm32/outputs -31083 0x11/imm32/alloc-id:fake -31084 _string_23_and/imm32/subx-name -31085 1/imm32/rm32-is-first-inout -31086 3/imm32/r32-is-first-output -31087 0/imm32/no-imm32 -31088 0/imm32/no-imm8 -31089 0/imm32/no-disp32 -31090 0/imm32/no-xm32 -31091 0/imm32/no-x32 -31092 0x11/imm32/alloc-id:fake -31093 _Primitive-and-lit-with-reg/imm32/next -31094 _Primitive-and-lit-with-reg: # (payload primitive) -31095 0x11/imm32/alloc-id:fake:payload -31096 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 -31097 0x11/imm32/alloc-id:fake -31098 _string-and/imm32/name -31099 0x11/imm32/alloc-id:fake -31100 Single-lit-var/imm32/inouts -31101 0x11/imm32/alloc-id:fake -31102 Single-int-var-in-some-register/imm32/outputs -31103 0x11/imm32/alloc-id:fake -31104 _string_81_subop_and/imm32/subx-name -31105 3/imm32/rm32-is-first-output -31106 0/imm32/no-r32 -31107 1/imm32/imm32-is-first-inout -31108 0/imm32/no-imm8 -31109 0/imm32/no-disp32 -31110 0/imm32/no-xm32 -31111 0/imm32/no-x32 -31112 0x11/imm32/alloc-id:fake -31113 _Primitive-and-lit-with-mem/imm32/next -31114 _Primitive-and-lit-with-mem: # (payload primitive) -31115 0x11/imm32/alloc-id:fake:payload -31116 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 -31117 0x11/imm32/alloc-id:fake -31118 _string-and-with/imm32/name -31119 0x11/imm32/alloc-id:fake -31120 Int-var-and-literal/imm32/inouts -31121 0/imm32/no-outputs -31122 0/imm32/no-outputs -31123 0x11/imm32/alloc-id:fake -31124 _string_81_subop_and/imm32/subx-name -31125 1/imm32/rm32-is-first-inout -31126 0/imm32/no-r32 -31127 2/imm32/imm32-is-second-inout -31128 0/imm32/no-imm8 -31129 0/imm32/no-disp32 -31130 0/imm32/no-xm32 -31131 0/imm32/no-x32 -31132 0x11/imm32/alloc-id:fake -31133 _Primitive-or-with-eax/imm32/next -31134 # - or -31135 _Primitive-or-with-eax: # (payload primitive) -31136 0x11/imm32/alloc-id:fake:payload -31137 # var/eax <- or lit => 0d/or-with-eax lit/imm32 +31022 _string_81_subop_subtract/imm32/subx-name +31023 1/imm32/rm32-is-first-inout +31024 0/imm32/no-r32 +31025 2/imm32/imm32-is-second-inout +31026 0/imm32/no-imm8 +31027 0/imm32/no-disp32 +31028 0/imm32/no-xm32 +31029 0/imm32/no-x32 +31030 0x11/imm32/alloc-id:fake +31031 _Primitive-and-with-eax/imm32/next +31032 # - and +31033 _Primitive-and-with-eax: # (payload primitive) +31034 0x11/imm32/alloc-id:fake:payload +31035 # var/eax <- and lit => 25/and-with-eax lit/imm32 +31036 0x11/imm32/alloc-id:fake +31037 _string-and/imm32/name +31038 0x11/imm32/alloc-id:fake +31039 Single-lit-var/imm32/inouts +31040 0x11/imm32/alloc-id:fake +31041 Single-int-var-in-eax/imm32/outputs +31042 0x11/imm32/alloc-id:fake +31043 _string_25_and_with_eax/imm32/subx-name +31044 0/imm32/no-rm32 +31045 0/imm32/no-r32 +31046 1/imm32/imm32-is-first-inout +31047 0/imm32/no-imm8 +31048 0/imm32/no-disp32 +31049 0/imm32/no-xm32 +31050 0/imm32/no-x32 +31051 0x11/imm32/alloc-id:fake +31052 _Primitive-and-reg-with-reg/imm32/next +31053 _Primitive-and-reg-with-reg: # (payload primitive) +31054 0x11/imm32/alloc-id:fake:payload +31055 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 +31056 0x11/imm32/alloc-id:fake +31057 _string-and/imm32/name +31058 0x11/imm32/alloc-id:fake +31059 Single-int-var-in-some-register/imm32/inouts +31060 0x11/imm32/alloc-id:fake +31061 Single-int-var-in-some-register/imm32/outputs +31062 0x11/imm32/alloc-id:fake +31063 _string_21_and_with/imm32/subx-name +31064 3/imm32/rm32-is-first-output +31065 1/imm32/r32-is-first-inout +31066 0/imm32/no-imm32 +31067 0/imm32/no-imm8 +31068 0/imm32/no-disp32 +31069 0/imm32/no-xm32 +31070 0/imm32/no-x32 +31071 0x11/imm32/alloc-id:fake +31072 _Primitive-and-reg-with-mem/imm32/next +31073 _Primitive-and-reg-with-mem: # (payload primitive) +31074 0x11/imm32/alloc-id:fake:payload +31075 # and-with var1 var2/reg => 21/and-with var1 var2/r32 +31076 0x11/imm32/alloc-id:fake +31077 _string-and-with/imm32/name +31078 0x11/imm32/alloc-id:fake +31079 Two-args-int-stack-int-reg/imm32/inouts +31080 0/imm32/no-outputs +31081 0/imm32/no-outputs +31082 0x11/imm32/alloc-id:fake +31083 _string_21_and_with/imm32/subx-name +31084 1/imm32/rm32-is-first-inout +31085 2/imm32/r32-is-second-inout +31086 0/imm32/no-imm32 +31087 0/imm32/no-imm8 +31088 0/imm32/no-disp32 +31089 0/imm32/no-xm32 +31090 0/imm32/no-x32 +31091 0x11/imm32/alloc-id:fake +31092 _Primitive-and-mem-with-reg/imm32/next +31093 _Primitive-and-mem-with-reg: # (payload primitive) +31094 0x11/imm32/alloc-id:fake:payload +31095 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 +31096 0x11/imm32/alloc-id:fake +31097 _string-and/imm32/name +31098 0x11/imm32/alloc-id:fake +31099 Single-int-var-in-mem/imm32/inouts +31100 0x11/imm32/alloc-id:fake +31101 Single-int-var-in-some-register/imm32/outputs +31102 0x11/imm32/alloc-id:fake +31103 _string_23_and/imm32/subx-name +31104 1/imm32/rm32-is-first-inout +31105 3/imm32/r32-is-first-output +31106 0/imm32/no-imm32 +31107 0/imm32/no-imm8 +31108 0/imm32/no-disp32 +31109 0/imm32/no-xm32 +31110 0/imm32/no-x32 +31111 0x11/imm32/alloc-id:fake +31112 _Primitive-and-lit-with-reg/imm32/next +31113 _Primitive-and-lit-with-reg: # (payload primitive) +31114 0x11/imm32/alloc-id:fake:payload +31115 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 +31116 0x11/imm32/alloc-id:fake +31117 _string-and/imm32/name +31118 0x11/imm32/alloc-id:fake +31119 Single-lit-var/imm32/inouts +31120 0x11/imm32/alloc-id:fake +31121 Single-int-var-in-some-register/imm32/outputs +31122 0x11/imm32/alloc-id:fake +31123 _string_81_subop_and/imm32/subx-name +31124 3/imm32/rm32-is-first-output +31125 0/imm32/no-r32 +31126 1/imm32/imm32-is-first-inout +31127 0/imm32/no-imm8 +31128 0/imm32/no-disp32 +31129 0/imm32/no-xm32 +31130 0/imm32/no-x32 +31131 0x11/imm32/alloc-id:fake +31132 _Primitive-and-lit-with-mem/imm32/next +31133 _Primitive-and-lit-with-mem: # (payload primitive) +31134 0x11/imm32/alloc-id:fake:payload +31135 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 +31136 0x11/imm32/alloc-id:fake +31137 _string-and-with/imm32/name 31138 0x11/imm32/alloc-id:fake -31139 _string-or/imm32/name -31140 0x11/imm32/alloc-id:fake -31141 Single-lit-var/imm32/inouts +31139 Int-var-and-literal/imm32/inouts +31140 0/imm32/no-outputs +31141 0/imm32/no-outputs 31142 0x11/imm32/alloc-id:fake -31143 Single-int-var-in-eax/imm32/outputs -31144 0x11/imm32/alloc-id:fake -31145 _string_0d_or_with_eax/imm32/subx-name -31146 0/imm32/no-rm32 -31147 0/imm32/no-r32 -31148 1/imm32/imm32-is-first-inout -31149 0/imm32/no-imm8 -31150 0/imm32/no-disp32 -31151 0/imm32/no-xm32 -31152 0/imm32/no-x32 -31153 0x11/imm32/alloc-id:fake -31154 _Primitive-or-reg-with-reg/imm32/next -31155 _Primitive-or-reg-with-reg: # (payload primitive) -31156 0x11/imm32/alloc-id:fake:payload -31157 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 -31158 0x11/imm32/alloc-id:fake -31159 _string-or/imm32/name -31160 0x11/imm32/alloc-id:fake -31161 Single-int-var-in-some-register/imm32/inouts -31162 0x11/imm32/alloc-id:fake -31163 Single-int-var-in-some-register/imm32/outputs -31164 0x11/imm32/alloc-id:fake -31165 _string_09_or_with/imm32/subx-name -31166 3/imm32/rm32-is-first-output -31167 1/imm32/r32-is-first-inout -31168 0/imm32/no-imm32 -31169 0/imm32/no-imm8 -31170 0/imm32/no-disp32 -31171 0/imm32/no-xm32 -31172 0/imm32/no-x32 -31173 0x11/imm32/alloc-id:fake -31174 _Primitive-or-reg-with-mem/imm32/next -31175 _Primitive-or-reg-with-mem: # (payload primitive) -31176 0x11/imm32/alloc-id:fake:payload -31177 # or-with var1 var2/reg => 09/or-with var1 var2/r32 -31178 0x11/imm32/alloc-id:fake -31179 _string-or-with/imm32/name -31180 0x11/imm32/alloc-id:fake -31181 Two-args-int-stack-int-reg/imm32/inouts -31182 0/imm32/no-outputs -31183 0/imm32/no-outputs -31184 0x11/imm32/alloc-id:fake -31185 _string_09_or_with/imm32/subx-name -31186 1/imm32/rm32-is-first-inout -31187 2/imm32/r32-is-second-inout -31188 0/imm32/no-imm32 -31189 0/imm32/no-imm8 -31190 0/imm32/no-disp32 -31191 0/imm32/no-xm32 -31192 0/imm32/no-x32 -31193 0x11/imm32/alloc-id:fake -31194 _Primitive-or-mem-with-reg/imm32/next -31195 _Primitive-or-mem-with-reg: # (payload primitive) -31196 0x11/imm32/alloc-id:fake:payload -31197 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 -31198 0x11/imm32/alloc-id:fake -31199 _string-or/imm32/name -31200 0x11/imm32/alloc-id:fake -31201 Single-int-var-in-mem/imm32/inouts -31202 0x11/imm32/alloc-id:fake -31203 Single-int-var-in-some-register/imm32/outputs -31204 0x11/imm32/alloc-id:fake -31205 _string_0b_or/imm32/subx-name -31206 1/imm32/rm32-is-first-inout -31207 3/imm32/r32-is-first-output -31208 0/imm32/no-imm32 -31209 0/imm32/no-imm8 -31210 0/imm32/no-disp32 -31211 0/imm32/no-xm32 -31212 0/imm32/no-x32 -31213 0x11/imm32/alloc-id:fake -31214 _Primitive-or-lit-with-reg/imm32/next -31215 _Primitive-or-lit-with-reg: # (payload primitive) -31216 0x11/imm32/alloc-id:fake:payload -31217 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 -31218 0x11/imm32/alloc-id:fake -31219 _string-or/imm32/name -31220 0x11/imm32/alloc-id:fake -31221 Single-lit-var/imm32/inouts -31222 0x11/imm32/alloc-id:fake -31223 Single-int-var-in-some-register/imm32/outputs -31224 0x11/imm32/alloc-id:fake -31225 _string_81_subop_or/imm32/subx-name -31226 3/imm32/rm32-is-first-output -31227 0/imm32/no-r32 -31228 1/imm32/imm32-is-first-inout -31229 0/imm32/no-imm8 -31230 0/imm32/no-disp32 -31231 0/imm32/no-xm32 -31232 0/imm32/no-x32 -31233 0x11/imm32/alloc-id:fake -31234 _Primitive-or-lit-with-mem/imm32/next -31235 _Primitive-or-lit-with-mem: # (payload primitive) -31236 0x11/imm32/alloc-id:fake:payload -31237 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 -31238 0x11/imm32/alloc-id:fake -31239 _string-or-with/imm32/name -31240 0x11/imm32/alloc-id:fake -31241 Int-var-and-literal/imm32/inouts -31242 0/imm32/no-outputs -31243 0/imm32/no-outputs -31244 0x11/imm32/alloc-id:fake -31245 _string_81_subop_or/imm32/subx-name -31246 1/imm32/rm32-is-first-inout -31247 0/imm32/no-r32 -31248 2/imm32/imm32-is-second-inout -31249 0/imm32/no-imm8 -31250 0/imm32/no-disp32 -31251 0/imm32/no-xm32 -31252 0/imm32/no-x32 -31253 0x11/imm32/alloc-id:fake -31254 _Primitive-not-reg/imm32/next -31255 # - not -31256 _Primitive-not-reg: # (payload primitive) -31257 0x11/imm32/alloc-id:fake:payload -31258 # var1/reg <- not => f7 2/subop/not var1/rm32 +31143 _string_81_subop_and/imm32/subx-name +31144 1/imm32/rm32-is-first-inout +31145 0/imm32/no-r32 +31146 2/imm32/imm32-is-second-inout +31147 0/imm32/no-imm8 +31148 0/imm32/no-disp32 +31149 0/imm32/no-xm32 +31150 0/imm32/no-x32 +31151 0x11/imm32/alloc-id:fake +31152 _Primitive-or-with-eax/imm32/next +31153 # - or +31154 _Primitive-or-with-eax: # (payload primitive) +31155 0x11/imm32/alloc-id:fake:payload +31156 # var/eax <- or lit => 0d/or-with-eax lit/imm32 +31157 0x11/imm32/alloc-id:fake +31158 _string-or/imm32/name +31159 0x11/imm32/alloc-id:fake +31160 Single-lit-var/imm32/inouts +31161 0x11/imm32/alloc-id:fake +31162 Single-int-var-in-eax/imm32/outputs +31163 0x11/imm32/alloc-id:fake +31164 _string_0d_or_with_eax/imm32/subx-name +31165 0/imm32/no-rm32 +31166 0/imm32/no-r32 +31167 1/imm32/imm32-is-first-inout +31168 0/imm32/no-imm8 +31169 0/imm32/no-disp32 +31170 0/imm32/no-xm32 +31171 0/imm32/no-x32 +31172 0x11/imm32/alloc-id:fake +31173 _Primitive-or-reg-with-reg/imm32/next +31174 _Primitive-or-reg-with-reg: # (payload primitive) +31175 0x11/imm32/alloc-id:fake:payload +31176 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 +31177 0x11/imm32/alloc-id:fake +31178 _string-or/imm32/name +31179 0x11/imm32/alloc-id:fake +31180 Single-int-var-in-some-register/imm32/inouts +31181 0x11/imm32/alloc-id:fake +31182 Single-int-var-in-some-register/imm32/outputs +31183 0x11/imm32/alloc-id:fake +31184 _string_09_or_with/imm32/subx-name +31185 3/imm32/rm32-is-first-output +31186 1/imm32/r32-is-first-inout +31187 0/imm32/no-imm32 +31188 0/imm32/no-imm8 +31189 0/imm32/no-disp32 +31190 0/imm32/no-xm32 +31191 0/imm32/no-x32 +31192 0x11/imm32/alloc-id:fake +31193 _Primitive-or-reg-with-mem/imm32/next +31194 _Primitive-or-reg-with-mem: # (payload primitive) +31195 0x11/imm32/alloc-id:fake:payload +31196 # or-with var1 var2/reg => 09/or-with var1 var2/r32 +31197 0x11/imm32/alloc-id:fake +31198 _string-or-with/imm32/name +31199 0x11/imm32/alloc-id:fake +31200 Two-args-int-stack-int-reg/imm32/inouts +31201 0/imm32/no-outputs +31202 0/imm32/no-outputs +31203 0x11/imm32/alloc-id:fake +31204 _string_09_or_with/imm32/subx-name +31205 1/imm32/rm32-is-first-inout +31206 2/imm32/r32-is-second-inout +31207 0/imm32/no-imm32 +31208 0/imm32/no-imm8 +31209 0/imm32/no-disp32 +31210 0/imm32/no-xm32 +31211 0/imm32/no-x32 +31212 0x11/imm32/alloc-id:fake +31213 _Primitive-or-mem-with-reg/imm32/next +31214 _Primitive-or-mem-with-reg: # (payload primitive) +31215 0x11/imm32/alloc-id:fake:payload +31216 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 +31217 0x11/imm32/alloc-id:fake +31218 _string-or/imm32/name +31219 0x11/imm32/alloc-id:fake +31220 Single-int-var-in-mem/imm32/inouts +31221 0x11/imm32/alloc-id:fake +31222 Single-int-var-in-some-register/imm32/outputs +31223 0x11/imm32/alloc-id:fake +31224 _string_0b_or/imm32/subx-name +31225 1/imm32/rm32-is-first-inout +31226 3/imm32/r32-is-first-output +31227 0/imm32/no-imm32 +31228 0/imm32/no-imm8 +31229 0/imm32/no-disp32 +31230 0/imm32/no-xm32 +31231 0/imm32/no-x32 +31232 0x11/imm32/alloc-id:fake +31233 _Primitive-or-lit-with-reg/imm32/next +31234 _Primitive-or-lit-with-reg: # (payload primitive) +31235 0x11/imm32/alloc-id:fake:payload +31236 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 +31237 0x11/imm32/alloc-id:fake +31238 _string-or/imm32/name +31239 0x11/imm32/alloc-id:fake +31240 Single-lit-var/imm32/inouts +31241 0x11/imm32/alloc-id:fake +31242 Single-int-var-in-some-register/imm32/outputs +31243 0x11/imm32/alloc-id:fake +31244 _string_81_subop_or/imm32/subx-name +31245 3/imm32/rm32-is-first-output +31246 0/imm32/no-r32 +31247 1/imm32/imm32-is-first-inout +31248 0/imm32/no-imm8 +31249 0/imm32/no-disp32 +31250 0/imm32/no-xm32 +31251 0/imm32/no-x32 +31252 0x11/imm32/alloc-id:fake +31253 _Primitive-or-lit-with-mem/imm32/next +31254 _Primitive-or-lit-with-mem: # (payload primitive) +31255 0x11/imm32/alloc-id:fake:payload +31256 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 +31257 0x11/imm32/alloc-id:fake +31258 _string-or-with/imm32/name 31259 0x11/imm32/alloc-id:fake -31260 _string-not/imm32/name -31261 0/imm32/no-inouts -31262 0/imm32/no-inouts +31260 Int-var-and-literal/imm32/inouts +31261 0/imm32/no-outputs +31262 0/imm32/no-outputs 31263 0x11/imm32/alloc-id:fake -31264 Single-int-var-in-some-register/imm32/outputs -31265 0x11/imm32/alloc-id:fake -31266 _string_f7_subop_not/imm32/subx-name -31267 3/imm32/rm32-is-first-output -31268 0/imm32/no-r32 -31269 0/imm32/no-imm32 -31270 0/imm32/no-imm8 -31271 0/imm32/no-disp32 -31272 0/imm32/no-xm32 -31273 0/imm32/no-x32 -31274 0x11/imm32/alloc-id:fake -31275 _Primitive-not-mem/imm32/next -31276 _Primitive-not-mem: # (payload primitive) -31277 0x11/imm32/alloc-id:fake:payload -31278 # not var1 => f7 2/subop/not var1/rm32 -31279 0x11/imm32/alloc-id:fake -31280 _string-not/imm32/name -31281 0x11/imm32/alloc-id:fake -31282 Single-int-var-in-mem/imm32/inouts -31283 0/imm32/no-outputs -31284 0/imm32/no-outputs -31285 0x11/imm32/alloc-id:fake -31286 _string_f7_subop_not/imm32/subx-name -31287 1/imm32/rm32-is-first-inout -31288 0/imm32/no-r32 -31289 0/imm32/no-imm32 -31290 0/imm32/no-imm8 -31291 0/imm32/no-disp32 -31292 0/imm32/no-xm32 -31293 0/imm32/no-x32 -31294 0x11/imm32/alloc-id:fake -31295 _Primitive-xor-with-eax/imm32/next -31296 # - xor -31297 _Primitive-xor-with-eax: # (payload primitive) -31298 0x11/imm32/alloc-id:fake:payload -31299 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 +31264 _string_81_subop_or/imm32/subx-name +31265 1/imm32/rm32-is-first-inout +31266 0/imm32/no-r32 +31267 2/imm32/imm32-is-second-inout +31268 0/imm32/no-imm8 +31269 0/imm32/no-disp32 +31270 0/imm32/no-xm32 +31271 0/imm32/no-x32 +31272 0x11/imm32/alloc-id:fake +31273 _Primitive-not-reg/imm32/next +31274 # - not +31275 _Primitive-not-reg: # (payload primitive) +31276 0x11/imm32/alloc-id:fake:payload +31277 # var1/reg <- not => f7 2/subop/not var1/rm32 +31278 0x11/imm32/alloc-id:fake +31279 _string-not/imm32/name +31280 0/imm32/no-inouts +31281 0/imm32/no-inouts +31282 0x11/imm32/alloc-id:fake +31283 Single-int-var-in-some-register/imm32/outputs +31284 0x11/imm32/alloc-id:fake +31285 _string_f7_subop_not/imm32/subx-name +31286 3/imm32/rm32-is-first-output +31287 0/imm32/no-r32 +31288 0/imm32/no-imm32 +31289 0/imm32/no-imm8 +31290 0/imm32/no-disp32 +31291 0/imm32/no-xm32 +31292 0/imm32/no-x32 +31293 0x11/imm32/alloc-id:fake +31294 _Primitive-not-mem/imm32/next +31295 _Primitive-not-mem: # (payload primitive) +31296 0x11/imm32/alloc-id:fake:payload +31297 # not var1 => f7 2/subop/not var1/rm32 +31298 0x11/imm32/alloc-id:fake +31299 _string-not/imm32/name 31300 0x11/imm32/alloc-id:fake -31301 _string-xor/imm32/name -31302 0x11/imm32/alloc-id:fake -31303 Single-lit-var/imm32/inouts +31301 Single-int-var-in-mem/imm32/inouts +31302 0/imm32/no-outputs +31303 0/imm32/no-outputs 31304 0x11/imm32/alloc-id:fake -31305 Single-int-var-in-eax/imm32/outputs -31306 0x11/imm32/alloc-id:fake -31307 _string_35_xor_with_eax/imm32/subx-name -31308 0/imm32/no-rm32 -31309 0/imm32/no-r32 -31310 1/imm32/imm32-is-first-inout -31311 0/imm32/no-imm8 -31312 0/imm32/no-disp32 -31313 0/imm32/no-xm32 -31314 0/imm32/no-x32 -31315 0x11/imm32/alloc-id:fake -31316 _Primitive-xor-reg-with-reg/imm32/next -31317 _Primitive-xor-reg-with-reg: # (payload primitive) -31318 0x11/imm32/alloc-id:fake:payload -31319 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 -31320 0x11/imm32/alloc-id:fake -31321 _string-xor/imm32/name -31322 0x11/imm32/alloc-id:fake -31323 Single-int-var-in-some-register/imm32/inouts -31324 0x11/imm32/alloc-id:fake -31325 Single-int-var-in-some-register/imm32/outputs -31326 0x11/imm32/alloc-id:fake -31327 _string_31_xor_with/imm32/subx-name -31328 3/imm32/rm32-is-first-output -31329 1/imm32/r32-is-first-inout -31330 0/imm32/no-imm32 -31331 0/imm32/no-imm8 -31332 0/imm32/no-disp32 -31333 0/imm32/no-xm32 -31334 0/imm32/no-x32 -31335 0x11/imm32/alloc-id:fake -31336 _Primitive-xor-reg-with-mem/imm32/next -31337 _Primitive-xor-reg-with-mem: # (payload primitive) -31338 0x11/imm32/alloc-id:fake:payload -31339 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 -31340 0x11/imm32/alloc-id:fake -31341 _string-xor-with/imm32/name -31342 0x11/imm32/alloc-id:fake -31343 Two-args-int-stack-int-reg/imm32/inouts -31344 0/imm32/no-outputs -31345 0/imm32/no-outputs -31346 0x11/imm32/alloc-id:fake -31347 _string_31_xor_with/imm32/subx-name -31348 1/imm32/rm32-is-first-inout -31349 2/imm32/r32-is-second-inout -31350 0/imm32/no-imm32 -31351 0/imm32/no-imm8 -31352 0/imm32/no-disp32 -31353 0/imm32/no-xm32 -31354 0/imm32/no-x32 -31355 0x11/imm32/alloc-id:fake -31356 _Primitive-xor-mem-with-reg/imm32/next -31357 _Primitive-xor-mem-with-reg: # (payload primitive) -31358 0x11/imm32/alloc-id:fake:payload -31359 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 -31360 0x11/imm32/alloc-id:fake -31361 _string-xor/imm32/name -31362 0x11/imm32/alloc-id:fake -31363 Single-int-var-in-mem/imm32/inouts -31364 0x11/imm32/alloc-id:fake -31365 Single-int-var-in-some-register/imm32/outputs -31366 0x11/imm32/alloc-id:fake -31367 _string_33_xor/imm32/subx-name -31368 1/imm32/rm32-is-first-inout -31369 3/imm32/r32-is-first-output -31370 0/imm32/no-imm32 -31371 0/imm32/no-imm8 -31372 0/imm32/no-disp32 -31373 0/imm32/no-xm32 -31374 0/imm32/no-x32 -31375 0x11/imm32/alloc-id:fake -31376 _Primitive-xor-lit-with-reg/imm32/next -31377 _Primitive-xor-lit-with-reg: # (payload primitive) -31378 0x11/imm32/alloc-id:fake:payload -31379 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 -31380 0x11/imm32/alloc-id:fake -31381 _string-xor/imm32/name -31382 0x11/imm32/alloc-id:fake -31383 Single-lit-var/imm32/inouts -31384 0x11/imm32/alloc-id:fake -31385 Single-int-var-in-some-register/imm32/outputs -31386 0x11/imm32/alloc-id:fake -31387 _string_81_subop_xor/imm32/subx-name -31388 3/imm32/rm32-is-first-output -31389 0/imm32/no-r32 -31390 1/imm32/imm32-is-first-inout -31391 0/imm32/no-imm8 -31392 0/imm32/no-disp32 -31393 0/imm32/no-xm32 -31394 0/imm32/no-x32 -31395 0x11/imm32/alloc-id:fake -31396 _Primitive-xor-lit-with-mem/imm32/next -31397 _Primitive-xor-lit-with-mem: # (payload primitive) -31398 0x11/imm32/alloc-id:fake:payload -31399 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 -31400 0x11/imm32/alloc-id:fake -31401 _string-xor-with/imm32/name -31402 0x11/imm32/alloc-id:fake -31403 Int-var-and-literal/imm32/inouts -31404 0/imm32/no-outputs -31405 0/imm32/no-outputs -31406 0x11/imm32/alloc-id:fake -31407 _string_81_subop_xor/imm32/subx-name -31408 1/imm32/rm32-is-first-inout -31409 0/imm32/no-r32 -31410 2/imm32/imm32-is-second-inout -31411 0/imm32/no-imm8 -31412 0/imm32/no-disp32 -31413 0/imm32/no-xm32 -31414 0/imm32/no-x32 -31415 0x11/imm32/alloc-id:fake -31416 _Primitive-shift-reg-left-by-lit/imm32/next -31417 _Primitive-shift-reg-left-by-lit: # (payload primitive) -31418 0x11/imm32/alloc-id:fake:payload -31419 # var1/reg <- shift-left lit => c1/shift 4/subop/left var1/rm32 lit/imm32 -31420 0x11/imm32/alloc-id:fake -31421 _string-shift-left/imm32/name -31422 0x11/imm32/alloc-id:fake -31423 Single-lit-var/imm32/inouts -31424 0x11/imm32/alloc-id:fake -31425 Single-int-var-in-some-register/imm32/outputs -31426 0x11/imm32/alloc-id:fake -31427 _string_c1_subop_shift_left/imm32/subx-name -31428 3/imm32/rm32-is-first-output -31429 0/imm32/no-r32 -31430 0/imm32/no-imm32 -31431 1/imm32/imm8-is-first-inout -31432 0/imm32/no-disp32 -31433 0/imm32/no-xm32 -31434 0/imm32/no-x32 -31435 0x11/imm32/alloc-id:fake -31436 _Primitive-shift-reg-right-by-lit/imm32/next -31437 _Primitive-shift-reg-right-by-lit: # (payload primitive) -31438 0x11/imm32/alloc-id:fake:payload -31439 # var1/reg <- shift-right lit => c1/shift 5/subop/right var1/rm32 lit/imm32 -31440 0x11/imm32/alloc-id:fake -31441 _string-shift-right/imm32/name -31442 0x11/imm32/alloc-id:fake -31443 Single-lit-var/imm32/inouts -31444 0x11/imm32/alloc-id:fake -31445 Single-int-var-in-some-register/imm32/outputs -31446 0x11/imm32/alloc-id:fake -31447 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name -31448 3/imm32/rm32-is-first-output -31449 0/imm32/no-r32 -31450 0/imm32/no-imm32 -31451 1/imm32/imm8-is-first-inout -31452 0/imm32/no-disp32 -31453 0/imm32/no-xm32 -31454 0/imm32/no-x32 -31455 0x11/imm32/alloc-id:fake -31456 _Primitive-shift-reg-right-signed-by-lit/imm32/next -31457 _Primitive-shift-reg-right-signed-by-lit: # (payload primitive) -31458 0x11/imm32/alloc-id:fake:payload -31459 # var1/reg <- shift-right-signed lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 -31460 0x11/imm32/alloc-id:fake -31461 _string-shift-right-signed/imm32/name -31462 0x11/imm32/alloc-id:fake -31463 Single-lit-var/imm32/inouts -31464 0x11/imm32/alloc-id:fake -31465 Single-int-var-in-some-register/imm32/outputs -31466 0x11/imm32/alloc-id:fake -31467 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name -31468 3/imm32/rm32-is-first-output -31469 0/imm32/no-r32 -31470 0/imm32/no-imm32 -31471 1/imm32/imm8-is-first-inout -31472 0/imm32/no-disp32 -31473 0/imm32/no-xm32 -31474 0/imm32/no-x32 -31475 0x11/imm32/alloc-id:fake -31476 _Primitive-shift-mem-left-by-lit/imm32/next -31477 _Primitive-shift-mem-left-by-lit: # (payload primitive) -31478 0x11/imm32/alloc-id:fake:payload -31479 # shift-left var1, lit => c1/shift 4/subop/left var1/rm32 lit/imm32 -31480 0x11/imm32/alloc-id:fake -31481 _string-shift-left/imm32/name -31482 0x11/imm32/alloc-id:fake -31483 Int-var-and-literal/imm32/inouts -31484 0/imm32/no-outputs -31485 0/imm32/no-outputs -31486 0x11/imm32/alloc-id:fake -31487 _string_c1_subop_shift_left/imm32/subx-name -31488 1/imm32/rm32-is-first-inout -31489 0/imm32/no-r32 -31490 0/imm32/no-imm32 -31491 2/imm32/imm8-is-second-inout -31492 0/imm32/no-disp32 -31493 0/imm32/no-xm32 -31494 0/imm32/no-x32 -31495 0x11/imm32/alloc-id:fake -31496 _Primitive-shift-mem-right-by-lit/imm32/next -31497 _Primitive-shift-mem-right-by-lit: # (payload primitive) -31498 0x11/imm32/alloc-id:fake:payload -31499 # shift-right var1, lit => c1/shift 5/subop/right var1/rm32 lit/imm32 -31500 0x11/imm32/alloc-id:fake -31501 _string-shift-right/imm32/name -31502 0x11/imm32/alloc-id:fake -31503 Int-var-and-literal/imm32/inouts +31305 _string_f7_subop_not/imm32/subx-name +31306 1/imm32/rm32-is-first-inout +31307 0/imm32/no-r32 +31308 0/imm32/no-imm32 +31309 0/imm32/no-imm8 +31310 0/imm32/no-disp32 +31311 0/imm32/no-xm32 +31312 0/imm32/no-x32 +31313 0x11/imm32/alloc-id:fake +31314 _Primitive-xor-with-eax/imm32/next +31315 # - xor +31316 _Primitive-xor-with-eax: # (payload primitive) +31317 0x11/imm32/alloc-id:fake:payload +31318 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 +31319 0x11/imm32/alloc-id:fake +31320 _string-xor/imm32/name +31321 0x11/imm32/alloc-id:fake +31322 Single-lit-var/imm32/inouts +31323 0x11/imm32/alloc-id:fake +31324 Single-int-var-in-eax/imm32/outputs +31325 0x11/imm32/alloc-id:fake +31326 _string_35_xor_with_eax/imm32/subx-name +31327 0/imm32/no-rm32 +31328 0/imm32/no-r32 +31329 1/imm32/imm32-is-first-inout +31330 0/imm32/no-imm8 +31331 0/imm32/no-disp32 +31332 0/imm32/no-xm32 +31333 0/imm32/no-x32 +31334 0x11/imm32/alloc-id:fake +31335 _Primitive-xor-reg-with-reg/imm32/next +31336 _Primitive-xor-reg-with-reg: # (payload primitive) +31337 0x11/imm32/alloc-id:fake:payload +31338 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 +31339 0x11/imm32/alloc-id:fake +31340 _string-xor/imm32/name +31341 0x11/imm32/alloc-id:fake +31342 Single-int-var-in-some-register/imm32/inouts +31343 0x11/imm32/alloc-id:fake +31344 Single-int-var-in-some-register/imm32/outputs +31345 0x11/imm32/alloc-id:fake +31346 _string_31_xor_with/imm32/subx-name +31347 3/imm32/rm32-is-first-output +31348 1/imm32/r32-is-first-inout +31349 0/imm32/no-imm32 +31350 0/imm32/no-imm8 +31351 0/imm32/no-disp32 +31352 0/imm32/no-xm32 +31353 0/imm32/no-x32 +31354 0x11/imm32/alloc-id:fake +31355 _Primitive-xor-reg-with-mem/imm32/next +31356 _Primitive-xor-reg-with-mem: # (payload primitive) +31357 0x11/imm32/alloc-id:fake:payload +31358 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 +31359 0x11/imm32/alloc-id:fake +31360 _string-xor-with/imm32/name +31361 0x11/imm32/alloc-id:fake +31362 Two-args-int-stack-int-reg/imm32/inouts +31363 0/imm32/no-outputs +31364 0/imm32/no-outputs +31365 0x11/imm32/alloc-id:fake +31366 _string_31_xor_with/imm32/subx-name +31367 1/imm32/rm32-is-first-inout +31368 2/imm32/r32-is-second-inout +31369 0/imm32/no-imm32 +31370 0/imm32/no-imm8 +31371 0/imm32/no-disp32 +31372 0/imm32/no-xm32 +31373 0/imm32/no-x32 +31374 0x11/imm32/alloc-id:fake +31375 _Primitive-xor-mem-with-reg/imm32/next +31376 _Primitive-xor-mem-with-reg: # (payload primitive) +31377 0x11/imm32/alloc-id:fake:payload +31378 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 +31379 0x11/imm32/alloc-id:fake +31380 _string-xor/imm32/name +31381 0x11/imm32/alloc-id:fake +31382 Single-int-var-in-mem/imm32/inouts +31383 0x11/imm32/alloc-id:fake +31384 Single-int-var-in-some-register/imm32/outputs +31385 0x11/imm32/alloc-id:fake +31386 _string_33_xor/imm32/subx-name +31387 1/imm32/rm32-is-first-inout +31388 3/imm32/r32-is-first-output +31389 0/imm32/no-imm32 +31390 0/imm32/no-imm8 +31391 0/imm32/no-disp32 +31392 0/imm32/no-xm32 +31393 0/imm32/no-x32 +31394 0x11/imm32/alloc-id:fake +31395 _Primitive-xor-lit-with-reg/imm32/next +31396 _Primitive-xor-lit-with-reg: # (payload primitive) +31397 0x11/imm32/alloc-id:fake:payload +31398 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 +31399 0x11/imm32/alloc-id:fake +31400 _string-xor/imm32/name +31401 0x11/imm32/alloc-id:fake +31402 Single-lit-var/imm32/inouts +31403 0x11/imm32/alloc-id:fake +31404 Single-int-var-in-some-register/imm32/outputs +31405 0x11/imm32/alloc-id:fake +31406 _string_81_subop_xor/imm32/subx-name +31407 3/imm32/rm32-is-first-output +31408 0/imm32/no-r32 +31409 1/imm32/imm32-is-first-inout +31410 0/imm32/no-imm8 +31411 0/imm32/no-disp32 +31412 0/imm32/no-xm32 +31413 0/imm32/no-x32 +31414 0x11/imm32/alloc-id:fake +31415 _Primitive-xor-lit-with-mem/imm32/next +31416 _Primitive-xor-lit-with-mem: # (payload primitive) +31417 0x11/imm32/alloc-id:fake:payload +31418 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 +31419 0x11/imm32/alloc-id:fake +31420 _string-xor-with/imm32/name +31421 0x11/imm32/alloc-id:fake +31422 Int-var-and-literal/imm32/inouts +31423 0/imm32/no-outputs +31424 0/imm32/no-outputs +31425 0x11/imm32/alloc-id:fake +31426 _string_81_subop_xor/imm32/subx-name +31427 1/imm32/rm32-is-first-inout +31428 0/imm32/no-r32 +31429 2/imm32/imm32-is-second-inout +31430 0/imm32/no-imm8 +31431 0/imm32/no-disp32 +31432 0/imm32/no-xm32 +31433 0/imm32/no-x32 +31434 0x11/imm32/alloc-id:fake +31435 _Primitive-shift-reg-left-by-lit/imm32/next +31436 _Primitive-shift-reg-left-by-lit: # (payload primitive) +31437 0x11/imm32/alloc-id:fake:payload +31438 # var1/reg <- shift-left lit => c1/shift 4/subop/left var1/rm32 lit/imm32 +31439 0x11/imm32/alloc-id:fake +31440 _string-shift-left/imm32/name +31441 0x11/imm32/alloc-id:fake +31442 Single-lit-var/imm32/inouts +31443 0x11/imm32/alloc-id:fake +31444 Single-int-var-in-some-register/imm32/outputs +31445 0x11/imm32/alloc-id:fake +31446 _string_c1_subop_shift_left/imm32/subx-name +31447 3/imm32/rm32-is-first-output +31448 0/imm32/no-r32 +31449 0/imm32/no-imm32 +31450 1/imm32/imm8-is-first-inout +31451 0/imm32/no-disp32 +31452 0/imm32/no-xm32 +31453 0/imm32/no-x32 +31454 0x11/imm32/alloc-id:fake +31455 _Primitive-shift-reg-right-by-lit/imm32/next +31456 _Primitive-shift-reg-right-by-lit: # (payload primitive) +31457 0x11/imm32/alloc-id:fake:payload +31458 # var1/reg <- shift-right lit => c1/shift 5/subop/right var1/rm32 lit/imm32 +31459 0x11/imm32/alloc-id:fake +31460 _string-shift-right/imm32/name +31461 0x11/imm32/alloc-id:fake +31462 Single-lit-var/imm32/inouts +31463 0x11/imm32/alloc-id:fake +31464 Single-int-var-in-some-register/imm32/outputs +31465 0x11/imm32/alloc-id:fake +31466 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name +31467 3/imm32/rm32-is-first-output +31468 0/imm32/no-r32 +31469 0/imm32/no-imm32 +31470 1/imm32/imm8-is-first-inout +31471 0/imm32/no-disp32 +31472 0/imm32/no-xm32 +31473 0/imm32/no-x32 +31474 0x11/imm32/alloc-id:fake +31475 _Primitive-shift-reg-right-signed-by-lit/imm32/next +31476 _Primitive-shift-reg-right-signed-by-lit: # (payload primitive) +31477 0x11/imm32/alloc-id:fake:payload +31478 # var1/reg <- shift-right-signed lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 +31479 0x11/imm32/alloc-id:fake +31480 _string-shift-right-signed/imm32/name +31481 0x11/imm32/alloc-id:fake +31482 Single-lit-var/imm32/inouts +31483 0x11/imm32/alloc-id:fake +31484 Single-int-var-in-some-register/imm32/outputs +31485 0x11/imm32/alloc-id:fake +31486 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name +31487 3/imm32/rm32-is-first-output +31488 0/imm32/no-r32 +31489 0/imm32/no-imm32 +31490 1/imm32/imm8-is-first-inout +31491 0/imm32/no-disp32 +31492 0/imm32/no-xm32 +31493 0/imm32/no-x32 +31494 0x11/imm32/alloc-id:fake +31495 _Primitive-shift-mem-left-by-lit/imm32/next +31496 _Primitive-shift-mem-left-by-lit: # (payload primitive) +31497 0x11/imm32/alloc-id:fake:payload +31498 # shift-left var1, lit => c1/shift 4/subop/left var1/rm32 lit/imm32 +31499 0x11/imm32/alloc-id:fake +31500 _string-shift-left/imm32/name +31501 0x11/imm32/alloc-id:fake +31502 Int-var-and-literal/imm32/inouts +31503 0/imm32/no-outputs 31504 0/imm32/no-outputs -31505 0/imm32/no-outputs -31506 0x11/imm32/alloc-id:fake -31507 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name -31508 1/imm32/rm32-is-first-inout -31509 0/imm32/no-r32 -31510 0/imm32/no-imm32 -31511 2/imm32/imm8-is-second-inout -31512 0/imm32/no-disp32 -31513 0/imm32/no-xm32 -31514 0/imm32/no-x32 -31515 0x11/imm32/alloc-id:fake -31516 _Primitive-shift-mem-right-signed-by-lit/imm32/next -31517 _Primitive-shift-mem-right-signed-by-lit: # (payload primitive) -31518 0x11/imm32/alloc-id:fake:payload -31519 # shift-right-signed var1, lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 -31520 0x11/imm32/alloc-id:fake -31521 _string-shift-right-signed/imm32/name -31522 0x11/imm32/alloc-id:fake -31523 Int-var-and-literal/imm32/inouts +31505 0x11/imm32/alloc-id:fake +31506 _string_c1_subop_shift_left/imm32/subx-name +31507 1/imm32/rm32-is-first-inout +31508 0/imm32/no-r32 +31509 0/imm32/no-imm32 +31510 2/imm32/imm8-is-second-inout +31511 0/imm32/no-disp32 +31512 0/imm32/no-xm32 +31513 0/imm32/no-x32 +31514 0x11/imm32/alloc-id:fake +31515 _Primitive-shift-mem-right-by-lit/imm32/next +31516 _Primitive-shift-mem-right-by-lit: # (payload primitive) +31517 0x11/imm32/alloc-id:fake:payload +31518 # shift-right var1, lit => c1/shift 5/subop/right var1/rm32 lit/imm32 +31519 0x11/imm32/alloc-id:fake +31520 _string-shift-right/imm32/name +31521 0x11/imm32/alloc-id:fake +31522 Int-var-and-literal/imm32/inouts +31523 0/imm32/no-outputs 31524 0/imm32/no-outputs -31525 0/imm32/no-outputs -31526 0x11/imm32/alloc-id:fake -31527 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name -31528 1/imm32/rm32-is-first-inout -31529 0/imm32/no-r32 -31530 0/imm32/no-imm32 -31531 2/imm32/imm8-is-second-inout -31532 0/imm32/no-disp32 -31533 0/imm32/no-xm32 -31534 0/imm32/no-x32 -31535 0x11/imm32/alloc-id:fake -31536 _Primitive-copy-to-eax/imm32/next -31537 # - copy -31538 _Primitive-copy-to-eax: # (payload primitive) -31539 0x11/imm32/alloc-id:fake:payload -31540 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 +31525 0x11/imm32/alloc-id:fake +31526 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name +31527 1/imm32/rm32-is-first-inout +31528 0/imm32/no-r32 +31529 0/imm32/no-imm32 +31530 2/imm32/imm8-is-second-inout +31531 0/imm32/no-disp32 +31532 0/imm32/no-xm32 +31533 0/imm32/no-x32 +31534 0x11/imm32/alloc-id:fake +31535 _Primitive-shift-mem-right-signed-by-lit/imm32/next +31536 _Primitive-shift-mem-right-signed-by-lit: # (payload primitive) +31537 0x11/imm32/alloc-id:fake:payload +31538 # shift-right-signed var1, lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 +31539 0x11/imm32/alloc-id:fake +31540 _string-shift-right-signed/imm32/name 31541 0x11/imm32/alloc-id:fake -31542 _string-copy/imm32/name -31543 0x11/imm32/alloc-id:fake -31544 Single-lit-var/imm32/inouts +31542 Int-var-and-literal/imm32/inouts +31543 0/imm32/no-outputs +31544 0/imm32/no-outputs 31545 0x11/imm32/alloc-id:fake -31546 Single-int-var-in-eax/imm32/outputs -31547 0x11/imm32/alloc-id:fake -31548 _string_b8_copy_to_eax/imm32/subx-name -31549 0/imm32/no-rm32 -31550 0/imm32/no-r32 -31551 1/imm32/imm32-is-first-inout -31552 0/imm32/no-imm8 -31553 0/imm32/no-disp32 -31554 0/imm32/no-xm32 -31555 0/imm32/no-x32 -31556 0x11/imm32/alloc-id:fake -31557 _Primitive-copy-to-ecx/imm32/next -31558 _Primitive-copy-to-ecx: # (payload primitive) -31559 0x11/imm32/alloc-id:fake:payload -31560 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 -31561 0x11/imm32/alloc-id:fake -31562 _string-copy/imm32/name -31563 0x11/imm32/alloc-id:fake -31564 Single-lit-var/imm32/inouts -31565 0x11/imm32/alloc-id:fake -31566 Single-int-var-in-ecx/imm32/outputs -31567 0x11/imm32/alloc-id:fake -31568 _string_b9_copy_to_ecx/imm32/subx-name -31569 0/imm32/no-rm32 -31570 0/imm32/no-r32 -31571 1/imm32/imm32-is-first-inout -31572 0/imm32/no-imm8 -31573 0/imm32/no-disp32 -31574 0/imm32/no-xm32 -31575 0/imm32/no-x32 -31576 0x11/imm32/alloc-id:fake -31577 _Primitive-copy-to-edx/imm32/next -31578 _Primitive-copy-to-edx: # (payload primitive) -31579 0x11/imm32/alloc-id:fake:payload -31580 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 -31581 0x11/imm32/alloc-id:fake -31582 _string-copy/imm32/name -31583 0x11/imm32/alloc-id:fake -31584 Single-lit-var/imm32/inouts -31585 0x11/imm32/alloc-id:fake -31586 Single-int-var-in-edx/imm32/outputs -31587 0x11/imm32/alloc-id:fake -31588 _string_ba_copy_to_edx/imm32/subx-name -31589 0/imm32/no-rm32 -31590 0/imm32/no-r32 -31591 1/imm32/imm32-is-first-inout -31592 0/imm32/no-imm8 -31593 0/imm32/no-disp32 -31594 0/imm32/no-xm32 -31595 0/imm32/no-x32 -31596 0x11/imm32/alloc-id:fake -31597 _Primitive-copy-to-ebx/imm32/next -31598 _Primitive-copy-to-ebx: # (payload primitive) -31599 0x11/imm32/alloc-id:fake:payload -31600 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 -31601 0x11/imm32/alloc-id:fake -31602 _string-copy/imm32/name -31603 0x11/imm32/alloc-id:fake -31604 Single-lit-var/imm32/inouts -31605 0x11/imm32/alloc-id:fake -31606 Single-int-var-in-ebx/imm32/outputs -31607 0x11/imm32/alloc-id:fake -31608 _string_bb_copy_to_ebx/imm32/subx-name -31609 0/imm32/no-rm32 -31610 0/imm32/no-r32 -31611 1/imm32/imm32-is-first-inout -31612 0/imm32/no-imm8 -31613 0/imm32/no-disp32 -31614 0/imm32/no-xm32 -31615 0/imm32/no-x32 -31616 0x11/imm32/alloc-id:fake -31617 _Primitive-copy-to-esi/imm32/next -31618 _Primitive-copy-to-esi: # (payload primitive) -31619 0x11/imm32/alloc-id:fake:payload -31620 # var/esi <- copy lit => be/copy-to-esi lit/imm32 -31621 0x11/imm32/alloc-id:fake -31622 _string-copy/imm32/name -31623 0x11/imm32/alloc-id:fake -31624 Single-lit-var/imm32/inouts -31625 0x11/imm32/alloc-id:fake -31626 Single-int-var-in-esi/imm32/outputs -31627 0x11/imm32/alloc-id:fake -31628 _string_be_copy_to_esi/imm32/subx-name -31629 0/imm32/no-rm32 -31630 0/imm32/no-r32 -31631 1/imm32/imm32-is-first-inout -31632 0/imm32/no-imm8 -31633 0/imm32/no-disp32 -31634 0/imm32/no-xm32 -31635 0/imm32/no-x32 -31636 0x11/imm32/alloc-id:fake -31637 _Primitive-copy-to-edi/imm32/next -31638 _Primitive-copy-to-edi: # (payload primitive) -31639 0x11/imm32/alloc-id:fake:payload -31640 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 -31641 0x11/imm32/alloc-id:fake -31642 _string-copy/imm32/name -31643 0x11/imm32/alloc-id:fake -31644 Single-lit-var/imm32/inouts -31645 0x11/imm32/alloc-id:fake -31646 Single-int-var-in-edi/imm32/outputs -31647 0x11/imm32/alloc-id:fake -31648 _string_bf_copy_to_edi/imm32/subx-name -31649 0/imm32/no-rm32 -31650 0/imm32/no-r32 -31651 1/imm32/imm32-is-first-inout -31652 0/imm32/no-imm8 -31653 0/imm32/no-disp32 -31654 0/imm32/no-xm32 -31655 0/imm32/no-x32 -31656 0x11/imm32/alloc-id:fake -31657 _Primitive-copy-reg-to-reg/imm32/next -31658 _Primitive-copy-reg-to-reg: # (payload primitive) -31659 0x11/imm32/alloc-id:fake:payload -31660 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 -31661 0x11/imm32/alloc-id:fake -31662 _string-copy/imm32/name -31663 0x11/imm32/alloc-id:fake -31664 Single-int-var-in-some-register/imm32/inouts -31665 0x11/imm32/alloc-id:fake -31666 Single-int-var-in-some-register/imm32/outputs -31667 0x11/imm32/alloc-id:fake -31668 _string_89_<-/imm32/subx-name -31669 3/imm32/rm32-is-first-output -31670 1/imm32/r32-is-first-inout -31671 0/imm32/no-imm32 -31672 0/imm32/no-imm8 -31673 0/imm32/no-disp32 -31674 0/imm32/no-xm32 -31675 0/imm32/no-x32 -31676 0x11/imm32/alloc-id:fake -31677 _Primitive-copy-reg-to-mem/imm32/next -31678 _Primitive-copy-reg-to-mem: # (payload primitive) -31679 0x11/imm32/alloc-id:fake:payload -31680 # copy-to var1 var2/reg => 89/<- var1 var2/r32 -31681 0x11/imm32/alloc-id:fake -31682 _string-copy-to/imm32/name -31683 0x11/imm32/alloc-id:fake -31684 Two-args-int-stack-int-reg/imm32/inouts -31685 0/imm32/no-outputs -31686 0/imm32/no-outputs -31687 0x11/imm32/alloc-id:fake -31688 _string_89_<-/imm32/subx-name -31689 1/imm32/rm32-is-first-inout -31690 2/imm32/r32-is-second-inout -31691 0/imm32/no-imm32 -31692 0/imm32/no-imm8 -31693 0/imm32/no-disp32 -31694 0/imm32/no-xm32 -31695 0/imm32/no-x32 -31696 0x11/imm32/alloc-id:fake -31697 _Primitive-copy-mem-to-reg/imm32/next -31698 _Primitive-copy-mem-to-reg: # (payload primitive) -31699 0x11/imm32/alloc-id:fake:payload -31700 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 -31701 0x11/imm32/alloc-id:fake -31702 _string-copy/imm32/name -31703 0x11/imm32/alloc-id:fake -31704 Single-int-var-in-mem/imm32/inouts -31705 0x11/imm32/alloc-id:fake -31706 Single-int-var-in-some-register/imm32/outputs -31707 0x11/imm32/alloc-id:fake -31708 _string_8b_->/imm32/subx-name -31709 1/imm32/rm32-is-first-inout -31710 3/imm32/r32-is-first-output -31711 0/imm32/no-imm32 -31712 0/imm32/no-imm8 -31713 0/imm32/no-disp32 -31714 0/imm32/no-xm32 -31715 0/imm32/no-x32 -31716 0x11/imm32/alloc-id:fake -31717 _Primitive-copy-lit-to-reg/imm32/next -31718 _Primitive-copy-lit-to-reg: # (payload primitive) -31719 0x11/imm32/alloc-id:fake:payload -31720 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 -31721 0x11/imm32/alloc-id:fake -31722 _string-copy/imm32/name -31723 0x11/imm32/alloc-id:fake -31724 Single-lit-var/imm32/inouts -31725 0x11/imm32/alloc-id:fake -31726 Single-int-var-in-some-register/imm32/outputs -31727 0x11/imm32/alloc-id:fake -31728 _string_c7_subop_copy/imm32/subx-name -31729 3/imm32/rm32-is-first-output -31730 0/imm32/no-r32 -31731 1/imm32/imm32-is-first-inout -31732 0/imm32/no-imm8 -31733 0/imm32/no-disp32 -31734 0/imm32/no-xm32 -31735 0/imm32/no-x32 -31736 0x11/imm32/alloc-id:fake -31737 _Primitive-copy-lit-to-mem/imm32/next -31738 _Primitive-copy-lit-to-mem: # (payload primitive) -31739 0x11/imm32/alloc-id:fake:payload -31740 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 -31741 0x11/imm32/alloc-id:fake -31742 _string-copy-to/imm32/name -31743 0x11/imm32/alloc-id:fake -31744 Int-var-and-literal/imm32/inouts -31745 0/imm32/no-outputs -31746 0/imm32/no-outputs -31747 0x11/imm32/alloc-id:fake -31748 _string_c7_subop_copy/imm32/subx-name -31749 1/imm32/rm32-is-first-inout -31750 0/imm32/no-r32 -31751 2/imm32/imm32-is-second-inout -31752 0/imm32/no-imm8 -31753 0/imm32/no-disp32 -31754 0/imm32/no-xm32 -31755 0/imm32/no-x32 -31756 0x11/imm32/alloc-id:fake -31757 _Primitive-copy-byte-from-reg/imm32/next -31758 # - copy byte -31759 _Primitive-copy-byte-from-reg: -31760 0x11/imm32/alloc-id:fake:payload -31761 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32 +31546 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name +31547 1/imm32/rm32-is-first-inout +31548 0/imm32/no-r32 +31549 0/imm32/no-imm32 +31550 2/imm32/imm8-is-second-inout +31551 0/imm32/no-disp32 +31552 0/imm32/no-xm32 +31553 0/imm32/no-x32 +31554 0x11/imm32/alloc-id:fake +31555 _Primitive-copy-to-eax/imm32/next +31556 # - copy +31557 _Primitive-copy-to-eax: # (payload primitive) +31558 0x11/imm32/alloc-id:fake:payload +31559 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 +31560 0x11/imm32/alloc-id:fake +31561 _string-copy/imm32/name +31562 0x11/imm32/alloc-id:fake +31563 Single-lit-var/imm32/inouts +31564 0x11/imm32/alloc-id:fake +31565 Single-int-var-in-eax/imm32/outputs +31566 0x11/imm32/alloc-id:fake +31567 _string_b8_copy_to_eax/imm32/subx-name +31568 0/imm32/no-rm32 +31569 0/imm32/no-r32 +31570 1/imm32/imm32-is-first-inout +31571 0/imm32/no-imm8 +31572 0/imm32/no-disp32 +31573 0/imm32/no-xm32 +31574 0/imm32/no-x32 +31575 0x11/imm32/alloc-id:fake +31576 _Primitive-copy-to-ecx/imm32/next +31577 _Primitive-copy-to-ecx: # (payload primitive) +31578 0x11/imm32/alloc-id:fake:payload +31579 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 +31580 0x11/imm32/alloc-id:fake +31581 _string-copy/imm32/name +31582 0x11/imm32/alloc-id:fake +31583 Single-lit-var/imm32/inouts +31584 0x11/imm32/alloc-id:fake +31585 Single-int-var-in-ecx/imm32/outputs +31586 0x11/imm32/alloc-id:fake +31587 _string_b9_copy_to_ecx/imm32/subx-name +31588 0/imm32/no-rm32 +31589 0/imm32/no-r32 +31590 1/imm32/imm32-is-first-inout +31591 0/imm32/no-imm8 +31592 0/imm32/no-disp32 +31593 0/imm32/no-xm32 +31594 0/imm32/no-x32 +31595 0x11/imm32/alloc-id:fake +31596 _Primitive-copy-to-edx/imm32/next +31597 _Primitive-copy-to-edx: # (payload primitive) +31598 0x11/imm32/alloc-id:fake:payload +31599 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 +31600 0x11/imm32/alloc-id:fake +31601 _string-copy/imm32/name +31602 0x11/imm32/alloc-id:fake +31603 Single-lit-var/imm32/inouts +31604 0x11/imm32/alloc-id:fake +31605 Single-int-var-in-edx/imm32/outputs +31606 0x11/imm32/alloc-id:fake +31607 _string_ba_copy_to_edx/imm32/subx-name +31608 0/imm32/no-rm32 +31609 0/imm32/no-r32 +31610 1/imm32/imm32-is-first-inout +31611 0/imm32/no-imm8 +31612 0/imm32/no-disp32 +31613 0/imm32/no-xm32 +31614 0/imm32/no-x32 +31615 0x11/imm32/alloc-id:fake +31616 _Primitive-copy-to-ebx/imm32/next +31617 _Primitive-copy-to-ebx: # (payload primitive) +31618 0x11/imm32/alloc-id:fake:payload +31619 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 +31620 0x11/imm32/alloc-id:fake +31621 _string-copy/imm32/name +31622 0x11/imm32/alloc-id:fake +31623 Single-lit-var/imm32/inouts +31624 0x11/imm32/alloc-id:fake +31625 Single-int-var-in-ebx/imm32/outputs +31626 0x11/imm32/alloc-id:fake +31627 _string_bb_copy_to_ebx/imm32/subx-name +31628 0/imm32/no-rm32 +31629 0/imm32/no-r32 +31630 1/imm32/imm32-is-first-inout +31631 0/imm32/no-imm8 +31632 0/imm32/no-disp32 +31633 0/imm32/no-xm32 +31634 0/imm32/no-x32 +31635 0x11/imm32/alloc-id:fake +31636 _Primitive-copy-to-esi/imm32/next +31637 _Primitive-copy-to-esi: # (payload primitive) +31638 0x11/imm32/alloc-id:fake:payload +31639 # var/esi <- copy lit => be/copy-to-esi lit/imm32 +31640 0x11/imm32/alloc-id:fake +31641 _string-copy/imm32/name +31642 0x11/imm32/alloc-id:fake +31643 Single-lit-var/imm32/inouts +31644 0x11/imm32/alloc-id:fake +31645 Single-int-var-in-esi/imm32/outputs +31646 0x11/imm32/alloc-id:fake +31647 _string_be_copy_to_esi/imm32/subx-name +31648 0/imm32/no-rm32 +31649 0/imm32/no-r32 +31650 1/imm32/imm32-is-first-inout +31651 0/imm32/no-imm8 +31652 0/imm32/no-disp32 +31653 0/imm32/no-xm32 +31654 0/imm32/no-x32 +31655 0x11/imm32/alloc-id:fake +31656 _Primitive-copy-to-edi/imm32/next +31657 _Primitive-copy-to-edi: # (payload primitive) +31658 0x11/imm32/alloc-id:fake:payload +31659 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 +31660 0x11/imm32/alloc-id:fake +31661 _string-copy/imm32/name +31662 0x11/imm32/alloc-id:fake +31663 Single-lit-var/imm32/inouts +31664 0x11/imm32/alloc-id:fake +31665 Single-int-var-in-edi/imm32/outputs +31666 0x11/imm32/alloc-id:fake +31667 _string_bf_copy_to_edi/imm32/subx-name +31668 0/imm32/no-rm32 +31669 0/imm32/no-r32 +31670 1/imm32/imm32-is-first-inout +31671 0/imm32/no-imm8 +31672 0/imm32/no-disp32 +31673 0/imm32/no-xm32 +31674 0/imm32/no-x32 +31675 0x11/imm32/alloc-id:fake +31676 _Primitive-copy-reg-to-reg/imm32/next +31677 _Primitive-copy-reg-to-reg: # (payload primitive) +31678 0x11/imm32/alloc-id:fake:payload +31679 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 +31680 0x11/imm32/alloc-id:fake +31681 _string-copy/imm32/name +31682 0x11/imm32/alloc-id:fake +31683 Single-int-var-in-some-register/imm32/inouts +31684 0x11/imm32/alloc-id:fake +31685 Single-int-var-in-some-register/imm32/outputs +31686 0x11/imm32/alloc-id:fake +31687 _string_89_<-/imm32/subx-name +31688 3/imm32/rm32-is-first-output +31689 1/imm32/r32-is-first-inout +31690 0/imm32/no-imm32 +31691 0/imm32/no-imm8 +31692 0/imm32/no-disp32 +31693 0/imm32/no-xm32 +31694 0/imm32/no-x32 +31695 0x11/imm32/alloc-id:fake +31696 _Primitive-copy-reg-to-mem/imm32/next +31697 _Primitive-copy-reg-to-mem: # (payload primitive) +31698 0x11/imm32/alloc-id:fake:payload +31699 # copy-to var1 var2/reg => 89/<- var1 var2/r32 +31700 0x11/imm32/alloc-id:fake +31701 _string-copy-to/imm32/name +31702 0x11/imm32/alloc-id:fake +31703 Two-args-int-stack-int-reg/imm32/inouts +31704 0/imm32/no-outputs +31705 0/imm32/no-outputs +31706 0x11/imm32/alloc-id:fake +31707 _string_89_<-/imm32/subx-name +31708 1/imm32/rm32-is-first-inout +31709 2/imm32/r32-is-second-inout +31710 0/imm32/no-imm32 +31711 0/imm32/no-imm8 +31712 0/imm32/no-disp32 +31713 0/imm32/no-xm32 +31714 0/imm32/no-x32 +31715 0x11/imm32/alloc-id:fake +31716 _Primitive-copy-mem-to-reg/imm32/next +31717 _Primitive-copy-mem-to-reg: # (payload primitive) +31718 0x11/imm32/alloc-id:fake:payload +31719 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 +31720 0x11/imm32/alloc-id:fake +31721 _string-copy/imm32/name +31722 0x11/imm32/alloc-id:fake +31723 Single-int-var-in-mem/imm32/inouts +31724 0x11/imm32/alloc-id:fake +31725 Single-int-var-in-some-register/imm32/outputs +31726 0x11/imm32/alloc-id:fake +31727 _string_8b_->/imm32/subx-name +31728 1/imm32/rm32-is-first-inout +31729 3/imm32/r32-is-first-output +31730 0/imm32/no-imm32 +31731 0/imm32/no-imm8 +31732 0/imm32/no-disp32 +31733 0/imm32/no-xm32 +31734 0/imm32/no-x32 +31735 0x11/imm32/alloc-id:fake +31736 _Primitive-copy-lit-to-reg/imm32/next +31737 _Primitive-copy-lit-to-reg: # (payload primitive) +31738 0x11/imm32/alloc-id:fake:payload +31739 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 +31740 0x11/imm32/alloc-id:fake +31741 _string-copy/imm32/name +31742 0x11/imm32/alloc-id:fake +31743 Single-lit-var/imm32/inouts +31744 0x11/imm32/alloc-id:fake +31745 Single-int-var-in-some-register/imm32/outputs +31746 0x11/imm32/alloc-id:fake +31747 _string_c7_subop_copy/imm32/subx-name +31748 3/imm32/rm32-is-first-output +31749 0/imm32/no-r32 +31750 1/imm32/imm32-is-first-inout +31751 0/imm32/no-imm8 +31752 0/imm32/no-disp32 +31753 0/imm32/no-xm32 +31754 0/imm32/no-x32 +31755 0x11/imm32/alloc-id:fake +31756 _Primitive-copy-lit-to-mem/imm32/next +31757 _Primitive-copy-lit-to-mem: # (payload primitive) +31758 0x11/imm32/alloc-id:fake:payload +31759 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 +31760 0x11/imm32/alloc-id:fake +31761 _string-copy-to/imm32/name 31762 0x11/imm32/alloc-id:fake -31763 _string-copy-byte/imm32/name -31764 0x11/imm32/alloc-id:fake -31765 Single-byte-var-in-some-register/imm32/inouts +31763 Int-var-and-literal/imm32/inouts +31764 0/imm32/no-outputs +31765 0/imm32/no-outputs 31766 0x11/imm32/alloc-id:fake -31767 Single-byte-var-in-some-register/imm32/outputs -31768 0x11/imm32/alloc-id:fake -31769 _string_8a_copy_byte/imm32/subx-name -31770 1/imm32/rm32-is-first-inout -31771 3/imm32/r32-is-first-output -31772 0/imm32/no-imm32 -31773 0/imm32/no-imm8 -31774 0/imm32/no-disp32 -31775 0/imm32/no-xm32 -31776 0/imm32/no-x32 -31777 0x11/imm32/alloc-id:fake -31778 _Primitive-copy-byte-from-mem/imm32/next -31779 _Primitive-copy-byte-from-mem: -31780 0x11/imm32/alloc-id:fake:payload -31781 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32 -31782 0x11/imm32/alloc-id:fake -31783 _string-copy-byte/imm32/name -31784 0x11/imm32/alloc-id:fake -31785 Single-byte-var-in-mem/imm32/inouts -31786 0x11/imm32/alloc-id:fake -31787 Single-byte-var-in-some-register/imm32/outputs -31788 0x11/imm32/alloc-id:fake -31789 _string_8a_copy_byte/imm32/subx-name -31790 1/imm32/rm32-is-first-inout -31791 3/imm32/r32-is-first-output -31792 0/imm32/no-imm32 -31793 0/imm32/no-imm8 -31794 0/imm32/no-disp32 -31795 0/imm32/no-xm32 -31796 0/imm32/no-x32 -31797 0x11/imm32/alloc-id:fake -31798 _Primitive-copy-byte-to-mem/imm32/next -31799 _Primitive-copy-byte-to-mem: -31800 0x11/imm32/alloc-id:fake:payload -31801 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32 -31802 0x11/imm32/alloc-id:fake -31803 _string-copy-byte-to/imm32/name -31804 0x11/imm32/alloc-id:fake -31805 Two-args-byte-stack-byte-reg/imm32/inouts -31806 0/imm32/no-outputs -31807 0/imm32/no-outputs -31808 0x11/imm32/alloc-id:fake -31809 _string_88_copy_byte/imm32/subx-name -31810 1/imm32/rm32-is-first-inout -31811 2/imm32/r32-is-second-inout -31812 0/imm32/no-imm32 -31813 0/imm32/no-imm8 -31814 0/imm32/no-disp32 -31815 0/imm32/no-xm32 -31816 0/imm32/no-x32 -31817 0x11/imm32/alloc-id:fake -31818 _Primitive-address/imm32/next -31819 # - address -31820 _Primitive-address: # (payload primitive) -31821 0x11/imm32/alloc-id:fake:payload -31822 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 +31767 _string_c7_subop_copy/imm32/subx-name +31768 1/imm32/rm32-is-first-inout +31769 0/imm32/no-r32 +31770 2/imm32/imm32-is-second-inout +31771 0/imm32/no-imm8 +31772 0/imm32/no-disp32 +31773 0/imm32/no-xm32 +31774 0/imm32/no-x32 +31775 0x11/imm32/alloc-id:fake +31776 _Primitive-copy-byte-from-reg/imm32/next +31777 # - copy byte +31778 _Primitive-copy-byte-from-reg: +31779 0x11/imm32/alloc-id:fake:payload +31780 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32 +31781 0x11/imm32/alloc-id:fake +31782 _string-copy-byte/imm32/name +31783 0x11/imm32/alloc-id:fake +31784 Single-byte-var-in-some-register/imm32/inouts +31785 0x11/imm32/alloc-id:fake +31786 Single-byte-var-in-some-register/imm32/outputs +31787 0x11/imm32/alloc-id:fake +31788 _string_8a_copy_byte/imm32/subx-name +31789 1/imm32/rm32-is-first-inout +31790 3/imm32/r32-is-first-output +31791 0/imm32/no-imm32 +31792 0/imm32/no-imm8 +31793 0/imm32/no-disp32 +31794 0/imm32/no-xm32 +31795 0/imm32/no-x32 +31796 0x11/imm32/alloc-id:fake +31797 _Primitive-copy-byte-from-mem/imm32/next +31798 _Primitive-copy-byte-from-mem: +31799 0x11/imm32/alloc-id:fake:payload +31800 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32 +31801 0x11/imm32/alloc-id:fake +31802 _string-copy-byte/imm32/name +31803 0x11/imm32/alloc-id:fake +31804 Single-byte-var-in-mem/imm32/inouts +31805 0x11/imm32/alloc-id:fake +31806 Single-byte-var-in-some-register/imm32/outputs +31807 0x11/imm32/alloc-id:fake +31808 _string_8a_copy_byte/imm32/subx-name +31809 1/imm32/rm32-is-first-inout +31810 3/imm32/r32-is-first-output +31811 0/imm32/no-imm32 +31812 0/imm32/no-imm8 +31813 0/imm32/no-disp32 +31814 0/imm32/no-xm32 +31815 0/imm32/no-x32 +31816 0x11/imm32/alloc-id:fake +31817 _Primitive-copy-byte-to-mem/imm32/next +31818 _Primitive-copy-byte-to-mem: +31819 0x11/imm32/alloc-id:fake:payload +31820 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32 +31821 0x11/imm32/alloc-id:fake +31822 _string-copy-byte-to/imm32/name 31823 0x11/imm32/alloc-id:fake -31824 _string-address/imm32/name -31825 0x11/imm32/alloc-id:fake -31826 Single-int-var-in-mem/imm32/inouts +31824 Two-args-byte-stack-byte-reg/imm32/inouts +31825 0/imm32/no-outputs +31826 0/imm32/no-outputs 31827 0x11/imm32/alloc-id:fake -31828 Single-addr-var-in-some-register/imm32/outputs -31829 0x11/imm32/alloc-id:fake -31830 _string_8d_copy_address/imm32/subx-name -31831 1/imm32/rm32-is-first-inout -31832 3/imm32/r32-is-first-output -31833 0/imm32/no-imm32 -31834 0/imm32/no-imm8 -31835 0/imm32/no-disp32 -31836 0/imm32/no-xm32 -31837 0/imm32/no-x32 -31838 0x11/imm32/alloc-id:fake -31839 _Primitive-compare-reg-with-reg/imm32/next -31840 # - compare -31841 _Primitive-compare-reg-with-reg: # (payload primitive) -31842 0x11/imm32/alloc-id:fake:payload -31843 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 +31828 _string_88_copy_byte/imm32/subx-name +31829 1/imm32/rm32-is-first-inout +31830 2/imm32/r32-is-second-inout +31831 0/imm32/no-imm32 +31832 0/imm32/no-imm8 +31833 0/imm32/no-disp32 +31834 0/imm32/no-xm32 +31835 0/imm32/no-x32 +31836 0x11/imm32/alloc-id:fake +31837 _Primitive-address/imm32/next +31838 # - address +31839 _Primitive-address: # (payload primitive) +31840 0x11/imm32/alloc-id:fake:payload +31841 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 +31842 0x11/imm32/alloc-id:fake +31843 _string-address/imm32/name 31844 0x11/imm32/alloc-id:fake -31845 _string-compare/imm32/name +31845 Single-int-var-in-mem/imm32/inouts 31846 0x11/imm32/alloc-id:fake -31847 Two-int-args-in-regs/imm32/inouts -31848 0/imm32/no-outputs -31849 0/imm32/no-outputs -31850 0x11/imm32/alloc-id:fake -31851 _string_39_compare->/imm32/subx-name -31852 1/imm32/rm32-is-first-inout -31853 2/imm32/r32-is-second-inout -31854 0/imm32/no-imm32 -31855 0/imm32/no-imm8 -31856 0/imm32/no-disp32 -31857 0/imm32/no-xm32 -31858 0/imm32/no-x32 -31859 0x11/imm32/alloc-id:fake -31860 _Primitive-compare-mem-with-reg/imm32/next -31861 _Primitive-compare-mem-with-reg: # (payload primitive) -31862 0x11/imm32/alloc-id:fake:payload -31863 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 -31864 0x11/imm32/alloc-id:fake -31865 _string-compare/imm32/name -31866 0x11/imm32/alloc-id:fake -31867 Two-args-int-stack-int-reg/imm32/inouts +31847 Single-addr-var-in-some-register/imm32/outputs +31848 0x11/imm32/alloc-id:fake +31849 _string_8d_copy_address/imm32/subx-name +31850 1/imm32/rm32-is-first-inout +31851 3/imm32/r32-is-first-output +31852 0/imm32/no-imm32 +31853 0/imm32/no-imm8 +31854 0/imm32/no-disp32 +31855 0/imm32/no-xm32 +31856 0/imm32/no-x32 +31857 0x11/imm32/alloc-id:fake +31858 _Primitive-compare-reg-with-reg/imm32/next +31859 # - compare +31860 _Primitive-compare-reg-with-reg: # (payload primitive) +31861 0x11/imm32/alloc-id:fake:payload +31862 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 +31863 0x11/imm32/alloc-id:fake +31864 _string-compare/imm32/name +31865 0x11/imm32/alloc-id:fake +31866 Two-int-args-in-regs/imm32/inouts +31867 0/imm32/no-outputs 31868 0/imm32/no-outputs -31869 0/imm32/no-outputs -31870 0x11/imm32/alloc-id:fake -31871 _string_39_compare->/imm32/subx-name -31872 1/imm32/rm32-is-first-inout -31873 2/imm32/r32-is-second-inout -31874 0/imm32/no-imm32 -31875 0/imm32/no-imm8 -31876 0/imm32/no-disp32 -31877 0/imm32/no-xm32 -31878 0/imm32/no-x32 -31879 0x11/imm32/alloc-id:fake -31880 _Primitive-compare-reg-with-mem/imm32/next -31881 _Primitive-compare-reg-with-mem: # (payload primitive) -31882 0x11/imm32/alloc-id:fake:payload -31883 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 -31884 0x11/imm32/alloc-id:fake -31885 _string-compare/imm32/name -31886 0x11/imm32/alloc-id:fake -31887 Two-args-int-reg-int-stack/imm32/inouts +31869 0x11/imm32/alloc-id:fake +31870 _string_39_compare->/imm32/subx-name +31871 1/imm32/rm32-is-first-inout +31872 2/imm32/r32-is-second-inout +31873 0/imm32/no-imm32 +31874 0/imm32/no-imm8 +31875 0/imm32/no-disp32 +31876 0/imm32/no-xm32 +31877 0/imm32/no-x32 +31878 0x11/imm32/alloc-id:fake +31879 _Primitive-compare-mem-with-reg/imm32/next +31880 _Primitive-compare-mem-with-reg: # (payload primitive) +31881 0x11/imm32/alloc-id:fake:payload +31882 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 +31883 0x11/imm32/alloc-id:fake +31884 _string-compare/imm32/name +31885 0x11/imm32/alloc-id:fake +31886 Two-args-int-stack-int-reg/imm32/inouts +31887 0/imm32/no-outputs 31888 0/imm32/no-outputs -31889 0/imm32/no-outputs -31890 0x11/imm32/alloc-id:fake -31891 _string_3b_compare<-/imm32/subx-name -31892 2/imm32/rm32-is-second-inout -31893 1/imm32/r32-is-first-inout -31894 0/imm32/no-imm32 -31895 0/imm32/no-imm8 -31896 0/imm32/no-disp32 -31897 0/imm32/no-xm32 -31898 0/imm32/no-x32 -31899 0x11/imm32/alloc-id:fake -31900 _Primitive-compare-eax-with-literal/imm32/next -31901 _Primitive-compare-eax-with-literal: # (payload primitive) -31902 0x11/imm32/alloc-id:fake:payload -31903 # compare var1/eax n => 3d/compare-eax-with n/imm32 -31904 0x11/imm32/alloc-id:fake -31905 _string-compare/imm32/name -31906 0x11/imm32/alloc-id:fake -31907 Two-args-int-eax-int-literal/imm32/inouts +31889 0x11/imm32/alloc-id:fake +31890 _string_39_compare->/imm32/subx-name +31891 1/imm32/rm32-is-first-inout +31892 2/imm32/r32-is-second-inout +31893 0/imm32/no-imm32 +31894 0/imm32/no-imm8 +31895 0/imm32/no-disp32 +31896 0/imm32/no-xm32 +31897 0/imm32/no-x32 +31898 0x11/imm32/alloc-id:fake +31899 _Primitive-compare-reg-with-mem/imm32/next +31900 _Primitive-compare-reg-with-mem: # (payload primitive) +31901 0x11/imm32/alloc-id:fake:payload +31902 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 +31903 0x11/imm32/alloc-id:fake +31904 _string-compare/imm32/name +31905 0x11/imm32/alloc-id:fake +31906 Two-args-int-reg-int-stack/imm32/inouts +31907 0/imm32/no-outputs 31908 0/imm32/no-outputs -31909 0/imm32/no-outputs -31910 0x11/imm32/alloc-id:fake -31911 _string_3d_compare_eax_with/imm32/subx-name -31912 0/imm32/no-rm32 -31913 0/imm32/no-r32 -31914 2/imm32/imm32-is-second-inout -31915 0/imm32/no-imm8 -31916 0/imm32/no-disp32 -31917 0/imm32/no-xm32 -31918 0/imm32/no-x32 -31919 0x11/imm32/alloc-id:fake -31920 _Primitive-compare-reg-with-literal/imm32/next -31921 _Primitive-compare-reg-with-literal: # (payload primitive) -31922 0x11/imm32/alloc-id:fake:payload -31923 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 -31924 0x11/imm32/alloc-id:fake -31925 _string-compare/imm32/name -31926 0x11/imm32/alloc-id:fake -31927 Int-var-in-register-and-literal/imm32/inouts +31909 0x11/imm32/alloc-id:fake +31910 _string_3b_compare<-/imm32/subx-name +31911 2/imm32/rm32-is-second-inout +31912 1/imm32/r32-is-first-inout +31913 0/imm32/no-imm32 +31914 0/imm32/no-imm8 +31915 0/imm32/no-disp32 +31916 0/imm32/no-xm32 +31917 0/imm32/no-x32 +31918 0x11/imm32/alloc-id:fake +31919 _Primitive-compare-eax-with-literal/imm32/next +31920 _Primitive-compare-eax-with-literal: # (payload primitive) +31921 0x11/imm32/alloc-id:fake:payload +31922 # compare var1/eax n => 3d/compare-eax-with n/imm32 +31923 0x11/imm32/alloc-id:fake +31924 _string-compare/imm32/name +31925 0x11/imm32/alloc-id:fake +31926 Two-args-int-eax-int-literal/imm32/inouts +31927 0/imm32/no-outputs 31928 0/imm32/no-outputs -31929 0/imm32/no-outputs -31930 0x11/imm32/alloc-id:fake -31931 _string_81_subop_compare/imm32/subx-name -31932 1/imm32/rm32-is-first-inout -31933 0/imm32/no-r32 -31934 2/imm32/imm32-is-second-inout -31935 0/imm32/no-imm8 -31936 0/imm32/no-disp32 -31937 0/imm32/no-xm32 -31938 0/imm32/no-x32 -31939 0x11/imm32/alloc-id:fake -31940 _Primitive-compare-mem-with-literal/imm32/next -31941 _Primitive-compare-mem-with-literal: # (payload primitive) -31942 0x11/imm32/alloc-id:fake:payload -31943 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 -31944 0x11/imm32/alloc-id:fake -31945 _string-compare/imm32/name -31946 0x11/imm32/alloc-id:fake -31947 Int-var-and-literal/imm32/inouts +31929 0x11/imm32/alloc-id:fake +31930 _string_3d_compare_eax_with/imm32/subx-name +31931 0/imm32/no-rm32 +31932 0/imm32/no-r32 +31933 2/imm32/imm32-is-second-inout +31934 0/imm32/no-imm8 +31935 0/imm32/no-disp32 +31936 0/imm32/no-xm32 +31937 0/imm32/no-x32 +31938 0x11/imm32/alloc-id:fake +31939 _Primitive-compare-reg-with-literal/imm32/next +31940 _Primitive-compare-reg-with-literal: # (payload primitive) +31941 0x11/imm32/alloc-id:fake:payload +31942 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 +31943 0x11/imm32/alloc-id:fake +31944 _string-compare/imm32/name +31945 0x11/imm32/alloc-id:fake +31946 Int-var-in-register-and-literal/imm32/inouts +31947 0/imm32/no-outputs 31948 0/imm32/no-outputs -31949 0/imm32/no-outputs -31950 0x11/imm32/alloc-id:fake -31951 _string_81_subop_compare/imm32/subx-name -31952 1/imm32/rm32-is-first-inout -31953 0/imm32/no-r32 -31954 2/imm32/imm32-is-second-inout -31955 0/imm32/no-imm8 -31956 0/imm32/no-disp32 -31957 0/imm32/no-xm32 -31958 0/imm32/no-x32 -31959 0x11/imm32/alloc-id:fake -31960 _Primitive-negate-reg/imm32/next -31961 # - negate -31962 _Primitive-negate-reg: # (payload primitive) -31963 0x11/imm32/alloc-id:fake:payload -31964 # var1/reg <- negate => f7 3/subop/negate var1/rm32 +31949 0x11/imm32/alloc-id:fake +31950 _string_81_subop_compare/imm32/subx-name +31951 1/imm32/rm32-is-first-inout +31952 0/imm32/no-r32 +31953 2/imm32/imm32-is-second-inout +31954 0/imm32/no-imm8 +31955 0/imm32/no-disp32 +31956 0/imm32/no-xm32 +31957 0/imm32/no-x32 +31958 0x11/imm32/alloc-id:fake +31959 _Primitive-compare-mem-with-literal/imm32/next +31960 _Primitive-compare-mem-with-literal: # (payload primitive) +31961 0x11/imm32/alloc-id:fake:payload +31962 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 +31963 0x11/imm32/alloc-id:fake +31964 _string-compare/imm32/name 31965 0x11/imm32/alloc-id:fake -31966 _string-negate/imm32/name -31967 0/imm32/no-inouts -31968 0/imm32/no-inouts +31966 Int-var-and-literal/imm32/inouts +31967 0/imm32/no-outputs +31968 0/imm32/no-outputs 31969 0x11/imm32/alloc-id:fake -31970 Single-int-var-in-some-register/imm32/outputs -31971 0x11/imm32/alloc-id:fake -31972 _string_f7_subop_negate/imm32/subx-name -31973 3/imm32/rm32-is-first-output -31974 0/imm32/no-r32 -31975 0/imm32/no-imm32 -31976 0/imm32/no-imm8 -31977 0/imm32/no-disp32 -31978 0/imm32/no-xm32 -31979 0/imm32/no-x32 -31980 0x11/imm32/alloc-id:fake -31981 _Primitive-negate-mem/imm32/next -31982 _Primitive-negate-mem: # (payload primitive) -31983 0x11/imm32/alloc-id:fake:payload -31984 # negate var1 => f7 3/subop/negate var1/rm32 -31985 0x11/imm32/alloc-id:fake -31986 _string-negate/imm32/name -31987 0x11/imm32/alloc-id:fake -31988 Single-int-var-in-mem/imm32/inouts -31989 0/imm32/no-outputs -31990 0/imm32/no-outputs -31991 0x11/imm32/alloc-id:fake -31992 _string_f7_subop_negate/imm32/subx-name -31993 1/imm32/rm32-is-first-inout -31994 0/imm32/no-r32 -31995 0/imm32/no-imm32 -31996 0/imm32/no-imm8 -31997 0/imm32/no-disp32 -31998 0/imm32/no-xm32 -31999 0/imm32/no-x32 -32000 0x11/imm32/alloc-id:fake -32001 _Primitive-multiply-reg-by-reg/imm32/next -32002 # - multiply -32003 _Primitive-multiply-reg-by-reg: # (payload primitive) -32004 0x11/imm32/alloc-id:fake:payload -32005 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +31970 _string_81_subop_compare/imm32/subx-name +31971 1/imm32/rm32-is-first-inout +31972 0/imm32/no-r32 +31973 2/imm32/imm32-is-second-inout +31974 0/imm32/no-imm8 +31975 0/imm32/no-disp32 +31976 0/imm32/no-xm32 +31977 0/imm32/no-x32 +31978 0x11/imm32/alloc-id:fake +31979 _Primitive-negate-reg/imm32/next +31980 # - negate +31981 _Primitive-negate-reg: # (payload primitive) +31982 0x11/imm32/alloc-id:fake:payload +31983 # var1/reg <- negate => f7 3/subop/negate var1/rm32 +31984 0x11/imm32/alloc-id:fake +31985 _string-negate/imm32/name +31986 0/imm32/no-inouts +31987 0/imm32/no-inouts +31988 0x11/imm32/alloc-id:fake +31989 Single-int-var-in-some-register/imm32/outputs +31990 0x11/imm32/alloc-id:fake +31991 _string_f7_subop_negate/imm32/subx-name +31992 3/imm32/rm32-is-first-output +31993 0/imm32/no-r32 +31994 0/imm32/no-imm32 +31995 0/imm32/no-imm8 +31996 0/imm32/no-disp32 +31997 0/imm32/no-xm32 +31998 0/imm32/no-x32 +31999 0x11/imm32/alloc-id:fake +32000 _Primitive-negate-mem/imm32/next +32001 _Primitive-negate-mem: # (payload primitive) +32002 0x11/imm32/alloc-id:fake:payload +32003 # negate var1 => f7 3/subop/negate var1/rm32 +32004 0x11/imm32/alloc-id:fake +32005 _string-negate/imm32/name 32006 0x11/imm32/alloc-id:fake -32007 _string-multiply/imm32/name -32008 0x11/imm32/alloc-id:fake -32009 Single-int-var-in-some-register/imm32/inouts +32007 Single-int-var-in-mem/imm32/inouts +32008 0/imm32/no-outputs +32009 0/imm32/no-outputs 32010 0x11/imm32/alloc-id:fake -32011 Single-int-var-in-some-register/imm32/outputs -32012 0x11/imm32/alloc-id:fake -32013 _string_0f_af_multiply/imm32/subx-name -32014 1/imm32/rm32-is-first-inout -32015 3/imm32/r32-is-first-output -32016 0/imm32/no-imm32 -32017 0/imm32/no-imm8 -32018 0/imm32/no-disp32 -32019 0/imm32/no-xm32 -32020 0/imm32/no-x32 -32021 0x11/imm32/alloc-id:fake -32022 _Primitive-multiply-reg-by-mem/imm32/next -32023 _Primitive-multiply-reg-by-mem: # (payload primitive) -32024 0x11/imm32/alloc-id:fake:payload -32025 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -32026 0x11/imm32/alloc-id:fake -32027 _string-multiply/imm32/name -32028 0x11/imm32/alloc-id:fake -32029 Single-int-var-in-mem/imm32/inouts -32030 0x11/imm32/alloc-id:fake -32031 Single-int-var-in-some-register/imm32/outputs -32032 0x11/imm32/alloc-id:fake -32033 _string_0f_af_multiply/imm32/subx-name -32034 1/imm32/rm32-is-first-inout -32035 3/imm32/r32-is-first-output -32036 0/imm32/no-imm32 -32037 0/imm32/no-imm8 -32038 0/imm32/no-disp32 -32039 0/imm32/no-xm32 -32040 0/imm32/no-x32 -32041 0x11/imm32/alloc-id:fake -32042 _Primitive-convert-mem-to-xreg/imm32/next -32043 # - convert int to floating point -32044 _Primitive-convert-mem-to-xreg: # (payload primitive) -32045 0x11/imm32/alloc-id:fake:payload -32046 # var1/xreg <- convert var2 => f3 0f 2a/convert-to-float var2/rm32 var1/x32 +32011 _string_f7_subop_negate/imm32/subx-name +32012 1/imm32/rm32-is-first-inout +32013 0/imm32/no-r32 +32014 0/imm32/no-imm32 +32015 0/imm32/no-imm8 +32016 0/imm32/no-disp32 +32017 0/imm32/no-xm32 +32018 0/imm32/no-x32 +32019 0x11/imm32/alloc-id:fake +32020 _Primitive-multiply-reg-by-reg/imm32/next +32021 # - multiply +32022 _Primitive-multiply-reg-by-reg: # (payload primitive) +32023 0x11/imm32/alloc-id:fake:payload +32024 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +32025 0x11/imm32/alloc-id:fake +32026 _string-multiply/imm32/name +32027 0x11/imm32/alloc-id:fake +32028 Single-int-var-in-some-register/imm32/inouts +32029 0x11/imm32/alloc-id:fake +32030 Single-int-var-in-some-register/imm32/outputs +32031 0x11/imm32/alloc-id:fake +32032 _string_0f_af_multiply/imm32/subx-name +32033 1/imm32/rm32-is-first-inout +32034 3/imm32/r32-is-first-output +32035 0/imm32/no-imm32 +32036 0/imm32/no-imm8 +32037 0/imm32/no-disp32 +32038 0/imm32/no-xm32 +32039 0/imm32/no-x32 +32040 0x11/imm32/alloc-id:fake +32041 _Primitive-multiply-reg-by-mem/imm32/next +32042 _Primitive-multiply-reg-by-mem: # (payload primitive) +32043 0x11/imm32/alloc-id:fake:payload +32044 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +32045 0x11/imm32/alloc-id:fake +32046 _string-multiply/imm32/name 32047 0x11/imm32/alloc-id:fake -32048 _string-convert/imm32/name +32048 Single-int-var-in-mem/imm32/inouts 32049 0x11/imm32/alloc-id:fake -32050 Single-int-var-in-mem/imm32/inouts +32050 Single-int-var-in-some-register/imm32/outputs 32051 0x11/imm32/alloc-id:fake -32052 Single-float-var-in-some-register/imm32/outputs -32053 0x11/imm32/alloc-id:fake -32054 _string_f3_0f_2a_convert_to_float/imm32/subx-name -32055 1/imm32/rm32-is-first-inout -32056 0/imm32/no-r32 -32057 0/imm32/no-imm32 -32058 0/imm32/no-imm8 -32059 0/imm32/no-disp32 -32060 0/imm32/no-xm32 -32061 3/imm32/x32-is-first-output -32062 0x11/imm32/alloc-id:fake -32063 _Primitive-convert-reg-to-xreg/imm32/next -32064 _Primitive-convert-reg-to-xreg: # (payload primitive) -32065 0x11/imm32/alloc-id:fake:payload -32066 # var1/xreg <- convert var2/reg => f3 0f 2a/convert-to-float var2/rm32 var1/x32 -32067 0x11/imm32/alloc-id:fake -32068 _string-convert/imm32/name -32069 0x11/imm32/alloc-id:fake -32070 Single-int-var-in-some-register/imm32/inouts -32071 0x11/imm32/alloc-id:fake -32072 Single-float-var-in-some-register/imm32/outputs -32073 0x11/imm32/alloc-id:fake -32074 _string_f3_0f_2a_convert_to_float/imm32/subx-name -32075 1/imm32/rm32-is-first-inout -32076 0/imm32/no-r32 -32077 0/imm32/no-imm32 -32078 0/imm32/no-imm8 -32079 0/imm32/no-disp32 -32080 0/imm32/no-xm32 -32081 3/imm32/x32-is-first-output -32082 0x11/imm32/alloc-id:fake -32083 _Primitive-convert-xmem-to-reg/imm32/next -32084 # - convert floating point to int -32085 _Primitive-convert-xmem-to-reg: # (payload primitive) -32086 0x11/imm32/alloc-id:fake:payload -32087 # var1/reg <- convert var2 => f3 0f 2d/convert-to-int var2/xm32 var1/r32 +32052 _string_0f_af_multiply/imm32/subx-name +32053 1/imm32/rm32-is-first-inout +32054 3/imm32/r32-is-first-output +32055 0/imm32/no-imm32 +32056 0/imm32/no-imm8 +32057 0/imm32/no-disp32 +32058 0/imm32/no-xm32 +32059 0/imm32/no-x32 +32060 0x11/imm32/alloc-id:fake +32061 _Primitive-convert-mem-to-xreg/imm32/next +32062 # - convert int to floating point +32063 _Primitive-convert-mem-to-xreg: # (payload primitive) +32064 0x11/imm32/alloc-id:fake:payload +32065 # var1/xreg <- convert var2 => f3 0f 2a/convert-to-float var2/rm32 var1/x32 +32066 0x11/imm32/alloc-id:fake +32067 _string-convert/imm32/name +32068 0x11/imm32/alloc-id:fake +32069 Single-int-var-in-mem/imm32/inouts +32070 0x11/imm32/alloc-id:fake +32071 Single-float-var-in-some-register/imm32/outputs +32072 0x11/imm32/alloc-id:fake +32073 _string_f3_0f_2a_convert_to_float/imm32/subx-name +32074 1/imm32/rm32-is-first-inout +32075 0/imm32/no-r32 +32076 0/imm32/no-imm32 +32077 0/imm32/no-imm8 +32078 0/imm32/no-disp32 +32079 0/imm32/no-xm32 +32080 3/imm32/x32-is-first-output +32081 0x11/imm32/alloc-id:fake +32082 _Primitive-convert-reg-to-xreg/imm32/next +32083 _Primitive-convert-reg-to-xreg: # (payload primitive) +32084 0x11/imm32/alloc-id:fake:payload +32085 # var1/xreg <- convert var2/reg => f3 0f 2a/convert-to-float var2/rm32 var1/x32 +32086 0x11/imm32/alloc-id:fake +32087 _string-convert/imm32/name 32088 0x11/imm32/alloc-id:fake -32089 _string-convert/imm32/name +32089 Single-int-var-in-some-register/imm32/inouts 32090 0x11/imm32/alloc-id:fake -32091 Single-float-var-in-mem/imm32/inouts +32091 Single-float-var-in-some-register/imm32/outputs 32092 0x11/imm32/alloc-id:fake -32093 Single-int-var-in-some-register/imm32/outputs -32094 0x11/imm32/alloc-id:fake -32095 _string_f3_0f_2d_convert_to_int/imm32/subx-name -32096 0/imm32/no-rm32 -32097 3/imm32/r32-is-first-output -32098 0/imm32/no-imm32 -32099 0/imm32/no-imm8 -32100 0/imm32/no-disp32 -32101 1/imm32/xm32-is-first-inout -32102 0/imm32/no-x32 -32103 0x11/imm32/alloc-id:fake -32104 _Primitive-convert-xreg-to-reg/imm32/next -32105 _Primitive-convert-xreg-to-reg: # (payload primitive) -32106 0x11/imm32/alloc-id:fake:payload -32107 # var1/reg <- convert var2/xreg => f3 0f 2d/convert-to-int var2/xm32 var1/r32 -32108 0x11/imm32/alloc-id:fake -32109 _string-convert/imm32/name -32110 0x11/imm32/alloc-id:fake -32111 Single-float-var-in-some-register/imm32/inouts -32112 0x11/imm32/alloc-id:fake -32113 Single-int-var-in-some-register/imm32/outputs -32114 0x11/imm32/alloc-id:fake -32115 _string_f3_0f_2d_convert_to_int/imm32/subx-name -32116 0/imm32/no-rm32 -32117 3/imm32/r32-is-first-output -32118 0/imm32/no-imm32 -32119 0/imm32/no-imm8 -32120 0/imm32/no-disp32 -32121 1/imm32/xm32-is-first-inout -32122 0/imm32/no-x32 -32123 0x11/imm32/alloc-id:fake -32124 _Primitive-truncate-xmem-to-reg/imm32/next -32125 _Primitive-truncate-xmem-to-reg: # (payload primitive) -32126 0x11/imm32/alloc-id:fake:payload -32127 # var1/reg <- truncate var2 => f3 0f 2c/truncate-to-int var2/xm32 var1/r32 -32128 0x11/imm32/alloc-id:fake -32129 _string-truncate/imm32/name -32130 0x11/imm32/alloc-id:fake -32131 Single-float-var-in-mem/imm32/inouts -32132 0x11/imm32/alloc-id:fake -32133 Single-int-var-in-some-register/imm32/outputs -32134 0x11/imm32/alloc-id:fake -32135 _string_f3_0f_2c_truncate_to_int/imm32/subx-name -32136 0/imm32/no-rm32 -32137 3/imm32/r32-is-first-output -32138 0/imm32/no-imm32 -32139 0/imm32/no-imm8 -32140 0/imm32/no-disp32 -32141 1/imm32/xm32-is-first-inout -32142 0/imm32/no-x32 -32143 0x11/imm32/alloc-id:fake -32144 _Primitive-truncate-xreg-to-reg/imm32/next -32145 _Primitive-truncate-xreg-to-reg: # (payload primitive) -32146 0x11/imm32/alloc-id:fake:payload -32147 # var1/reg <- truncate var2/xreg => f3 0f 2c/truncate-to-int var2/xm32 var1/r32 -32148 0x11/imm32/alloc-id:fake -32149 _string-truncate/imm32/name -32150 0x11/imm32/alloc-id:fake -32151 Single-float-var-in-some-register/imm32/inouts -32152 0x11/imm32/alloc-id:fake -32153 Single-int-var-in-some-register/imm32/outputs -32154 0x11/imm32/alloc-id:fake -32155 _string_f3_0f_2c_truncate_to_int/imm32/subx-name -32156 0/imm32/no-rm32 -32157 3/imm32/r32-is-first-output -32158 0/imm32/no-imm32 -32159 0/imm32/no-imm8 -32160 0/imm32/no-disp32 -32161 1/imm32/xm32-is-first-inout -32162 0/imm32/no-x32 -32163 0x11/imm32/alloc-id:fake -32164 _Primitive-reinterpret-xmem-as-reg/imm32/next -32165 # - reinterpret bytes (just for debugging) -32166 _Primitive-reinterpret-xmem-as-reg: # (payload primitive) -32167 0x11/imm32/alloc-id:fake:payload -32168 # var1/reg <- reinterpret var2 => 8b/-> var2/xm32 var1/r32 +32093 _string_f3_0f_2a_convert_to_float/imm32/subx-name +32094 1/imm32/rm32-is-first-inout +32095 0/imm32/no-r32 +32096 0/imm32/no-imm32 +32097 0/imm32/no-imm8 +32098 0/imm32/no-disp32 +32099 0/imm32/no-xm32 +32100 3/imm32/x32-is-first-output +32101 0x11/imm32/alloc-id:fake +32102 _Primitive-convert-xmem-to-reg/imm32/next +32103 # - convert floating point to int +32104 _Primitive-convert-xmem-to-reg: # (payload primitive) +32105 0x11/imm32/alloc-id:fake:payload +32106 # var1/reg <- convert var2 => f3 0f 2d/convert-to-int var2/xm32 var1/r32 +32107 0x11/imm32/alloc-id:fake +32108 _string-convert/imm32/name +32109 0x11/imm32/alloc-id:fake +32110 Single-float-var-in-mem/imm32/inouts +32111 0x11/imm32/alloc-id:fake +32112 Single-int-var-in-some-register/imm32/outputs +32113 0x11/imm32/alloc-id:fake +32114 _string_f3_0f_2d_convert_to_int/imm32/subx-name +32115 0/imm32/no-rm32 +32116 3/imm32/r32-is-first-output +32117 0/imm32/no-imm32 +32118 0/imm32/no-imm8 +32119 0/imm32/no-disp32 +32120 1/imm32/xm32-is-first-inout +32121 0/imm32/no-x32 +32122 0x11/imm32/alloc-id:fake +32123 _Primitive-convert-xreg-to-reg/imm32/next +32124 _Primitive-convert-xreg-to-reg: # (payload primitive) +32125 0x11/imm32/alloc-id:fake:payload +32126 # var1/reg <- convert var2/xreg => f3 0f 2d/convert-to-int var2/xm32 var1/r32 +32127 0x11/imm32/alloc-id:fake +32128 _string-convert/imm32/name +32129 0x11/imm32/alloc-id:fake +32130 Single-float-var-in-some-register/imm32/inouts +32131 0x11/imm32/alloc-id:fake +32132 Single-int-var-in-some-register/imm32/outputs +32133 0x11/imm32/alloc-id:fake +32134 _string_f3_0f_2d_convert_to_int/imm32/subx-name +32135 0/imm32/no-rm32 +32136 3/imm32/r32-is-first-output +32137 0/imm32/no-imm32 +32138 0/imm32/no-imm8 +32139 0/imm32/no-disp32 +32140 1/imm32/xm32-is-first-inout +32141 0/imm32/no-x32 +32142 0x11/imm32/alloc-id:fake +32143 _Primitive-truncate-xmem-to-reg/imm32/next +32144 _Primitive-truncate-xmem-to-reg: # (payload primitive) +32145 0x11/imm32/alloc-id:fake:payload +32146 # var1/reg <- truncate var2 => f3 0f 2c/truncate-to-int var2/xm32 var1/r32 +32147 0x11/imm32/alloc-id:fake +32148 _string-truncate/imm32/name +32149 0x11/imm32/alloc-id:fake +32150 Single-float-var-in-mem/imm32/inouts +32151 0x11/imm32/alloc-id:fake +32152 Single-int-var-in-some-register/imm32/outputs +32153 0x11/imm32/alloc-id:fake +32154 _string_f3_0f_2c_truncate_to_int/imm32/subx-name +32155 0/imm32/no-rm32 +32156 3/imm32/r32-is-first-output +32157 0/imm32/no-imm32 +32158 0/imm32/no-imm8 +32159 0/imm32/no-disp32 +32160 1/imm32/xm32-is-first-inout +32161 0/imm32/no-x32 +32162 0x11/imm32/alloc-id:fake +32163 _Primitive-truncate-xreg-to-reg/imm32/next +32164 _Primitive-truncate-xreg-to-reg: # (payload primitive) +32165 0x11/imm32/alloc-id:fake:payload +32166 # var1/reg <- truncate var2/xreg => f3 0f 2c/truncate-to-int var2/xm32 var1/r32 +32167 0x11/imm32/alloc-id:fake +32168 _string-truncate/imm32/name 32169 0x11/imm32/alloc-id:fake -32170 _string-reinterpret/imm32/name +32170 Single-float-var-in-some-register/imm32/inouts 32171 0x11/imm32/alloc-id:fake -32172 Single-float-var-in-mem/imm32/inouts +32172 Single-int-var-in-some-register/imm32/outputs 32173 0x11/imm32/alloc-id:fake -32174 Single-int-var-in-some-register/imm32/outputs -32175 0x11/imm32/alloc-id:fake -32176 _string_8b_->/imm32/subx-name -32177 0/imm32/no-rm32 -32178 3/imm32/r32-is-first-output -32179 0/imm32/no-imm32 -32180 0/imm32/no-imm8 -32181 0/imm32/no-disp32 -32182 1/imm32/xm32-is-first-inout -32183 0/imm32/no-x32 -32184 0x11/imm32/alloc-id:fake -32185 _Primitive-reinterpret-mem-as-xreg/imm32/next -32186 _Primitive-reinterpret-mem-as-xreg: # (payload primitive) -32187 0x11/imm32/alloc-id:fake:payload -32188 # var1/xreg <- reinterpret var2 => f3 0f 10/-> var2/rm32 var1/x32 -32189 0x11/imm32/alloc-id:fake -32190 _string-reinterpret/imm32/name -32191 0x11/imm32/alloc-id:fake -32192 Single-int-var-in-mem/imm32/inouts -32193 0x11/imm32/alloc-id:fake -32194 Single-float-var-in-some-register/imm32/outputs -32195 0x11/imm32/alloc-id:fake -32196 _string_f3_0f_10_copy/imm32/subx-name -32197 1/imm32/rm32-is-first-inout -32198 0/imm32/no-r32 -32199 0/imm32/no-imm32 -32200 0/imm32/no-imm8 -32201 0/imm32/no-disp32 -32202 0/imm32/no-xm32 -32203 3/imm32/x32-is-first-output -32204 0x11/imm32/alloc-id:fake -32205 _Primitive-copy-xreg-to-xreg/imm32/next -32206 # - floating-point copy -32207 _Primitive-copy-xreg-to-xreg: # (payload primitive) -32208 0x11/imm32/alloc-id:fake:payload -32209 # var1/xreg <- copy var2/xreg => f3 0f 11/<- var1/xm32 var2/x32 +32174 _string_f3_0f_2c_truncate_to_int/imm32/subx-name +32175 0/imm32/no-rm32 +32176 3/imm32/r32-is-first-output +32177 0/imm32/no-imm32 +32178 0/imm32/no-imm8 +32179 0/imm32/no-disp32 +32180 1/imm32/xm32-is-first-inout +32181 0/imm32/no-x32 +32182 0x11/imm32/alloc-id:fake +32183 _Primitive-reinterpret-xmem-as-reg/imm32/next +32184 # - reinterpret bytes (just for debugging) +32185 _Primitive-reinterpret-xmem-as-reg: # (payload primitive) +32186 0x11/imm32/alloc-id:fake:payload +32187 # var1/reg <- reinterpret var2 => 8b/-> var2/xm32 var1/r32 +32188 0x11/imm32/alloc-id:fake +32189 _string-reinterpret/imm32/name +32190 0x11/imm32/alloc-id:fake +32191 Single-float-var-in-mem/imm32/inouts +32192 0x11/imm32/alloc-id:fake +32193 Single-int-var-in-some-register/imm32/outputs +32194 0x11/imm32/alloc-id:fake +32195 _string_8b_->/imm32/subx-name +32196 0/imm32/no-rm32 +32197 3/imm32/r32-is-first-output +32198 0/imm32/no-imm32 +32199 0/imm32/no-imm8 +32200 0/imm32/no-disp32 +32201 1/imm32/xm32-is-first-inout +32202 0/imm32/no-x32 +32203 0x11/imm32/alloc-id:fake +32204 _Primitive-reinterpret-mem-as-xreg/imm32/next +32205 _Primitive-reinterpret-mem-as-xreg: # (payload primitive) +32206 0x11/imm32/alloc-id:fake:payload +32207 # var1/xreg <- reinterpret var2 => f3 0f 10/-> var2/rm32 var1/x32 +32208 0x11/imm32/alloc-id:fake +32209 _string-reinterpret/imm32/name 32210 0x11/imm32/alloc-id:fake -32211 _string-copy/imm32/name +32211 Single-int-var-in-mem/imm32/inouts 32212 0x11/imm32/alloc-id:fake -32213 Single-float-var-in-some-register/imm32/inouts +32213 Single-float-var-in-some-register/imm32/outputs 32214 0x11/imm32/alloc-id:fake -32215 Single-float-var-in-some-register/imm32/outputs -32216 0x11/imm32/alloc-id:fake -32217 _string_f3_0f_11_copy/imm32/subx-name -32218 0/imm32/no-rm32 -32219 0/imm32/no-r32 -32220 0/imm32/no-imm32 -32221 0/imm32/no-imm8 -32222 0/imm32/no-disp32 -32223 3/imm32/xm32-is-first-output -32224 1/imm32/x32-is-first-inout -32225 0x11/imm32/alloc-id:fake -32226 _Primitive-copy-xreg-to-mem/imm32/next -32227 _Primitive-copy-xreg-to-mem: # (payload primitive) -32228 0x11/imm32/alloc-id:fake:payload -32229 # copy-to var1 var2/xreg => f3 0f 11/<- var1 var2/x32 -32230 0x11/imm32/alloc-id:fake -32231 _string-copy-to/imm32/name -32232 0x11/imm32/alloc-id:fake -32233 Two-args-float-stack-float-reg/imm32/inouts -32234 0/imm32/no-outputs -32235 0/imm32/no-outputs -32236 0x11/imm32/alloc-id:fake -32237 _string_f3_0f_11_copy/imm32/subx-name -32238 0/imm32/no-rm32 -32239 0/imm32/no-r32 -32240 0/imm32/no-imm32 -32241 0/imm32/no-imm8 -32242 0/imm32/no-disp32 -32243 1/imm32/xm32-is-first-inout -32244 2/imm32/x32-is-second-inout -32245 0x11/imm32/alloc-id:fake -32246 _Primitive-copy-mem-to-xreg/imm32/next -32247 _Primitive-copy-mem-to-xreg: # (payload primitive) -32248 0x11/imm32/alloc-id:fake:payload -32249 # var1/xreg <- copy var2 => f3 0f 10/-> var2/rm32 var1/x32 -32250 0x11/imm32/alloc-id:fake -32251 _string-copy/imm32/name -32252 0x11/imm32/alloc-id:fake -32253 Single-float-var-in-mem/imm32/inouts -32254 0x11/imm32/alloc-id:fake -32255 Single-float-var-in-some-register/imm32/outputs -32256 0x11/imm32/alloc-id:fake -32257 _string_f3_0f_10_copy/imm32/subx-name -32258 0/imm32/no-rm32 -32259 0/imm32/no-r32 -32260 0/imm32/no-imm32 -32261 0/imm32/no-imm8 -32262 0/imm32/no-disp32 -32263 1/imm32/xm32-is-first-inout -32264 3/imm32/x32-is-first-output -32265 0x11/imm32/alloc-id:fake -32266 _Primitive-address-of-xmem/imm32/next -32267 # - floating-point-address -32268 _Primitive-address-of-xmem: # (payload primitive) -32269 0x11/imm32/alloc-id:fake:payload -32270 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 +32215 _string_f3_0f_10_copy/imm32/subx-name +32216 1/imm32/rm32-is-first-inout +32217 0/imm32/no-r32 +32218 0/imm32/no-imm32 +32219 0/imm32/no-imm8 +32220 0/imm32/no-disp32 +32221 0/imm32/no-xm32 +32222 3/imm32/x32-is-first-output +32223 0x11/imm32/alloc-id:fake +32224 _Primitive-copy-xreg-to-xreg/imm32/next +32225 # - floating-point copy +32226 _Primitive-copy-xreg-to-xreg: # (payload primitive) +32227 0x11/imm32/alloc-id:fake:payload +32228 # var1/xreg <- copy var2/xreg => f3 0f 11/<- var1/xm32 var2/x32 +32229 0x11/imm32/alloc-id:fake +32230 _string-copy/imm32/name +32231 0x11/imm32/alloc-id:fake +32232 Single-float-var-in-some-register/imm32/inouts +32233 0x11/imm32/alloc-id:fake +32234 Single-float-var-in-some-register/imm32/outputs +32235 0x11/imm32/alloc-id:fake +32236 _string_f3_0f_11_copy/imm32/subx-name +32237 0/imm32/no-rm32 +32238 0/imm32/no-r32 +32239 0/imm32/no-imm32 +32240 0/imm32/no-imm8 +32241 0/imm32/no-disp32 +32242 3/imm32/xm32-is-first-output +32243 1/imm32/x32-is-first-inout +32244 0x11/imm32/alloc-id:fake +32245 _Primitive-copy-xreg-to-mem/imm32/next +32246 _Primitive-copy-xreg-to-mem: # (payload primitive) +32247 0x11/imm32/alloc-id:fake:payload +32248 # copy-to var1 var2/xreg => f3 0f 11/<- var1 var2/x32 +32249 0x11/imm32/alloc-id:fake +32250 _string-copy-to/imm32/name +32251 0x11/imm32/alloc-id:fake +32252 Two-args-float-stack-float-reg/imm32/inouts +32253 0/imm32/no-outputs +32254 0/imm32/no-outputs +32255 0x11/imm32/alloc-id:fake +32256 _string_f3_0f_11_copy/imm32/subx-name +32257 0/imm32/no-rm32 +32258 0/imm32/no-r32 +32259 0/imm32/no-imm32 +32260 0/imm32/no-imm8 +32261 0/imm32/no-disp32 +32262 1/imm32/xm32-is-first-inout +32263 2/imm32/x32-is-second-inout +32264 0x11/imm32/alloc-id:fake +32265 _Primitive-copy-mem-to-xreg/imm32/next +32266 _Primitive-copy-mem-to-xreg: # (payload primitive) +32267 0x11/imm32/alloc-id:fake:payload +32268 # var1/xreg <- copy var2 => f3 0f 10/-> var2/rm32 var1/x32 +32269 0x11/imm32/alloc-id:fake +32270 _string-copy/imm32/name 32271 0x11/imm32/alloc-id:fake -32272 _string-address/imm32/name +32272 Single-float-var-in-mem/imm32/inouts 32273 0x11/imm32/alloc-id:fake -32274 Single-float-var-in-mem/imm32/inouts +32274 Single-float-var-in-some-register/imm32/outputs 32275 0x11/imm32/alloc-id:fake -32276 Single-addr-var-in-some-register/imm32/outputs -32277 0x11/imm32/alloc-id:fake -32278 _string_8d_copy_address/imm32/subx-name -32279 1/imm32/rm32-is-first-inout -32280 3/imm32/r32-is-first-output -32281 0/imm32/no-imm32 -32282 0/imm32/no-imm8 -32283 0/imm32/no-disp32 -32284 0/imm32/no-xm32 -32285 0/imm32/no-x32 -32286 0x11/imm32/alloc-id:fake -32287 _Primitive-add-xreg-to-xreg/imm32/next -32288 # - floating-point add -32289 _Primitive-add-xreg-to-xreg: # (payload primitive) -32290 0x11/imm32/alloc-id:fake:payload -32291 # var1/xreg <- add var2/xreg => f3 0f 58/add var1/xm32 var2/x32 +32276 _string_f3_0f_10_copy/imm32/subx-name +32277 0/imm32/no-rm32 +32278 0/imm32/no-r32 +32279 0/imm32/no-imm32 +32280 0/imm32/no-imm8 +32281 0/imm32/no-disp32 +32282 1/imm32/xm32-is-first-inout +32283 3/imm32/x32-is-first-output +32284 0x11/imm32/alloc-id:fake +32285 _Primitive-address-of-xmem/imm32/next +32286 # - floating-point-address +32287 _Primitive-address-of-xmem: # (payload primitive) +32288 0x11/imm32/alloc-id:fake:payload +32289 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 +32290 0x11/imm32/alloc-id:fake +32291 _string-address/imm32/name 32292 0x11/imm32/alloc-id:fake -32293 _string-add/imm32/name +32293 Single-float-var-in-mem/imm32/inouts 32294 0x11/imm32/alloc-id:fake -32295 Single-float-var-in-some-register/imm32/inouts +32295 Single-addr-var-in-some-register/imm32/outputs 32296 0x11/imm32/alloc-id:fake -32297 Single-float-var-in-some-register/imm32/outputs -32298 0x11/imm32/alloc-id:fake -32299 _string_f3_0f_58_add/imm32/subx-name -32300 0/imm32/no-rm32 -32301 0/imm32/no-r32 -32302 0/imm32/no-imm32 -32303 0/imm32/no-imm8 -32304 0/imm32/no-disp32 -32305 1/imm32/xm32-is-first-inout -32306 3/imm32/x32-is-first-output -32307 0x11/imm32/alloc-id:fake -32308 _Primitive-add-mem-to-xreg/imm32/next -32309 _Primitive-add-mem-to-xreg: # (payload primitive) -32310 0x11/imm32/alloc-id:fake:payload -32311 # var1/xreg <- add var2 => f3 0f 58/add var2/xm32 var1/x32 -32312 0x11/imm32/alloc-id:fake -32313 _string-add/imm32/name -32314 0x11/imm32/alloc-id:fake -32315 Single-float-var-in-mem/imm32/inouts -32316 0x11/imm32/alloc-id:fake -32317 Single-float-var-in-some-register/imm32/outputs -32318 0x11/imm32/alloc-id:fake -32319 _string_f3_0f_58_add/imm32/subx-name -32320 0/imm32/no-rm32 -32321 0/imm32/no-r32 -32322 0/imm32/no-imm32 -32323 0/imm32/no-imm8 -32324 0/imm32/no-disp32 -32325 1/imm32/xm32-is-first-inout -32326 3/imm32/x32-is-first-output -32327 0x11/imm32/alloc-id:fake -32328 _Primitive-subtract-xreg-from-xreg/imm32/next -32329 # - floating-point subtract -32330 _Primitive-subtract-xreg-from-xreg: # (payload primitive) -32331 0x11/imm32/alloc-id:fake:payload -32332 # var1/xreg <- subtract var2/xreg => f3 0f 5c/subtract var1/xm32 var2/x32 +32297 _string_8d_copy_address/imm32/subx-name +32298 1/imm32/rm32-is-first-inout +32299 3/imm32/r32-is-first-output +32300 0/imm32/no-imm32 +32301 0/imm32/no-imm8 +32302 0/imm32/no-disp32 +32303 0/imm32/no-xm32 +32304 0/imm32/no-x32 +32305 0x11/imm32/alloc-id:fake +32306 _Primitive-add-xreg-to-xreg/imm32/next +32307 # - floating-point add +32308 _Primitive-add-xreg-to-xreg: # (payload primitive) +32309 0x11/imm32/alloc-id:fake:payload +32310 # var1/xreg <- add var2/xreg => f3 0f 58/add var1/xm32 var2/x32 +32311 0x11/imm32/alloc-id:fake +32312 _string-add/imm32/name +32313 0x11/imm32/alloc-id:fake +32314 Single-float-var-in-some-register/imm32/inouts +32315 0x11/imm32/alloc-id:fake +32316 Single-float-var-in-some-register/imm32/outputs +32317 0x11/imm32/alloc-id:fake +32318 _string_f3_0f_58_add/imm32/subx-name +32319 0/imm32/no-rm32 +32320 0/imm32/no-r32 +32321 0/imm32/no-imm32 +32322 0/imm32/no-imm8 +32323 0/imm32/no-disp32 +32324 1/imm32/xm32-is-first-inout +32325 3/imm32/x32-is-first-output +32326 0x11/imm32/alloc-id:fake +32327 _Primitive-add-mem-to-xreg/imm32/next +32328 _Primitive-add-mem-to-xreg: # (payload primitive) +32329 0x11/imm32/alloc-id:fake:payload +32330 # var1/xreg <- add var2 => f3 0f 58/add var2/xm32 var1/x32 +32331 0x11/imm32/alloc-id:fake +32332 _string-add/imm32/name 32333 0x11/imm32/alloc-id:fake -32334 _string-subtract/imm32/name +32334 Single-float-var-in-mem/imm32/inouts 32335 0x11/imm32/alloc-id:fake -32336 Single-float-var-in-some-register/imm32/inouts +32336 Single-float-var-in-some-register/imm32/outputs 32337 0x11/imm32/alloc-id:fake -32338 Single-float-var-in-some-register/imm32/outputs -32339 0x11/imm32/alloc-id:fake -32340 _string_f3_0f_5c_subtract/imm32/subx-name -32341 0/imm32/no-rm32 -32342 0/imm32/no-r32 -32343 0/imm32/no-imm32 -32344 0/imm32/no-imm8 -32345 0/imm32/no-disp32 -32346 1/imm32/xm32-is-first-inout -32347 3/imm32/x32-is-first-output -32348 0x11/imm32/alloc-id:fake -32349 _Primitive-subtract-mem-from-xreg/imm32/next -32350 _Primitive-subtract-mem-from-xreg: # (payload primitive) -32351 0x11/imm32/alloc-id:fake:payload -32352 # var1/xreg <- subtract var2 => f3 0f 5c/subtract var2/xm32 var1/x32 -32353 0x11/imm32/alloc-id:fake -32354 _string-subtract/imm32/name -32355 0x11/imm32/alloc-id:fake -32356 Single-float-var-in-mem/imm32/inouts -32357 0x11/imm32/alloc-id:fake -32358 Single-float-var-in-some-register/imm32/outputs -32359 0x11/imm32/alloc-id:fake -32360 _string_f3_0f_5c_subtract/imm32/subx-name -32361 0/imm32/no-rm32 -32362 0/imm32/no-r32 -32363 0/imm32/no-imm32 -32364 0/imm32/no-imm8 -32365 0/imm32/no-disp32 -32366 1/imm32/xm32-is-first-inout -32367 3/imm32/x32-is-first-output -32368 0x11/imm32/alloc-id:fake -32369 _Primitive-multiply-xreg-by-xreg/imm32/next -32370 # - floating-point multiply -32371 _Primitive-multiply-xreg-by-xreg: # (payload primitive) -32372 0x11/imm32/alloc-id:fake:payload -32373 # var1/xreg <- multiply var2 => f3 0f 59/multiply var2/xm32 var1/x32 +32338 _string_f3_0f_58_add/imm32/subx-name +32339 0/imm32/no-rm32 +32340 0/imm32/no-r32 +32341 0/imm32/no-imm32 +32342 0/imm32/no-imm8 +32343 0/imm32/no-disp32 +32344 1/imm32/xm32-is-first-inout +32345 3/imm32/x32-is-first-output +32346 0x11/imm32/alloc-id:fake +32347 _Primitive-subtract-xreg-from-xreg/imm32/next +32348 # - floating-point subtract +32349 _Primitive-subtract-xreg-from-xreg: # (payload primitive) +32350 0x11/imm32/alloc-id:fake:payload +32351 # var1/xreg <- subtract var2/xreg => f3 0f 5c/subtract var1/xm32 var2/x32 +32352 0x11/imm32/alloc-id:fake +32353 _string-subtract/imm32/name +32354 0x11/imm32/alloc-id:fake +32355 Single-float-var-in-some-register/imm32/inouts +32356 0x11/imm32/alloc-id:fake +32357 Single-float-var-in-some-register/imm32/outputs +32358 0x11/imm32/alloc-id:fake +32359 _string_f3_0f_5c_subtract/imm32/subx-name +32360 0/imm32/no-rm32 +32361 0/imm32/no-r32 +32362 0/imm32/no-imm32 +32363 0/imm32/no-imm8 +32364 0/imm32/no-disp32 +32365 1/imm32/xm32-is-first-inout +32366 3/imm32/x32-is-first-output +32367 0x11/imm32/alloc-id:fake +32368 _Primitive-subtract-mem-from-xreg/imm32/next +32369 _Primitive-subtract-mem-from-xreg: # (payload primitive) +32370 0x11/imm32/alloc-id:fake:payload +32371 # var1/xreg <- subtract var2 => f3 0f 5c/subtract var2/xm32 var1/x32 +32372 0x11/imm32/alloc-id:fake +32373 _string-subtract/imm32/name 32374 0x11/imm32/alloc-id:fake -32375 _string-multiply/imm32/name +32375 Single-float-var-in-mem/imm32/inouts 32376 0x11/imm32/alloc-id:fake -32377 Single-float-var-in-some-register/imm32/inouts +32377 Single-float-var-in-some-register/imm32/outputs 32378 0x11/imm32/alloc-id:fake -32379 Single-float-var-in-some-register/imm32/outputs -32380 0x11/imm32/alloc-id:fake -32381 _string_f3_0f_59_multiply/imm32/subx-name -32382 0/imm32/no-rm32 -32383 0/imm32/no-r32 -32384 0/imm32/no-imm32 -32385 0/imm32/no-imm8 -32386 0/imm32/no-disp32 -32387 1/imm32/xm32-is-first-inout -32388 3/imm32/x32-is-first-output -32389 0x11/imm32/alloc-id:fake -32390 _Primitive-multiply-xreg-by-mem/imm32/next -32391 _Primitive-multiply-xreg-by-mem: # (payload primitive) -32392 0x11/imm32/alloc-id:fake:payload -32393 # var1/xreg <- multiply var2 => 53 0f 59/multiply var2/xm32 var1/x32 -32394 0x11/imm32/alloc-id:fake -32395 _string-multiply/imm32/name -32396 0x11/imm32/alloc-id:fake -32397 Single-float-var-in-mem/imm32/inouts -32398 0x11/imm32/alloc-id:fake -32399 Single-float-var-in-some-register/imm32/outputs -32400 0x11/imm32/alloc-id:fake -32401 _string_f3_0f_59_multiply/imm32/subx-name -32402 0/imm32/no-rm32 -32403 0/imm32/no-r32 -32404 0/imm32/no-imm32 -32405 0/imm32/no-imm8 -32406 0/imm32/no-disp32 -32407 1/imm32/xm32-is-first-inout -32408 3/imm32/x32-is-first-output -32409 0x11/imm32/alloc-id:fake -32410 _Primitive-divide-xreg-by-xreg/imm32/next -32411 # - floating-point divide -32412 _Primitive-divide-xreg-by-xreg: # (payload primitive) -32413 0x11/imm32/alloc-id:fake:payload -32414 # var1/xreg <- divide var2 => f3 0f 5e/divide var2/xm32 var1/x32 +32379 _string_f3_0f_5c_subtract/imm32/subx-name +32380 0/imm32/no-rm32 +32381 0/imm32/no-r32 +32382 0/imm32/no-imm32 +32383 0/imm32/no-imm8 +32384 0/imm32/no-disp32 +32385 1/imm32/xm32-is-first-inout +32386 3/imm32/x32-is-first-output +32387 0x11/imm32/alloc-id:fake +32388 _Primitive-multiply-xreg-by-xreg/imm32/next +32389 # - floating-point multiply +32390 _Primitive-multiply-xreg-by-xreg: # (payload primitive) +32391 0x11/imm32/alloc-id:fake:payload +32392 # var1/xreg <- multiply var2 => f3 0f 59/multiply var2/xm32 var1/x32 +32393 0x11/imm32/alloc-id:fake +32394 _string-multiply/imm32/name +32395 0x11/imm32/alloc-id:fake +32396 Single-float-var-in-some-register/imm32/inouts +32397 0x11/imm32/alloc-id:fake +32398 Single-float-var-in-some-register/imm32/outputs +32399 0x11/imm32/alloc-id:fake +32400 _string_f3_0f_59_multiply/imm32/subx-name +32401 0/imm32/no-rm32 +32402 0/imm32/no-r32 +32403 0/imm32/no-imm32 +32404 0/imm32/no-imm8 +32405 0/imm32/no-disp32 +32406 1/imm32/xm32-is-first-inout +32407 3/imm32/x32-is-first-output +32408 0x11/imm32/alloc-id:fake +32409 _Primitive-multiply-xreg-by-mem/imm32/next +32410 _Primitive-multiply-xreg-by-mem: # (payload primitive) +32411 0x11/imm32/alloc-id:fake:payload +32412 # var1/xreg <- multiply var2 => 53 0f 59/multiply var2/xm32 var1/x32 +32413 0x11/imm32/alloc-id:fake +32414 _string-multiply/imm32/name 32415 0x11/imm32/alloc-id:fake -32416 _string-divide/imm32/name +32416 Single-float-var-in-mem/imm32/inouts 32417 0x11/imm32/alloc-id:fake -32418 Single-float-var-in-some-register/imm32/inouts +32418 Single-float-var-in-some-register/imm32/outputs 32419 0x11/imm32/alloc-id:fake -32420 Single-float-var-in-some-register/imm32/outputs -32421 0x11/imm32/alloc-id:fake -32422 _string_f3_0f_5e_divide/imm32/subx-name -32423 0/imm32/no-rm32 -32424 0/imm32/no-r32 -32425 0/imm32/no-imm32 -32426 0/imm32/no-imm8 -32427 0/imm32/no-disp32 -32428 1/imm32/xm32-is-first-inout -32429 3/imm32/x32-is-first-output -32430 0x11/imm32/alloc-id:fake -32431 _Primitive-divide-xreg-by-mem/imm32/next -32432 _Primitive-divide-xreg-by-mem: # (payload primitive) -32433 0x11/imm32/alloc-id:fake:payload -32434 # var1/xreg <- divide var2 => f3 0f 5e/divide var2/xm32 var1/x32 -32435 0x11/imm32/alloc-id:fake -32436 _string-divide/imm32/name -32437 0x11/imm32/alloc-id:fake -32438 Single-float-var-in-mem/imm32/inouts -32439 0x11/imm32/alloc-id:fake -32440 Single-float-var-in-some-register/imm32/outputs -32441 0x11/imm32/alloc-id:fake -32442 _string_f3_0f_5e_divide/imm32/subx-name -32443 0/imm32/no-rm32 -32444 0/imm32/no-r32 -32445 0/imm32/no-imm32 -32446 0/imm32/no-imm8 -32447 0/imm32/no-disp32 -32448 1/imm32/xm32-is-first-inout -32449 3/imm32/x32-is-first-output -32450 0x11/imm32/alloc-id:fake -32451 _Primitive-max-xreg-with-xreg/imm32/next -32452 # - floating-point maximum -32453 _Primitive-max-xreg-with-xreg: # (payload primitive) -32454 0x11/imm32/alloc-id:fake:payload -32455 # var1/xreg <- max var2 => f3 0f 5f/max var2/xm32 var1/x32 +32420 _string_f3_0f_59_multiply/imm32/subx-name +32421 0/imm32/no-rm32 +32422 0/imm32/no-r32 +32423 0/imm32/no-imm32 +32424 0/imm32/no-imm8 +32425 0/imm32/no-disp32 +32426 1/imm32/xm32-is-first-inout +32427 3/imm32/x32-is-first-output +32428 0x11/imm32/alloc-id:fake +32429 _Primitive-divide-xreg-by-xreg/imm32/next +32430 # - floating-point divide +32431 _Primitive-divide-xreg-by-xreg: # (payload primitive) +32432 0x11/imm32/alloc-id:fake:payload +32433 # var1/xreg <- divide var2 => f3 0f 5e/divide var2/xm32 var1/x32 +32434 0x11/imm32/alloc-id:fake +32435 _string-divide/imm32/name +32436 0x11/imm32/alloc-id:fake +32437 Single-float-var-in-some-register/imm32/inouts +32438 0x11/imm32/alloc-id:fake +32439 Single-float-var-in-some-register/imm32/outputs +32440 0x11/imm32/alloc-id:fake +32441 _string_f3_0f_5e_divide/imm32/subx-name +32442 0/imm32/no-rm32 +32443 0/imm32/no-r32 +32444 0/imm32/no-imm32 +32445 0/imm32/no-imm8 +32446 0/imm32/no-disp32 +32447 1/imm32/xm32-is-first-inout +32448 3/imm32/x32-is-first-output +32449 0x11/imm32/alloc-id:fake +32450 _Primitive-divide-xreg-by-mem/imm32/next +32451 _Primitive-divide-xreg-by-mem: # (payload primitive) +32452 0x11/imm32/alloc-id:fake:payload +32453 # var1/xreg <- divide var2 => f3 0f 5e/divide var2/xm32 var1/x32 +32454 0x11/imm32/alloc-id:fake +32455 _string-divide/imm32/name 32456 0x11/imm32/alloc-id:fake -32457 _string-max/imm32/name +32457 Single-float-var-in-mem/imm32/inouts 32458 0x11/imm32/alloc-id:fake -32459 Single-float-var-in-some-register/imm32/inouts +32459 Single-float-var-in-some-register/imm32/outputs 32460 0x11/imm32/alloc-id:fake -32461 Single-float-var-in-some-register/imm32/outputs -32462 0x11/imm32/alloc-id:fake -32463 _string_f3_0f_5f_max/imm32/subx-name -32464 0/imm32/no-rm32 -32465 0/imm32/no-r32 -32466 0/imm32/no-imm32 -32467 0/imm32/no-imm8 -32468 0/imm32/no-disp32 -32469 1/imm32/xm32-is-first-inout -32470 3/imm32/x32-is-first-output -32471 0x11/imm32/alloc-id:fake -32472 _Primitive-max-xreg-with-mem/imm32/next -32473 _Primitive-max-xreg-with-mem: # (payload primitive) -32474 0x11/imm32/alloc-id:fake:payload -32475 # var1/xreg <- divide var2 => f3 0f 5f/max var2/xm32 var1/x32 -32476 0x11/imm32/alloc-id:fake -32477 _string-max/imm32/name -32478 0x11/imm32/alloc-id:fake -32479 Single-float-var-in-mem/imm32/inouts -32480 0x11/imm32/alloc-id:fake -32481 Single-float-var-in-some-register/imm32/outputs -32482 0x11/imm32/alloc-id:fake -32483 _string_f3_0f_5f_max/imm32/subx-name -32484 0/imm32/no-rm32 -32485 0/imm32/no-r32 -32486 0/imm32/no-imm32 -32487 0/imm32/no-imm8 -32488 0/imm32/no-disp32 -32489 1/imm32/xm32-is-first-inout -32490 3/imm32/x32-is-first-output -32491 0x11/imm32/alloc-id:fake -32492 _Primitive-min-xreg-with-xreg/imm32/next -32493 # - floating-point minimum -32494 _Primitive-min-xreg-with-xreg: # (payload primitive) -32495 0x11/imm32/alloc-id:fake:payload -32496 # var1/xreg <- divide var2 => f3 0f 5d/min var2/xm32 var1/x32 +32461 _string_f3_0f_5e_divide/imm32/subx-name +32462 0/imm32/no-rm32 +32463 0/imm32/no-r32 +32464 0/imm32/no-imm32 +32465 0/imm32/no-imm8 +32466 0/imm32/no-disp32 +32467 1/imm32/xm32-is-first-inout +32468 3/imm32/x32-is-first-output +32469 0x11/imm32/alloc-id:fake +32470 _Primitive-max-xreg-with-xreg/imm32/next +32471 # - floating-point maximum +32472 _Primitive-max-xreg-with-xreg: # (payload primitive) +32473 0x11/imm32/alloc-id:fake:payload +32474 # var1/xreg <- max var2 => f3 0f 5f/max var2/xm32 var1/x32 +32475 0x11/imm32/alloc-id:fake +32476 _string-max/imm32/name +32477 0x11/imm32/alloc-id:fake +32478 Single-float-var-in-some-register/imm32/inouts +32479 0x11/imm32/alloc-id:fake +32480 Single-float-var-in-some-register/imm32/outputs +32481 0x11/imm32/alloc-id:fake +32482 _string_f3_0f_5f_max/imm32/subx-name +32483 0/imm32/no-rm32 +32484 0/imm32/no-r32 +32485 0/imm32/no-imm32 +32486 0/imm32/no-imm8 +32487 0/imm32/no-disp32 +32488 1/imm32/xm32-is-first-inout +32489 3/imm32/x32-is-first-output +32490 0x11/imm32/alloc-id:fake +32491 _Primitive-max-xreg-with-mem/imm32/next +32492 _Primitive-max-xreg-with-mem: # (payload primitive) +32493 0x11/imm32/alloc-id:fake:payload +32494 # var1/xreg <- divide var2 => f3 0f 5f/max var2/xm32 var1/x32 +32495 0x11/imm32/alloc-id:fake +32496 _string-max/imm32/name 32497 0x11/imm32/alloc-id:fake -32498 _string-min/imm32/name +32498 Single-float-var-in-mem/imm32/inouts 32499 0x11/imm32/alloc-id:fake -32500 Single-float-var-in-some-register/imm32/inouts +32500 Single-float-var-in-some-register/imm32/outputs 32501 0x11/imm32/alloc-id:fake -32502 Single-float-var-in-some-register/imm32/outputs -32503 0x11/imm32/alloc-id:fake -32504 _string_f3_0f_5d_min/imm32/subx-name -32505 0/imm32/no-rm32 -32506 0/imm32/no-r32 -32507 0/imm32/no-imm32 -32508 0/imm32/no-imm8 -32509 0/imm32/no-disp32 -32510 1/imm32/xm32-is-first-inout -32511 3/imm32/x32-is-first-output -32512 0x11/imm32/alloc-id:fake -32513 _Primitive-min-xreg-with-mem/imm32/next -32514 _Primitive-min-xreg-with-mem: # (payload primitive) -32515 0x11/imm32/alloc-id:fake:payload -32516 # var1/xreg <- divide var2 => f3 0f 5d/min var2/xm32 var1/x32 -32517 0x11/imm32/alloc-id:fake -32518 _string-min/imm32/name -32519 0x11/imm32/alloc-id:fake -32520 Single-float-var-in-mem/imm32/inouts -32521 0x11/imm32/alloc-id:fake -32522 Single-float-var-in-some-register/imm32/outputs -32523 0x11/imm32/alloc-id:fake -32524 _string_f3_0f_5d_min/imm32/subx-name -32525 0/imm32/no-rm32 -32526 0/imm32/no-r32 -32527 0/imm32/no-imm32 -32528 0/imm32/no-imm8 -32529 0/imm32/no-disp32 -32530 1/imm32/xm32-is-first-inout -32531 3/imm32/x32-is-first-output -32532 0x11/imm32/alloc-id:fake -32533 _Primitive-reciprocal-xreg-to-xreg/imm32/next -32534 # - floating-point reciprocal -32535 _Primitive-reciprocal-xreg-to-xreg: # (payload primitive) -32536 0x11/imm32/alloc-id:fake:payload -32537 # var1/xreg <- reciprocal var2 => f3 0f 53/reciprocal var2/xm32 var1/x32 +32502 _string_f3_0f_5f_max/imm32/subx-name +32503 0/imm32/no-rm32 +32504 0/imm32/no-r32 +32505 0/imm32/no-imm32 +32506 0/imm32/no-imm8 +32507 0/imm32/no-disp32 +32508 1/imm32/xm32-is-first-inout +32509 3/imm32/x32-is-first-output +32510 0x11/imm32/alloc-id:fake +32511 _Primitive-min-xreg-with-xreg/imm32/next +32512 # - floating-point minimum +32513 _Primitive-min-xreg-with-xreg: # (payload primitive) +32514 0x11/imm32/alloc-id:fake:payload +32515 # var1/xreg <- divide var2 => f3 0f 5d/min var2/xm32 var1/x32 +32516 0x11/imm32/alloc-id:fake +32517 _string-min/imm32/name +32518 0x11/imm32/alloc-id:fake +32519 Single-float-var-in-some-register/imm32/inouts +32520 0x11/imm32/alloc-id:fake +32521 Single-float-var-in-some-register/imm32/outputs +32522 0x11/imm32/alloc-id:fake +32523 _string_f3_0f_5d_min/imm32/subx-name +32524 0/imm32/no-rm32 +32525 0/imm32/no-r32 +32526 0/imm32/no-imm32 +32527 0/imm32/no-imm8 +32528 0/imm32/no-disp32 +32529 1/imm32/xm32-is-first-inout +32530 3/imm32/x32-is-first-output +32531 0x11/imm32/alloc-id:fake +32532 _Primitive-min-xreg-with-mem/imm32/next +32533 _Primitive-min-xreg-with-mem: # (payload primitive) +32534 0x11/imm32/alloc-id:fake:payload +32535 # var1/xreg <- divide var2 => f3 0f 5d/min var2/xm32 var1/x32 +32536 0x11/imm32/alloc-id:fake +32537 _string-min/imm32/name 32538 0x11/imm32/alloc-id:fake -32539 _string-reciprocal/imm32/name +32539 Single-float-var-in-mem/imm32/inouts 32540 0x11/imm32/alloc-id:fake -32541 Single-float-var-in-some-register/imm32/inouts +32541 Single-float-var-in-some-register/imm32/outputs 32542 0x11/imm32/alloc-id:fake -32543 Single-float-var-in-some-register/imm32/outputs -32544 0x11/imm32/alloc-id:fake -32545 _string_f3_0f_53_reciprocal/imm32/subx-name -32546 0/imm32/no-rm32 -32547 0/imm32/no-r32 -32548 0/imm32/no-imm32 -32549 0/imm32/no-imm8 -32550 0/imm32/no-disp32 -32551 1/imm32/xm32-is-first-inout -32552 3/imm32/x32-is-first-output -32553 0x11/imm32/alloc-id:fake -32554 _Primitive-reciprocal-mem-to-xreg/imm32/next -32555 _Primitive-reciprocal-mem-to-xreg: # (payload primitive) -32556 0x11/imm32/alloc-id:fake:payload -32557 # var1/xreg <- divide var2 => f3 0f 53/reciprocal var2/xm32 var1/x32 -32558 0x11/imm32/alloc-id:fake -32559 _string-reciprocal/imm32/name -32560 0x11/imm32/alloc-id:fake -32561 Single-float-var-in-mem/imm32/inouts -32562 0x11/imm32/alloc-id:fake -32563 Single-float-var-in-some-register/imm32/outputs -32564 0x11/imm32/alloc-id:fake -32565 _string_f3_0f_53_reciprocal/imm32/subx-name -32566 0/imm32/no-rm32 -32567 0/imm32/no-r32 -32568 0/imm32/no-imm32 -32569 0/imm32/no-imm8 -32570 0/imm32/no-disp32 -32571 1/imm32/xm32-is-first-inout -32572 3/imm32/x32-is-first-output -32573 0x11/imm32/alloc-id:fake -32574 _Primitive-square-root-xreg-to-xreg/imm32/next -32575 # - floating-point square root -32576 _Primitive-square-root-xreg-to-xreg: # (payload primitive) -32577 0x11/imm32/alloc-id:fake:payload -32578 # var1/xreg <- square-root var2 => f3 0f 51/square-root var2/xm32 var1/x32 +32543 _string_f3_0f_5d_min/imm32/subx-name +32544 0/imm32/no-rm32 +32545 0/imm32/no-r32 +32546 0/imm32/no-imm32 +32547 0/imm32/no-imm8 +32548 0/imm32/no-disp32 +32549 1/imm32/xm32-is-first-inout +32550 3/imm32/x32-is-first-output +32551 0x11/imm32/alloc-id:fake +32552 _Primitive-reciprocal-xreg-to-xreg/imm32/next +32553 # - floating-point reciprocal +32554 _Primitive-reciprocal-xreg-to-xreg: # (payload primitive) +32555 0x11/imm32/alloc-id:fake:payload +32556 # var1/xreg <- reciprocal var2 => f3 0f 53/reciprocal var2/xm32 var1/x32 +32557 0x11/imm32/alloc-id:fake +32558 _string-reciprocal/imm32/name +32559 0x11/imm32/alloc-id:fake +32560 Single-float-var-in-some-register/imm32/inouts +32561 0x11/imm32/alloc-id:fake +32562 Single-float-var-in-some-register/imm32/outputs +32563 0x11/imm32/alloc-id:fake +32564 _string_f3_0f_53_reciprocal/imm32/subx-name +32565 0/imm32/no-rm32 +32566 0/imm32/no-r32 +32567 0/imm32/no-imm32 +32568 0/imm32/no-imm8 +32569 0/imm32/no-disp32 +32570 1/imm32/xm32-is-first-inout +32571 3/imm32/x32-is-first-output +32572 0x11/imm32/alloc-id:fake +32573 _Primitive-reciprocal-mem-to-xreg/imm32/next +32574 _Primitive-reciprocal-mem-to-xreg: # (payload primitive) +32575 0x11/imm32/alloc-id:fake:payload +32576 # var1/xreg <- divide var2 => f3 0f 53/reciprocal var2/xm32 var1/x32 +32577 0x11/imm32/alloc-id:fake +32578 _string-reciprocal/imm32/name 32579 0x11/imm32/alloc-id:fake -32580 _string-square-root/imm32/name +32580 Single-float-var-in-mem/imm32/inouts 32581 0x11/imm32/alloc-id:fake -32582 Single-float-var-in-some-register/imm32/inouts +32582 Single-float-var-in-some-register/imm32/outputs 32583 0x11/imm32/alloc-id:fake -32584 Single-float-var-in-some-register/imm32/outputs -32585 0x11/imm32/alloc-id:fake -32586 _string_f3_0f_51_square_root/imm32/subx-name -32587 0/imm32/no-rm32 -32588 0/imm32/no-r32 -32589 0/imm32/no-imm32 -32590 0/imm32/no-imm8 -32591 0/imm32/no-disp32 -32592 1/imm32/xm32-is-first-inout -32593 3/imm32/x32-is-first-output -32594 0x11/imm32/alloc-id:fake -32595 _Primitive-square-root-mem-to-xreg/imm32/next -32596 _Primitive-square-root-mem-to-xreg: # (payload primitive) -32597 0x11/imm32/alloc-id:fake:payload -32598 # var1/xreg <- divide var2 => f3 0f 51/square-root var2/xm32 var1/x32 -32599 0x11/imm32/alloc-id:fake -32600 _string-square-root/imm32/name -32601 0x11/imm32/alloc-id:fake -32602 Single-float-var-in-mem/imm32/inouts -32603 0x11/imm32/alloc-id:fake -32604 Single-float-var-in-some-register/imm32/outputs -32605 0x11/imm32/alloc-id:fake -32606 _string_f3_0f_51_square_root/imm32/subx-name -32607 0/imm32/no-rm32 -32608 0/imm32/no-r32 -32609 0/imm32/no-imm32 -32610 0/imm32/no-imm8 -32611 0/imm32/no-disp32 -32612 1/imm32/xm32-is-first-inout -32613 3/imm32/x32-is-first-output -32614 0x11/imm32/alloc-id:fake -32615 _Primitive-inverse-square-root-xreg-to-xreg/imm32/next -32616 # - floating-point inverse square root 1/sqrt(x) -32617 _Primitive-inverse-square-root-xreg-to-xreg: # (payload primitive) -32618 0x11/imm32/alloc-id:fake:payload -32619 # var1/xreg <- reciprocal var2 => f3 0f 52/inverse-square-root var2/xm32 var1/x32 +32584 _string_f3_0f_53_reciprocal/imm32/subx-name +32585 0/imm32/no-rm32 +32586 0/imm32/no-r32 +32587 0/imm32/no-imm32 +32588 0/imm32/no-imm8 +32589 0/imm32/no-disp32 +32590 1/imm32/xm32-is-first-inout +32591 3/imm32/x32-is-first-output +32592 0x11/imm32/alloc-id:fake +32593 _Primitive-square-root-xreg-to-xreg/imm32/next +32594 # - floating-point square root +32595 _Primitive-square-root-xreg-to-xreg: # (payload primitive) +32596 0x11/imm32/alloc-id:fake:payload +32597 # var1/xreg <- square-root var2 => f3 0f 51/square-root var2/xm32 var1/x32 +32598 0x11/imm32/alloc-id:fake +32599 _string-square-root/imm32/name +32600 0x11/imm32/alloc-id:fake +32601 Single-float-var-in-some-register/imm32/inouts +32602 0x11/imm32/alloc-id:fake +32603 Single-float-var-in-some-register/imm32/outputs +32604 0x11/imm32/alloc-id:fake +32605 _string_f3_0f_51_square_root/imm32/subx-name +32606 0/imm32/no-rm32 +32607 0/imm32/no-r32 +32608 0/imm32/no-imm32 +32609 0/imm32/no-imm8 +32610 0/imm32/no-disp32 +32611 1/imm32/xm32-is-first-inout +32612 3/imm32/x32-is-first-output +32613 0x11/imm32/alloc-id:fake +32614 _Primitive-square-root-mem-to-xreg/imm32/next +32615 _Primitive-square-root-mem-to-xreg: # (payload primitive) +32616 0x11/imm32/alloc-id:fake:payload +32617 # var1/xreg <- divide var2 => f3 0f 51/square-root var2/xm32 var1/x32 +32618 0x11/imm32/alloc-id:fake +32619 _string-square-root/imm32/name 32620 0x11/imm32/alloc-id:fake -32621 _string-inverse-square-root/imm32/name +32621 Single-float-var-in-mem/imm32/inouts 32622 0x11/imm32/alloc-id:fake -32623 Single-float-var-in-some-register/imm32/inouts +32623 Single-float-var-in-some-register/imm32/outputs 32624 0x11/imm32/alloc-id:fake -32625 Single-float-var-in-some-register/imm32/outputs -32626 0x11/imm32/alloc-id:fake -32627 _string_f3_0f_52_inverse_square_root/imm32/subx-name -32628 0/imm32/no-rm32 -32629 0/imm32/no-r32 -32630 0/imm32/no-imm32 -32631 0/imm32/no-imm8 -32632 0/imm32/no-disp32 -32633 1/imm32/xm32-is-first-inout -32634 3/imm32/x32-is-first-output -32635 0x11/imm32/alloc-id:fake -32636 _Primitive-inverse-square-root-mem-to-xreg/imm32/next -32637 _Primitive-inverse-square-root-mem-to-xreg: # (payload primitive) -32638 0x11/imm32/alloc-id:fake:payload -32639 # var1/xreg <- divide var2 => f3 0f 52/inverse-square-root var2/xm32 var1/x32 -32640 0x11/imm32/alloc-id:fake -32641 _string-inverse-square-root/imm32/name -32642 0x11/imm32/alloc-id:fake -32643 Single-float-var-in-mem/imm32/inouts -32644 0x11/imm32/alloc-id:fake -32645 Single-float-var-in-some-register/imm32/outputs -32646 0x11/imm32/alloc-id:fake -32647 _string_f3_0f_52_inverse_square_root/imm32/subx-name -32648 0/imm32/no-rm32 -32649 0/imm32/no-r32 -32650 0/imm32/no-imm32 -32651 0/imm32/no-imm8 -32652 0/imm32/no-disp32 -32653 1/imm32/xm32-is-first-inout -32654 3/imm32/x32-is-first-output -32655 0x11/imm32/alloc-id:fake -32656 _Primitive-compare-xreg-with-xreg/imm32/next -32657 # - floating-point compare -32658 _Primitive-compare-xreg-with-xreg: # (payload primitive) -32659 0x11/imm32/alloc-id:fake:payload -32660 # compare var1/reg1 var2/reg2 => 0f 2f/compare var2/x32 var1/xm32 +32625 _string_f3_0f_51_square_root/imm32/subx-name +32626 0/imm32/no-rm32 +32627 0/imm32/no-r32 +32628 0/imm32/no-imm32 +32629 0/imm32/no-imm8 +32630 0/imm32/no-disp32 +32631 1/imm32/xm32-is-first-inout +32632 3/imm32/x32-is-first-output +32633 0x11/imm32/alloc-id:fake +32634 _Primitive-inverse-square-root-xreg-to-xreg/imm32/next +32635 # - floating-point inverse square root 1/sqrt(x) +32636 _Primitive-inverse-square-root-xreg-to-xreg: # (payload primitive) +32637 0x11/imm32/alloc-id:fake:payload +32638 # var1/xreg <- reciprocal var2 => f3 0f 52/inverse-square-root var2/xm32 var1/x32 +32639 0x11/imm32/alloc-id:fake +32640 _string-inverse-square-root/imm32/name +32641 0x11/imm32/alloc-id:fake +32642 Single-float-var-in-some-register/imm32/inouts +32643 0x11/imm32/alloc-id:fake +32644 Single-float-var-in-some-register/imm32/outputs +32645 0x11/imm32/alloc-id:fake +32646 _string_f3_0f_52_inverse_square_root/imm32/subx-name +32647 0/imm32/no-rm32 +32648 0/imm32/no-r32 +32649 0/imm32/no-imm32 +32650 0/imm32/no-imm8 +32651 0/imm32/no-disp32 +32652 1/imm32/xm32-is-first-inout +32653 3/imm32/x32-is-first-output +32654 0x11/imm32/alloc-id:fake +32655 _Primitive-inverse-square-root-mem-to-xreg/imm32/next +32656 _Primitive-inverse-square-root-mem-to-xreg: # (payload primitive) +32657 0x11/imm32/alloc-id:fake:payload +32658 # var1/xreg <- divide var2 => f3 0f 52/inverse-square-root var2/xm32 var1/x32 +32659 0x11/imm32/alloc-id:fake +32660 _string-inverse-square-root/imm32/name 32661 0x11/imm32/alloc-id:fake -32662 _string-compare/imm32/name +32662 Single-float-var-in-mem/imm32/inouts 32663 0x11/imm32/alloc-id:fake -32664 Two-float-args-in-regs/imm32/inouts -32665 0/imm32/no-outputs -32666 0/imm32/no-outputs -32667 0x11/imm32/alloc-id:fake -32668 _string_0f_2f_compare/imm32/subx-name -32669 0/imm32/no-rm32 -32670 0/imm32/no-r32 -32671 0/imm32/no-imm32 -32672 0/imm32/no-imm8 -32673 0/imm32/no-disp32 -32674 2/imm32/xm32-is-second-inout -32675 1/imm32/x32-is-first-inout -32676 0x11/imm32/alloc-id:fake -32677 _Primitive-compare-xreg-with-mem/imm32/next -32678 _Primitive-compare-xreg-with-mem: # (payload primitive) -32679 0x11/imm32/alloc-id:fake:payload -32680 # compare var1/xreg var2 => 0f 2f/compare var1/x32 var2/xm32 -32681 0x11/imm32/alloc-id:fake -32682 _string-compare/imm32/name -32683 0x11/imm32/alloc-id:fake -32684 Two-args-float-reg-float-stack/imm32/inouts +32664 Single-float-var-in-some-register/imm32/outputs +32665 0x11/imm32/alloc-id:fake +32666 _string_f3_0f_52_inverse_square_root/imm32/subx-name +32667 0/imm32/no-rm32 +32668 0/imm32/no-r32 +32669 0/imm32/no-imm32 +32670 0/imm32/no-imm8 +32671 0/imm32/no-disp32 +32672 1/imm32/xm32-is-first-inout +32673 3/imm32/x32-is-first-output +32674 0x11/imm32/alloc-id:fake +32675 _Primitive-compare-xreg-with-xreg/imm32/next +32676 # - floating-point compare +32677 _Primitive-compare-xreg-with-xreg: # (payload primitive) +32678 0x11/imm32/alloc-id:fake:payload +32679 # compare var1/reg1 var2/reg2 => 0f 2f/compare var2/x32 var1/xm32 +32680 0x11/imm32/alloc-id:fake +32681 _string-compare/imm32/name +32682 0x11/imm32/alloc-id:fake +32683 Two-float-args-in-regs/imm32/inouts +32684 0/imm32/no-outputs 32685 0/imm32/no-outputs -32686 0/imm32/no-outputs -32687 0x11/imm32/alloc-id:fake -32688 _string_0f_2f_compare/imm32/subx-name -32689 0/imm32/no-rm32 -32690 0/imm32/no-r32 -32691 0/imm32/no-imm32 -32692 0/imm32/no-imm8 -32693 0/imm32/no-disp32 -32694 2/imm32/xm32-is-second-inout -32695 1/imm32/x32-is-first-inout -32696 0x11/imm32/alloc-id:fake -32697 _Primitive-break-if-addr</imm32/next -32698 # - branches -32699 _Primitive-break-if-addr<: # (payload primitive) -32700 0x11/imm32/alloc-id:fake:payload -32701 0x11/imm32/alloc-id:fake -32702 _string-break-if-addr</imm32/name -32703 0/imm32/no-inouts -32704 0/imm32/no-inouts +32686 0x11/imm32/alloc-id:fake +32687 _string_0f_2f_compare/imm32/subx-name +32688 0/imm32/no-rm32 +32689 0/imm32/no-r32 +32690 0/imm32/no-imm32 +32691 0/imm32/no-imm8 +32692 0/imm32/no-disp32 +32693 2/imm32/xm32-is-second-inout +32694 1/imm32/x32-is-first-inout +32695 0x11/imm32/alloc-id:fake +32696 _Primitive-compare-xreg-with-mem/imm32/next +32697 _Primitive-compare-xreg-with-mem: # (payload primitive) +32698 0x11/imm32/alloc-id:fake:payload +32699 # compare var1/xreg var2 => 0f 2f/compare var1/x32 var2/xm32 +32700 0x11/imm32/alloc-id:fake +32701 _string-compare/imm32/name +32702 0x11/imm32/alloc-id:fake +32703 Two-args-float-reg-float-stack/imm32/inouts +32704 0/imm32/no-outputs 32705 0/imm32/no-outputs -32706 0/imm32/no-outputs -32707 0x11/imm32/alloc-id:fake -32708 _string_0f_82_jump_break/imm32/subx-name -32709 0/imm32/no-rm32 -32710 0/imm32/no-r32 -32711 0/imm32/no-imm32 -32712 0/imm32/no-imm8 -32713 0/imm32/no-disp32 -32714 0/imm32/no-xm32 -32715 0/imm32/no-x32 -32716 0x11/imm32/alloc-id:fake -32717 _Primitive-break-if-addr>=/imm32/next -32718 _Primitive-break-if-addr>=: # (payload primitive) +32706 0x11/imm32/alloc-id:fake +32707 _string_0f_2f_compare/imm32/subx-name +32708 0/imm32/no-rm32 +32709 0/imm32/no-r32 +32710 0/imm32/no-imm32 +32711 0/imm32/no-imm8 +32712 0/imm32/no-disp32 +32713 2/imm32/xm32-is-second-inout +32714 1/imm32/x32-is-first-inout +32715 0x11/imm32/alloc-id:fake +32716 _Primitive-break-if-addr</imm32/next +32717 # - branches +32718 _Primitive-break-if-addr<: # (payload primitive) 32719 0x11/imm32/alloc-id:fake:payload 32720 0x11/imm32/alloc-id:fake -32721 _string-break-if-addr>=/imm32/name +32721 _string-break-if-addr</imm32/name 32722 0/imm32/no-inouts 32723 0/imm32/no-inouts 32724 0/imm32/no-outputs 32725 0/imm32/no-outputs 32726 0x11/imm32/alloc-id:fake -32727 _string_0f_83_jump_break/imm32/subx-name +32727 _string_0f_82_jump_break/imm32/subx-name 32728 0/imm32/no-rm32 32729 0/imm32/no-r32 32730 0/imm32/no-imm32 @@ -31108,17 +31108,17 @@ if ('onhashchange' in window) { 32733 0/imm32/no-xm32 32734 0/imm32/no-x32 32735 0x11/imm32/alloc-id:fake -32736 _Primitive-break-if-=/imm32/next -32737 _Primitive-break-if-=: # (payload primitive) +32736 _Primitive-break-if-addr>=/imm32/next +32737 _Primitive-break-if-addr>=: # (payload primitive) 32738 0x11/imm32/alloc-id:fake:payload 32739 0x11/imm32/alloc-id:fake -32740 _string-break-if-=/imm32/name +32740 _string-break-if-addr>=/imm32/name 32741 0/imm32/no-inouts 32742 0/imm32/no-inouts 32743 0/imm32/no-outputs 32744 0/imm32/no-outputs 32745 0x11/imm32/alloc-id:fake -32746 _string_0f_84_jump_break/imm32/subx-name +32746 _string_0f_83_jump_break/imm32/subx-name 32747 0/imm32/no-rm32 32748 0/imm32/no-r32 32749 0/imm32/no-imm32 @@ -31127,17 +31127,17 @@ if ('onhashchange' in window) { 32752 0/imm32/no-xm32 32753 0/imm32/no-x32 32754 0x11/imm32/alloc-id:fake -32755 _Primitive-break-if-!=/imm32/next -32756 _Primitive-break-if-!=: # (payload primitive) +32755 _Primitive-break-if-=/imm32/next +32756 _Primitive-break-if-=: # (payload primitive) 32757 0x11/imm32/alloc-id:fake:payload 32758 0x11/imm32/alloc-id:fake -32759 _string-break-if-!=/imm32/name +32759 _string-break-if-=/imm32/name 32760 0/imm32/no-inouts 32761 0/imm32/no-inouts 32762 0/imm32/no-outputs 32763 0/imm32/no-outputs 32764 0x11/imm32/alloc-id:fake -32765 _string_0f_85_jump_break/imm32/subx-name +32765 _string_0f_84_jump_break/imm32/subx-name 32766 0/imm32/no-rm32 32767 0/imm32/no-r32 32768 0/imm32/no-imm32 @@ -31146,17 +31146,17 @@ if ('onhashchange' in window) { 32771 0/imm32/no-xm32 32772 0/imm32/no-x32 32773 0x11/imm32/alloc-id:fake -32774 _Primitive-break-if-addr<=/imm32/next -32775 _Primitive-break-if-addr<=: # (payload primitive) +32774 _Primitive-break-if-!=/imm32/next +32775 _Primitive-break-if-!=: # (payload primitive) 32776 0x11/imm32/alloc-id:fake:payload 32777 0x11/imm32/alloc-id:fake -32778 _string-break-if-addr<=/imm32/name +32778 _string-break-if-!=/imm32/name 32779 0/imm32/no-inouts 32780 0/imm32/no-inouts 32781 0/imm32/no-outputs 32782 0/imm32/no-outputs 32783 0x11/imm32/alloc-id:fake -32784 _string_0f_86_jump_break/imm32/subx-name +32784 _string_0f_85_jump_break/imm32/subx-name 32785 0/imm32/no-rm32 32786 0/imm32/no-r32 32787 0/imm32/no-imm32 @@ -31165,17 +31165,17 @@ if ('onhashchange' in window) { 32790 0/imm32/no-xm32 32791 0/imm32/no-x32 32792 0x11/imm32/alloc-id:fake -32793 _Primitive-break-if-addr>/imm32/next -32794 _Primitive-break-if-addr>: # (payload primitive) +32793 _Primitive-break-if-addr<=/imm32/next +32794 _Primitive-break-if-addr<=: # (payload primitive) 32795 0x11/imm32/alloc-id:fake:payload 32796 0x11/imm32/alloc-id:fake -32797 _string-break-if-addr>/imm32/name +32797 _string-break-if-addr<=/imm32/name 32798 0/imm32/no-inouts 32799 0/imm32/no-inouts 32800 0/imm32/no-outputs 32801 0/imm32/no-outputs 32802 0x11/imm32/alloc-id:fake -32803 _string_0f_87_jump_break/imm32/subx-name +32803 _string_0f_86_jump_break/imm32/subx-name 32804 0/imm32/no-rm32 32805 0/imm32/no-r32 32806 0/imm32/no-imm32 @@ -31184,17 +31184,17 @@ if ('onhashchange' in window) { 32809 0/imm32/no-xm32 32810 0/imm32/no-x32 32811 0x11/imm32/alloc-id:fake -32812 _Primitive-break-if-</imm32/next -32813 _Primitive-break-if-<: # (payload primitive) +32812 _Primitive-break-if-addr>/imm32/next +32813 _Primitive-break-if-addr>: # (payload primitive) 32814 0x11/imm32/alloc-id:fake:payload 32815 0x11/imm32/alloc-id:fake -32816 _string-break-if-</imm32/name +32816 _string-break-if-addr>/imm32/name 32817 0/imm32/no-inouts 32818 0/imm32/no-inouts 32819 0/imm32/no-outputs 32820 0/imm32/no-outputs 32821 0x11/imm32/alloc-id:fake -32822 _string_0f_8c_jump_break/imm32/subx-name +32822 _string_0f_87_jump_break/imm32/subx-name 32823 0/imm32/no-rm32 32824 0/imm32/no-r32 32825 0/imm32/no-imm32 @@ -31203,17 +31203,17 @@ if ('onhashchange' in window) { 32828 0/imm32/no-xm32 32829 0/imm32/no-x32 32830 0x11/imm32/alloc-id:fake -32831 _Primitive-break-if->=/imm32/next -32832 _Primitive-break-if->=: # (payload primitive) +32831 _Primitive-break-if-</imm32/next +32832 _Primitive-break-if-<: # (payload primitive) 32833 0x11/imm32/alloc-id:fake:payload 32834 0x11/imm32/alloc-id:fake -32835 _string-break-if->=/imm32/name +32835 _string-break-if-</imm32/name 32836 0/imm32/no-inouts 32837 0/imm32/no-inouts 32838 0/imm32/no-outputs 32839 0/imm32/no-outputs 32840 0x11/imm32/alloc-id:fake -32841 _string_0f_8d_jump_break/imm32/subx-name +32841 _string_0f_8c_jump_break/imm32/subx-name 32842 0/imm32/no-rm32 32843 0/imm32/no-r32 32844 0/imm32/no-imm32 @@ -31222,17 +31222,17 @@ if ('onhashchange' in window) { 32847 0/imm32/no-xm32 32848 0/imm32/no-x32 32849 0x11/imm32/alloc-id:fake -32850 _Primitive-break-if-<=/imm32/next -32851 _Primitive-break-if-<=: # (payload primitive) +32850 _Primitive-break-if->=/imm32/next +32851 _Primitive-break-if->=: # (payload primitive) 32852 0x11/imm32/alloc-id:fake:payload 32853 0x11/imm32/alloc-id:fake -32854 _string-break-if-<=/imm32/name +32854 _string-break-if->=/imm32/name 32855 0/imm32/no-inouts 32856 0/imm32/no-inouts 32857 0/imm32/no-outputs 32858 0/imm32/no-outputs 32859 0x11/imm32/alloc-id:fake -32860 _string_0f_8e_jump_break/imm32/subx-name +32860 _string_0f_8d_jump_break/imm32/subx-name 32861 0/imm32/no-rm32 32862 0/imm32/no-r32 32863 0/imm32/no-imm32 @@ -31241,17 +31241,17 @@ if ('onhashchange' in window) { 32866 0/imm32/no-xm32 32867 0/imm32/no-x32 32868 0x11/imm32/alloc-id:fake -32869 _Primitive-break-if->/imm32/next -32870 _Primitive-break-if->: # (payload primitive) +32869 _Primitive-break-if-<=/imm32/next +32870 _Primitive-break-if-<=: # (payload primitive) 32871 0x11/imm32/alloc-id:fake:payload 32872 0x11/imm32/alloc-id:fake -32873 _string-break-if->/imm32/name +32873 _string-break-if-<=/imm32/name 32874 0/imm32/no-inouts 32875 0/imm32/no-inouts 32876 0/imm32/no-outputs 32877 0/imm32/no-outputs 32878 0x11/imm32/alloc-id:fake -32879 _string_0f_8f_jump_break/imm32/subx-name +32879 _string_0f_8e_jump_break/imm32/subx-name 32880 0/imm32/no-rm32 32881 0/imm32/no-r32 32882 0/imm32/no-imm32 @@ -31260,17 +31260,17 @@ if ('onhashchange' in window) { 32885 0/imm32/no-xm32 32886 0/imm32/no-x32 32887 0x11/imm32/alloc-id:fake -32888 _Primitive-break-if-carry/imm32/next -32889 _Primitive-break-if-carry: # (payload primitive) +32888 _Primitive-break-if->/imm32/next +32889 _Primitive-break-if->: # (payload primitive) 32890 0x11/imm32/alloc-id:fake:payload 32891 0x11/imm32/alloc-id:fake -32892 _string-break-if-carry/imm32/name +32892 _string-break-if->/imm32/name 32893 0/imm32/no-inouts 32894 0/imm32/no-inouts 32895 0/imm32/no-outputs 32896 0/imm32/no-outputs 32897 0x11/imm32/alloc-id:fake -32898 _string_0f_82_jump_break/imm32/subx-name +32898 _string_0f_8f_jump_break/imm32/subx-name 32899 0/imm32/no-rm32 32900 0/imm32/no-r32 32901 0/imm32/no-imm32 @@ -31279,17 +31279,17 @@ if ('onhashchange' in window) { 32904 0/imm32/no-xm32 32905 0/imm32/no-x32 32906 0x11/imm32/alloc-id:fake -32907 _Primitive-break-if-not-carry/imm32/next -32908 _Primitive-break-if-not-carry: # (payload primitive) +32907 _Primitive-break-if-carry/imm32/next +32908 _Primitive-break-if-carry: # (payload primitive) 32909 0x11/imm32/alloc-id:fake:payload 32910 0x11/imm32/alloc-id:fake -32911 _string-break-if-not-carry/imm32/name +32911 _string-break-if-carry/imm32/name 32912 0/imm32/no-inouts 32913 0/imm32/no-inouts 32914 0/imm32/no-outputs 32915 0/imm32/no-outputs 32916 0x11/imm32/alloc-id:fake -32917 _string_0f_83_jump_break/imm32/subx-name +32917 _string_0f_82_jump_break/imm32/subx-name 32918 0/imm32/no-rm32 32919 0/imm32/no-r32 32920 0/imm32/no-imm32 @@ -31298,17 +31298,17 @@ if ('onhashchange' in window) { 32923 0/imm32/no-xm32 32924 0/imm32/no-x32 32925 0x11/imm32/alloc-id:fake -32926 _Primitive-break-if-overflow/imm32/next -32927 _Primitive-break-if-overflow: # (payload primitive) +32926 _Primitive-break-if-not-carry/imm32/next +32927 _Primitive-break-if-not-carry: # (payload primitive) 32928 0x11/imm32/alloc-id:fake:payload 32929 0x11/imm32/alloc-id:fake -32930 _string-break-if-overflow/imm32/name +32930 _string-break-if-not-carry/imm32/name 32931 0/imm32/no-inouts 32932 0/imm32/no-inouts 32933 0/imm32/no-outputs 32934 0/imm32/no-outputs 32935 0x11/imm32/alloc-id:fake -32936 _string_0f_80_jump_break/imm32/subx-name +32936 _string_0f_83_jump_break/imm32/subx-name 32937 0/imm32/no-rm32 32938 0/imm32/no-r32 32939 0/imm32/no-imm32 @@ -31317,17 +31317,17 @@ if ('onhashchange' in window) { 32942 0/imm32/no-xm32 32943 0/imm32/no-x32 32944 0x11/imm32/alloc-id:fake -32945 _Primitive-break-if-not-overflow/imm32/next -32946 _Primitive-break-if-not-overflow: # (payload primitive) +32945 _Primitive-break-if-overflow/imm32/next +32946 _Primitive-break-if-overflow: # (payload primitive) 32947 0x11/imm32/alloc-id:fake:payload 32948 0x11/imm32/alloc-id:fake -32949 _string-break-if-not-overflow/imm32/name +32949 _string-break-if-overflow/imm32/name 32950 0/imm32/no-inouts 32951 0/imm32/no-inouts 32952 0/imm32/no-outputs 32953 0/imm32/no-outputs 32954 0x11/imm32/alloc-id:fake -32955 _string_0f_81_jump_break/imm32/subx-name +32955 _string_0f_80_jump_break/imm32/subx-name 32956 0/imm32/no-rm32 32957 0/imm32/no-r32 32958 0/imm32/no-imm32 @@ -31336,17 +31336,17 @@ if ('onhashchange' in window) { 32961 0/imm32/no-xm32 32962 0/imm32/no-x32 32963 0x11/imm32/alloc-id:fake -32964 _Primitive-break/imm32/next -32965 _Primitive-break: # (payload primitive) +32964 _Primitive-break-if-not-overflow/imm32/next +32965 _Primitive-break-if-not-overflow: # (payload primitive) 32966 0x11/imm32/alloc-id:fake:payload 32967 0x11/imm32/alloc-id:fake -32968 _string-break/imm32/name +32968 _string-break-if-not-overflow/imm32/name 32969 0/imm32/no-inouts 32970 0/imm32/no-inouts 32971 0/imm32/no-outputs 32972 0/imm32/no-outputs 32973 0x11/imm32/alloc-id:fake -32974 _string_e9_jump_break/imm32/subx-name +32974 _string_0f_81_jump_break/imm32/subx-name 32975 0/imm32/no-rm32 32976 0/imm32/no-r32 32977 0/imm32/no-imm32 @@ -31355,17 +31355,17 @@ if ('onhashchange' in window) { 32980 0/imm32/no-xm32 32981 0/imm32/no-x32 32982 0x11/imm32/alloc-id:fake -32983 _Primitive-loop-if-addr</imm32/next -32984 _Primitive-loop-if-addr<: # (payload primitive) +32983 _Primitive-break/imm32/next +32984 _Primitive-break: # (payload primitive) 32985 0x11/imm32/alloc-id:fake:payload 32986 0x11/imm32/alloc-id:fake -32987 _string-loop-if-addr</imm32/name +32987 _string-break/imm32/name 32988 0/imm32/no-inouts 32989 0/imm32/no-inouts 32990 0/imm32/no-outputs 32991 0/imm32/no-outputs 32992 0x11/imm32/alloc-id:fake -32993 _string_0f_82_jump_loop/imm32/subx-name +32993 _string_e9_jump_break/imm32/subx-name 32994 0/imm32/no-rm32 32995 0/imm32/no-r32 32996 0/imm32/no-imm32 @@ -31374,17 +31374,17 @@ if ('onhashchange' in window) { 32999 0/imm32/no-xm32 33000 0/imm32/no-x32 33001 0x11/imm32/alloc-id:fake -33002 _Primitive-loop-if-addr>=/imm32/next -33003 _Primitive-loop-if-addr>=: # (payload primitive) +33002 _Primitive-loop-if-addr</imm32/next +33003 _Primitive-loop-if-addr<: # (payload primitive) 33004 0x11/imm32/alloc-id:fake:payload 33005 0x11/imm32/alloc-id:fake -33006 _string-loop-if-addr>=/imm32/name +33006 _string-loop-if-addr</imm32/name 33007 0/imm32/no-inouts 33008 0/imm32/no-inouts 33009 0/imm32/no-outputs 33010 0/imm32/no-outputs 33011 0x11/imm32/alloc-id:fake -33012 _string_0f_83_jump_loop/imm32/subx-name +33012 _string_0f_82_jump_loop/imm32/subx-name 33013 0/imm32/no-rm32 33014 0/imm32/no-r32 33015 0/imm32/no-imm32 @@ -31393,17 +31393,17 @@ if ('onhashchange' in window) { 33018 0/imm32/no-xm32 33019 0/imm32/no-x32 33020 0x11/imm32/alloc-id:fake -33021 _Primitive-loop-if-=/imm32/next -33022 _Primitive-loop-if-=: # (payload primitive) +33021 _Primitive-loop-if-addr>=/imm32/next +33022 _Primitive-loop-if-addr>=: # (payload primitive) 33023 0x11/imm32/alloc-id:fake:payload 33024 0x11/imm32/alloc-id:fake -33025 _string-loop-if-=/imm32/name +33025 _string-loop-if-addr>=/imm32/name 33026 0/imm32/no-inouts 33027 0/imm32/no-inouts 33028 0/imm32/no-outputs 33029 0/imm32/no-outputs 33030 0x11/imm32/alloc-id:fake -33031 _string_0f_84_jump_loop/imm32/subx-name +33031 _string_0f_83_jump_loop/imm32/subx-name 33032 0/imm32/no-rm32 33033 0/imm32/no-r32 33034 0/imm32/no-imm32 @@ -31412,17 +31412,17 @@ if ('onhashchange' in window) { 33037 0/imm32/no-xm32 33038 0/imm32/no-x32 33039 0x11/imm32/alloc-id:fake -33040 _Primitive-loop-if-!=/imm32/next -33041 _Primitive-loop-if-!=: # (payload primitive) +33040 _Primitive-loop-if-=/imm32/next +33041 _Primitive-loop-if-=: # (payload primitive) 33042 0x11/imm32/alloc-id:fake:payload 33043 0x11/imm32/alloc-id:fake -33044 _string-loop-if-!=/imm32/name +33044 _string-loop-if-=/imm32/name 33045 0/imm32/no-inouts 33046 0/imm32/no-inouts 33047 0/imm32/no-outputs 33048 0/imm32/no-outputs 33049 0x11/imm32/alloc-id:fake -33050 _string_0f_85_jump_loop/imm32/subx-name +33050 _string_0f_84_jump_loop/imm32/subx-name 33051 0/imm32/no-rm32 33052 0/imm32/no-r32 33053 0/imm32/no-imm32 @@ -31431,17 +31431,17 @@ if ('onhashchange' in window) { 33056 0/imm32/no-xm32 33057 0/imm32/no-x32 33058 0x11/imm32/alloc-id:fake -33059 _Primitive-loop-if-addr<=/imm32/next -33060 _Primitive-loop-if-addr<=: # (payload primitive) +33059 _Primitive-loop-if-!=/imm32/next +33060 _Primitive-loop-if-!=: # (payload primitive) 33061 0x11/imm32/alloc-id:fake:payload 33062 0x11/imm32/alloc-id:fake -33063 _string-loop-if-addr<=/imm32/name +33063 _string-loop-if-!=/imm32/name 33064 0/imm32/no-inouts 33065 0/imm32/no-inouts 33066 0/imm32/no-outputs 33067 0/imm32/no-outputs 33068 0x11/imm32/alloc-id:fake -33069 _string_0f_86_jump_loop/imm32/subx-name +33069 _string_0f_85_jump_loop/imm32/subx-name 33070 0/imm32/no-rm32 33071 0/imm32/no-r32 33072 0/imm32/no-imm32 @@ -31450,17 +31450,17 @@ if ('onhashchange' in window) { 33075 0/imm32/no-xm32 33076 0/imm32/no-x32 33077 0x11/imm32/alloc-id:fake -33078 _Primitive-loop-if-addr>/imm32/next -33079 _Primitive-loop-if-addr>: # (payload primitive) +33078 _Primitive-loop-if-addr<=/imm32/next +33079 _Primitive-loop-if-addr<=: # (payload primitive) 33080 0x11/imm32/alloc-id:fake:payload 33081 0x11/imm32/alloc-id:fake -33082 _string-loop-if-addr>/imm32/name +33082 _string-loop-if-addr<=/imm32/name 33083 0/imm32/no-inouts 33084 0/imm32/no-inouts 33085 0/imm32/no-outputs 33086 0/imm32/no-outputs 33087 0x11/imm32/alloc-id:fake -33088 _string_0f_87_jump_loop/imm32/subx-name +33088 _string_0f_86_jump_loop/imm32/subx-name 33089 0/imm32/no-rm32 33090 0/imm32/no-r32 33091 0/imm32/no-imm32 @@ -31469,17 +31469,17 @@ if ('onhashchange' in window) { 33094 0/imm32/no-xm32 33095 0/imm32/no-x32 33096 0x11/imm32/alloc-id:fake -33097 _Primitive-loop-if-</imm32/next -33098 _Primitive-loop-if-<: # (payload primitive) +33097 _Primitive-loop-if-addr>/imm32/next +33098 _Primitive-loop-if-addr>: # (payload primitive) 33099 0x11/imm32/alloc-id:fake:payload 33100 0x11/imm32/alloc-id:fake -33101 _string-loop-if-</imm32/name +33101 _string-loop-if-addr>/imm32/name 33102 0/imm32/no-inouts 33103 0/imm32/no-inouts 33104 0/imm32/no-outputs 33105 0/imm32/no-outputs 33106 0x11/imm32/alloc-id:fake -33107 _string_0f_8c_jump_loop/imm32/subx-name +33107 _string_0f_87_jump_loop/imm32/subx-name 33108 0/imm32/no-rm32 33109 0/imm32/no-r32 33110 0/imm32/no-imm32 @@ -31488,17 +31488,17 @@ if ('onhashchange' in window) { 33113 0/imm32/no-xm32 33114 0/imm32/no-x32 33115 0x11/imm32/alloc-id:fake -33116 _Primitive-loop-if->=/imm32/next -33117 _Primitive-loop-if->=: # (payload primitive) +33116 _Primitive-loop-if-</imm32/next +33117 _Primitive-loop-if-<: # (payload primitive) 33118 0x11/imm32/alloc-id:fake:payload 33119 0x11/imm32/alloc-id:fake -33120 _string-loop-if->=/imm32/name +33120 _string-loop-if-</imm32/name 33121 0/imm32/no-inouts 33122 0/imm32/no-inouts 33123 0/imm32/no-outputs 33124 0/imm32/no-outputs 33125 0x11/imm32/alloc-id:fake -33126 _string_0f_8d_jump_loop/imm32/subx-name +33126 _string_0f_8c_jump_loop/imm32/subx-name 33127 0/imm32/no-rm32 33128 0/imm32/no-r32 33129 0/imm32/no-imm32 @@ -31507,17 +31507,17 @@ if ('onhashchange' in window) { 33132 0/imm32/no-xm32 33133 0/imm32/no-x32 33134 0x11/imm32/alloc-id:fake -33135 _Primitive-loop-if-<=/imm32/next -33136 _Primitive-loop-if-<=: # (payload primitive) +33135 _Primitive-loop-if->=/imm32/next +33136 _Primitive-loop-if->=: # (payload primitive) 33137 0x11/imm32/alloc-id:fake:payload 33138 0x11/imm32/alloc-id:fake -33139 _string-loop-if-<=/imm32/name +33139 _string-loop-if->=/imm32/name 33140 0/imm32/no-inouts 33141 0/imm32/no-inouts 33142 0/imm32/no-outputs 33143 0/imm32/no-outputs 33144 0x11/imm32/alloc-id:fake -33145 _string_0f_8e_jump_loop/imm32/subx-name +33145 _string_0f_8d_jump_loop/imm32/subx-name 33146 0/imm32/no-rm32 33147 0/imm32/no-r32 33148 0/imm32/no-imm32 @@ -31526,17 +31526,17 @@ if ('onhashchange' in window) { 33151 0/imm32/no-xm32 33152 0/imm32/no-x32 33153 0x11/imm32/alloc-id:fake -33154 _Primitive-loop-if->/imm32/next -33155 _Primitive-loop-if->: # (payload primitive) +33154 _Primitive-loop-if-<=/imm32/next +33155 _Primitive-loop-if-<=: # (payload primitive) 33156 0x11/imm32/alloc-id:fake:payload 33157 0x11/imm32/alloc-id:fake -33158 _string-loop-if->/imm32/name +33158 _string-loop-if-<=/imm32/name 33159 0/imm32/no-inouts 33160 0/imm32/no-inouts 33161 0/imm32/no-outputs 33162 0/imm32/no-outputs 33163 0x11/imm32/alloc-id:fake -33164 _string_0f_8f_jump_loop/imm32/subx-name +33164 _string_0f_8e_jump_loop/imm32/subx-name 33165 0/imm32/no-rm32 33166 0/imm32/no-r32 33167 0/imm32/no-imm32 @@ -31545,17 +31545,17 @@ if ('onhashchange' in window) { 33170 0/imm32/no-xm32 33171 0/imm32/no-x32 33172 0x11/imm32/alloc-id:fake -33173 _Primitive-loop-if-carry/imm32/next -33174 _Primitive-loop-if-carry: # (payload primitive) +33173 _Primitive-loop-if->/imm32/next +33174 _Primitive-loop-if->: # (payload primitive) 33175 0x11/imm32/alloc-id:fake:payload 33176 0x11/imm32/alloc-id:fake -33177 _string-loop-if-carry/imm32/name +33177 _string-loop-if->/imm32/name 33178 0/imm32/no-inouts 33179 0/imm32/no-inouts 33180 0/imm32/no-outputs 33181 0/imm32/no-outputs 33182 0x11/imm32/alloc-id:fake -33183 _string_0f_82_jump_loop/imm32/subx-name +33183 _string_0f_8f_jump_loop/imm32/subx-name 33184 0/imm32/no-rm32 33185 0/imm32/no-r32 33186 0/imm32/no-imm32 @@ -31564,17 +31564,17 @@ if ('onhashchange' in window) { 33189 0/imm32/no-xm32 33190 0/imm32/no-x32 33191 0x11/imm32/alloc-id:fake -33192 _Primitive-loop-if-not-carry/imm32/next -33193 _Primitive-loop-if-not-carry: # (payload primitive) +33192 _Primitive-loop-if-carry/imm32/next +33193 _Primitive-loop-if-carry: # (payload primitive) 33194 0x11/imm32/alloc-id:fake:payload 33195 0x11/imm32/alloc-id:fake -33196 _string-loop-if-not-carry/imm32/name +33196 _string-loop-if-carry/imm32/name 33197 0/imm32/no-inouts 33198 0/imm32/no-inouts 33199 0/imm32/no-outputs 33200 0/imm32/no-outputs 33201 0x11/imm32/alloc-id:fake -33202 _string_0f_83_jump_loop/imm32/subx-name +33202 _string_0f_82_jump_loop/imm32/subx-name 33203 0/imm32/no-rm32 33204 0/imm32/no-r32 33205 0/imm32/no-imm32 @@ -31583,17 +31583,17 @@ if ('onhashchange' in window) { 33208 0/imm32/no-xm32 33209 0/imm32/no-x32 33210 0x11/imm32/alloc-id:fake -33211 _Primitive-loop-if-overflow/imm32/next -33212 _Primitive-loop-if-overflow: # (payload primitive) +33211 _Primitive-loop-if-not-carry/imm32/next +33212 _Primitive-loop-if-not-carry: # (payload primitive) 33213 0x11/imm32/alloc-id:fake:payload 33214 0x11/imm32/alloc-id:fake -33215 _string-loop-if-overflow/imm32/name +33215 _string-loop-if-not-carry/imm32/name 33216 0/imm32/no-inouts 33217 0/imm32/no-inouts 33218 0/imm32/no-outputs 33219 0/imm32/no-outputs 33220 0x11/imm32/alloc-id:fake -33221 _string_0f_80_jump_loop/imm32/subx-name +33221 _string_0f_83_jump_loop/imm32/subx-name 33222 0/imm32/no-rm32 33223 0/imm32/no-r32 33224 0/imm32/no-imm32 @@ -31602,17 +31602,17 @@ if ('onhashchange' in window) { 33227 0/imm32/no-xm32 33228 0/imm32/no-x32 33229 0x11/imm32/alloc-id:fake -33230 _Primitive-loop-if-not-overflow/imm32/next -33231 _Primitive-loop-if-not-overflow: # (payload primitive) +33230 _Primitive-loop-if-overflow/imm32/next +33231 _Primitive-loop-if-overflow: # (payload primitive) 33232 0x11/imm32/alloc-id:fake:payload 33233 0x11/imm32/alloc-id:fake -33234 _string-loop-if-not-overflow/imm32/name +33234 _string-loop-if-overflow/imm32/name 33235 0/imm32/no-inouts 33236 0/imm32/no-inouts 33237 0/imm32/no-outputs 33238 0/imm32/no-outputs 33239 0x11/imm32/alloc-id:fake -33240 _string_0f_81_jump_loop/imm32/subx-name +33240 _string_0f_80_jump_loop/imm32/subx-name 33241 0/imm32/no-rm32 33242 0/imm32/no-r32 33243 0/imm32/no-imm32 @@ -31621,17 +31621,17 @@ if ('onhashchange' in window) { 33246 0/imm32/no-xm32 33247 0/imm32/no-x32 33248 0x11/imm32/alloc-id:fake -33249 _Primitive-loop/imm32/next # we probably don't need an unconditional break -33250 _Primitive-loop: # (payload primitive) +33249 _Primitive-loop-if-not-overflow/imm32/next +33250 _Primitive-loop-if-not-overflow: # (payload primitive) 33251 0x11/imm32/alloc-id:fake:payload 33252 0x11/imm32/alloc-id:fake -33253 _string-loop/imm32/name +33253 _string-loop-if-not-overflow/imm32/name 33254 0/imm32/no-inouts 33255 0/imm32/no-inouts 33256 0/imm32/no-outputs 33257 0/imm32/no-outputs 33258 0x11/imm32/alloc-id:fake -33259 _string_e9_jump_loop/imm32/subx-name +33259 _string_0f_81_jump_loop/imm32/subx-name 33260 0/imm32/no-rm32 33261 0/imm32/no-r32 33262 0/imm32/no-imm32 @@ -31640,37 +31640,37 @@ if ('onhashchange' in window) { 33265 0/imm32/no-xm32 33266 0/imm32/no-x32 33267 0x11/imm32/alloc-id:fake -33268 _Primitive-break-if-addr<-named/imm32/next -33269 # - branches to named blocks -33270 _Primitive-break-if-addr<-named: # (payload primitive) -33271 0x11/imm32/alloc-id:fake:payload -33272 0x11/imm32/alloc-id:fake -33273 _string-break-if-addr</imm32/name -33274 0x11/imm32/alloc-id:fake -33275 Single-lit-var/imm32/inouts +33268 _Primitive-loop/imm32/next # we probably don't need an unconditional break +33269 _Primitive-loop: # (payload primitive) +33270 0x11/imm32/alloc-id:fake:payload +33271 0x11/imm32/alloc-id:fake +33272 _string-loop/imm32/name +33273 0/imm32/no-inouts +33274 0/imm32/no-inouts +33275 0/imm32/no-outputs 33276 0/imm32/no-outputs -33277 0/imm32/no-outputs -33278 0x11/imm32/alloc-id:fake -33279 _string_0f_82_jump_label/imm32/subx-name -33280 0/imm32/no-rm32 -33281 0/imm32/no-r32 -33282 0/imm32/no-imm32 -33283 0/imm32/no-imm8 -33284 1/imm32/disp32-is-first-inout -33285 0/imm32/no-xm32 -33286 0/imm32/no-x32 -33287 0x11/imm32/alloc-id:fake -33288 _Primitive-break-if-addr>=-named/imm32/next -33289 _Primitive-break-if-addr>=-named: # (payload primitive) +33277 0x11/imm32/alloc-id:fake +33278 _string_e9_jump_loop/imm32/subx-name +33279 0/imm32/no-rm32 +33280 0/imm32/no-r32 +33281 0/imm32/no-imm32 +33282 0/imm32/no-imm8 +33283 0/imm32/no-disp32 +33284 0/imm32/no-xm32 +33285 0/imm32/no-x32 +33286 0x11/imm32/alloc-id:fake +33287 _Primitive-break-if-addr<-named/imm32/next +33288 # - branches to named blocks +33289 _Primitive-break-if-addr<-named: # (payload primitive) 33290 0x11/imm32/alloc-id:fake:payload 33291 0x11/imm32/alloc-id:fake -33292 _string-break-if-addr>=/imm32/name +33292 _string-break-if-addr</imm32/name 33293 0x11/imm32/alloc-id:fake -33294 Single-lit-var/imm32/inouts +33294 Single-lit-var/imm32/inouts 33295 0/imm32/no-outputs 33296 0/imm32/no-outputs 33297 0x11/imm32/alloc-id:fake -33298 _string_0f_83_jump_label/imm32/subx-name +33298 _string_0f_82_jump_label/imm32/subx-name 33299 0/imm32/no-rm32 33300 0/imm32/no-r32 33301 0/imm32/no-imm32 @@ -31679,17 +31679,17 @@ if ('onhashchange' in window) { 33304 0/imm32/no-xm32 33305 0/imm32/no-x32 33306 0x11/imm32/alloc-id:fake -33307 _Primitive-break-if-=-named/imm32/next -33308 _Primitive-break-if-=-named: # (payload primitive) +33307 _Primitive-break-if-addr>=-named/imm32/next +33308 _Primitive-break-if-addr>=-named: # (payload primitive) 33309 0x11/imm32/alloc-id:fake:payload 33310 0x11/imm32/alloc-id:fake -33311 _string-break-if-=/imm32/name +33311 _string-break-if-addr>=/imm32/name 33312 0x11/imm32/alloc-id:fake -33313 Single-lit-var/imm32/inouts +33313 Single-lit-var/imm32/inouts 33314 0/imm32/no-outputs 33315 0/imm32/no-outputs 33316 0x11/imm32/alloc-id:fake -33317 _string_0f_84_jump_label/imm32/subx-name +33317 _string_0f_83_jump_label/imm32/subx-name 33318 0/imm32/no-rm32 33319 0/imm32/no-r32 33320 0/imm32/no-imm32 @@ -31698,17 +31698,17 @@ if ('onhashchange' in window) { 33323 0/imm32/no-xm32 33324 0/imm32/no-x32 33325 0x11/imm32/alloc-id:fake -33326 _Primitive-break-if-!=-named/imm32/next -33327 _Primitive-break-if-!=-named: # (payload primitive) +33326 _Primitive-break-if-=-named/imm32/next +33327 _Primitive-break-if-=-named: # (payload primitive) 33328 0x11/imm32/alloc-id:fake:payload 33329 0x11/imm32/alloc-id:fake -33330 _string-break-if-!=/imm32/name +33330 _string-break-if-=/imm32/name 33331 0x11/imm32/alloc-id:fake -33332 Single-lit-var/imm32/inouts +33332 Single-lit-var/imm32/inouts 33333 0/imm32/no-outputs 33334 0/imm32/no-outputs 33335 0x11/imm32/alloc-id:fake -33336 _string_0f_85_jump_label/imm32/subx-name +33336 _string_0f_84_jump_label/imm32/subx-name 33337 0/imm32/no-rm32 33338 0/imm32/no-r32 33339 0/imm32/no-imm32 @@ -31717,17 +31717,17 @@ if ('onhashchange' in window) { 33342 0/imm32/no-xm32 33343 0/imm32/no-x32 33344 0x11/imm32/alloc-id:fake -33345 _Primitive-break-if-addr<=-named/imm32/next -33346 _Primitive-break-if-addr<=-named: # (payload primitive) +33345 _Primitive-break-if-!=-named/imm32/next +33346 _Primitive-break-if-!=-named: # (payload primitive) 33347 0x11/imm32/alloc-id:fake:payload 33348 0x11/imm32/alloc-id:fake -33349 _string-break-if-addr<=/imm32/name +33349 _string-break-if-!=/imm32/name 33350 0x11/imm32/alloc-id:fake -33351 Single-lit-var/imm32/inouts +33351 Single-lit-var/imm32/inouts 33352 0/imm32/no-outputs 33353 0/imm32/no-outputs 33354 0x11/imm32/alloc-id:fake -33355 _string_0f_86_jump_label/imm32/subx-name +33355 _string_0f_85_jump_label/imm32/subx-name 33356 0/imm32/no-rm32 33357 0/imm32/no-r32 33358 0/imm32/no-imm32 @@ -31736,17 +31736,17 @@ if ('onhashchange' in window) { 33361 0/imm32/no-xm32 33362 0/imm32/no-x32 33363 0x11/imm32/alloc-id:fake -33364 _Primitive-break-if-addr>-named/imm32/next -33365 _Primitive-break-if-addr>-named: # (payload primitive) +33364 _Primitive-break-if-addr<=-named/imm32/next +33365 _Primitive-break-if-addr<=-named: # (payload primitive) 33366 0x11/imm32/alloc-id:fake:payload 33367 0x11/imm32/alloc-id:fake -33368 _string-break-if-addr>/imm32/name +33368 _string-break-if-addr<=/imm32/name 33369 0x11/imm32/alloc-id:fake -33370 Single-lit-var/imm32/inouts +33370 Single-lit-var/imm32/inouts 33371 0/imm32/no-outputs 33372 0/imm32/no-outputs 33373 0x11/imm32/alloc-id:fake -33374 _string_0f_87_jump_label/imm32/subx-name +33374 _string_0f_86_jump_label/imm32/subx-name 33375 0/imm32/no-rm32 33376 0/imm32/no-r32 33377 0/imm32/no-imm32 @@ -31755,17 +31755,17 @@ if ('onhashchange' in window) { 33380 0/imm32/no-xm32 33381 0/imm32/no-x32 33382 0x11/imm32/alloc-id:fake -33383 _Primitive-break-if-<-named/imm32/next -33384 _Primitive-break-if-<-named: # (payload primitive) +33383 _Primitive-break-if-addr>-named/imm32/next +33384 _Primitive-break-if-addr>-named: # (payload primitive) 33385 0x11/imm32/alloc-id:fake:payload 33386 0x11/imm32/alloc-id:fake -33387 _string-break-if-</imm32/name +33387 _string-break-if-addr>/imm32/name 33388 0x11/imm32/alloc-id:fake -33389 Single-lit-var/imm32/inouts +33389 Single-lit-var/imm32/inouts 33390 0/imm32/no-outputs 33391 0/imm32/no-outputs 33392 0x11/imm32/alloc-id:fake -33393 _string_0f_8c_jump_label/imm32/subx-name +33393 _string_0f_87_jump_label/imm32/subx-name 33394 0/imm32/no-rm32 33395 0/imm32/no-r32 33396 0/imm32/no-imm32 @@ -31774,17 +31774,17 @@ if ('onhashchange' in window) { 33399 0/imm32/no-xm32 33400 0/imm32/no-x32 33401 0x11/imm32/alloc-id:fake -33402 _Primitive-break-if->=-named/imm32/next -33403 _Primitive-break-if->=-named: # (payload primitive) +33402 _Primitive-break-if-<-named/imm32/next +33403 _Primitive-break-if-<-named: # (payload primitive) 33404 0x11/imm32/alloc-id:fake:payload 33405 0x11/imm32/alloc-id:fake -33406 _string-break-if->=/imm32/name +33406 _string-break-if-</imm32/name 33407 0x11/imm32/alloc-id:fake -33408 Single-lit-var/imm32/inouts +33408 Single-lit-var/imm32/inouts 33409 0/imm32/no-outputs 33410 0/imm32/no-outputs 33411 0x11/imm32/alloc-id:fake -33412 _string_0f_8d_jump_label/imm32/subx-name +33412 _string_0f_8c_jump_label/imm32/subx-name 33413 0/imm32/no-rm32 33414 0/imm32/no-r32 33415 0/imm32/no-imm32 @@ -31793,17 +31793,17 @@ if ('onhashchange' in window) { 33418 0/imm32/no-xm32 33419 0/imm32/no-x32 33420 0x11/imm32/alloc-id:fake -33421 _Primitive-break-if-<=-named/imm32/next -33422 _Primitive-break-if-<=-named: # (payload primitive) +33421 _Primitive-break-if->=-named/imm32/next +33422 _Primitive-break-if->=-named: # (payload primitive) 33423 0x11/imm32/alloc-id:fake:payload 33424 0x11/imm32/alloc-id:fake -33425 _string-break-if-<=/imm32/name +33425 _string-break-if->=/imm32/name 33426 0x11/imm32/alloc-id:fake -33427 Single-lit-var/imm32/inouts +33427 Single-lit-var/imm32/inouts 33428 0/imm32/no-outputs 33429 0/imm32/no-outputs 33430 0x11/imm32/alloc-id:fake -33431 _string_0f_8e_jump_label/imm32/subx-name +33431 _string_0f_8d_jump_label/imm32/subx-name 33432 0/imm32/no-rm32 33433 0/imm32/no-r32 33434 0/imm32/no-imm32 @@ -31812,17 +31812,17 @@ if ('onhashchange' in window) { 33437 0/imm32/no-xm32 33438 0/imm32/no-x32 33439 0x11/imm32/alloc-id:fake -33440 _Primitive-break-if->-named/imm32/next -33441 _Primitive-break-if->-named: # (payload primitive) +33440 _Primitive-break-if-<=-named/imm32/next +33441 _Primitive-break-if-<=-named: # (payload primitive) 33442 0x11/imm32/alloc-id:fake:payload 33443 0x11/imm32/alloc-id:fake -33444 _string-break-if->/imm32/name +33444 _string-break-if-<=/imm32/name 33445 0x11/imm32/alloc-id:fake -33446 Single-lit-var/imm32/inouts +33446 Single-lit-var/imm32/inouts 33447 0/imm32/no-outputs 33448 0/imm32/no-outputs 33449 0x11/imm32/alloc-id:fake -33450 _string_0f_8f_jump_label/imm32/subx-name +33450 _string_0f_8e_jump_label/imm32/subx-name 33451 0/imm32/no-rm32 33452 0/imm32/no-r32 33453 0/imm32/no-imm32 @@ -31831,17 +31831,17 @@ if ('onhashchange' in window) { 33456 0/imm32/no-xm32 33457 0/imm32/no-x32 33458 0x11/imm32/alloc-id:fake -33459 _Primitive-break-named/imm32/next -33460 _Primitive-break-named: # (payload primitive) +33459 _Primitive-break-if->-named/imm32/next +33460 _Primitive-break-if->-named: # (payload primitive) 33461 0x11/imm32/alloc-id:fake:payload 33462 0x11/imm32/alloc-id:fake -33463 _string-break/imm32/name +33463 _string-break-if->/imm32/name 33464 0x11/imm32/alloc-id:fake -33465 Single-lit-var/imm32/inouts +33465 Single-lit-var/imm32/inouts 33466 0/imm32/no-outputs 33467 0/imm32/no-outputs 33468 0x11/imm32/alloc-id:fake -33469 _string_e9_jump_label/imm32/subx-name +33469 _string_0f_8f_jump_label/imm32/subx-name 33470 0/imm32/no-rm32 33471 0/imm32/no-r32 33472 0/imm32/no-imm32 @@ -31850,17 +31850,17 @@ if ('onhashchange' in window) { 33475 0/imm32/no-xm32 33476 0/imm32/no-x32 33477 0x11/imm32/alloc-id:fake -33478 _Primitive-loop-if-addr<-named/imm32/next -33479 _Primitive-loop-if-addr<-named: # (payload primitive) +33478 _Primitive-break-named/imm32/next +33479 _Primitive-break-named: # (payload primitive) 33480 0x11/imm32/alloc-id:fake:payload 33481 0x11/imm32/alloc-id:fake -33482 _string-loop-if-addr</imm32/name +33482 _string-break/imm32/name 33483 0x11/imm32/alloc-id:fake -33484 Single-lit-var/imm32/inouts +33484 Single-lit-var/imm32/inouts 33485 0/imm32/no-outputs 33486 0/imm32/no-outputs 33487 0x11/imm32/alloc-id:fake -33488 _string_0f_82_jump_label/imm32/subx-name +33488 _string_e9_jump_label/imm32/subx-name 33489 0/imm32/no-rm32 33490 0/imm32/no-r32 33491 0/imm32/no-imm32 @@ -31869,17 +31869,17 @@ if ('onhashchange' in window) { 33494 0/imm32/no-xm32 33495 0/imm32/no-x32 33496 0x11/imm32/alloc-id:fake -33497 _Primitive-loop-if-addr>=-named/imm32/next -33498 _Primitive-loop-if-addr>=-named: # (payload primitive) +33497 _Primitive-loop-if-addr<-named/imm32/next +33498 _Primitive-loop-if-addr<-named: # (payload primitive) 33499 0x11/imm32/alloc-id:fake:payload 33500 0x11/imm32/alloc-id:fake -33501 _string-loop-if-addr>=/imm32/name +33501 _string-loop-if-addr</imm32/name 33502 0x11/imm32/alloc-id:fake -33503 Single-lit-var/imm32/inouts +33503 Single-lit-var/imm32/inouts 33504 0/imm32/no-outputs 33505 0/imm32/no-outputs 33506 0x11/imm32/alloc-id:fake -33507 _string_0f_83_jump_label/imm32/subx-name +33507 _string_0f_82_jump_label/imm32/subx-name 33508 0/imm32/no-rm32 33509 0/imm32/no-r32 33510 0/imm32/no-imm32 @@ -31888,17 +31888,17 @@ if ('onhashchange' in window) { 33513 0/imm32/no-xm32 33514 0/imm32/no-x32 33515 0x11/imm32/alloc-id:fake -33516 _Primitive-loop-if-=-named/imm32/next -33517 _Primitive-loop-if-=-named: # (payload primitive) +33516 _Primitive-loop-if-addr>=-named/imm32/next +33517 _Primitive-loop-if-addr>=-named: # (payload primitive) 33518 0x11/imm32/alloc-id:fake:payload 33519 0x11/imm32/alloc-id:fake -33520 _string-loop-if-=/imm32/name +33520 _string-loop-if-addr>=/imm32/name 33521 0x11/imm32/alloc-id:fake -33522 Single-lit-var/imm32/inouts +33522 Single-lit-var/imm32/inouts 33523 0/imm32/no-outputs 33524 0/imm32/no-outputs 33525 0x11/imm32/alloc-id:fake -33526 _string_0f_84_jump_label/imm32/subx-name +33526 _string_0f_83_jump_label/imm32/subx-name 33527 0/imm32/no-rm32 33528 0/imm32/no-r32 33529 0/imm32/no-imm32 @@ -31907,17 +31907,17 @@ if ('onhashchange' in window) { 33532 0/imm32/no-xm32 33533 0/imm32/no-x32 33534 0x11/imm32/alloc-id:fake -33535 _Primitive-loop-if-!=-named/imm32/next -33536 _Primitive-loop-if-!=-named: # (payload primitive) +33535 _Primitive-loop-if-=-named/imm32/next +33536 _Primitive-loop-if-=-named: # (payload primitive) 33537 0x11/imm32/alloc-id:fake:payload 33538 0x11/imm32/alloc-id:fake -33539 _string-loop-if-!=/imm32/name +33539 _string-loop-if-=/imm32/name 33540 0x11/imm32/alloc-id:fake -33541 Single-lit-var/imm32/inouts +33541 Single-lit-var/imm32/inouts 33542 0/imm32/no-outputs 33543 0/imm32/no-outputs 33544 0x11/imm32/alloc-id:fake -33545 _string_0f_85_jump_label/imm32/subx-name +33545 _string_0f_84_jump_label/imm32/subx-name 33546 0/imm32/no-rm32 33547 0/imm32/no-r32 33548 0/imm32/no-imm32 @@ -31926,17 +31926,17 @@ if ('onhashchange' in window) { 33551 0/imm32/no-xm32 33552 0/imm32/no-x32 33553 0x11/imm32/alloc-id:fake -33554 _Primitive-loop-if-addr<=-named/imm32/next -33555 _Primitive-loop-if-addr<=-named: # (payload primitive) +33554 _Primitive-loop-if-!=-named/imm32/next +33555 _Primitive-loop-if-!=-named: # (payload primitive) 33556 0x11/imm32/alloc-id:fake:payload 33557 0x11/imm32/alloc-id:fake -33558 _string-loop-if-addr<=/imm32/name +33558 _string-loop-if-!=/imm32/name 33559 0x11/imm32/alloc-id:fake -33560 Single-lit-var/imm32/inouts +33560 Single-lit-var/imm32/inouts 33561 0/imm32/no-outputs 33562 0/imm32/no-outputs 33563 0x11/imm32/alloc-id:fake -33564 _string_0f_86_jump_label/imm32/subx-name +33564 _string_0f_85_jump_label/imm32/subx-name 33565 0/imm32/no-rm32 33566 0/imm32/no-r32 33567 0/imm32/no-imm32 @@ -31945,17 +31945,17 @@ if ('onhashchange' in window) { 33570 0/imm32/no-xm32 33571 0/imm32/no-x32 33572 0x11/imm32/alloc-id:fake -33573 _Primitive-loop-if-addr>-named/imm32/next -33574 _Primitive-loop-if-addr>-named: # (payload primitive) +33573 _Primitive-loop-if-addr<=-named/imm32/next +33574 _Primitive-loop-if-addr<=-named: # (payload primitive) 33575 0x11/imm32/alloc-id:fake:payload 33576 0x11/imm32/alloc-id:fake -33577 _string-loop-if-addr>/imm32/name +33577 _string-loop-if-addr<=/imm32/name 33578 0x11/imm32/alloc-id:fake -33579 Single-lit-var/imm32/inouts +33579 Single-lit-var/imm32/inouts 33580 0/imm32/no-outputs 33581 0/imm32/no-outputs 33582 0x11/imm32/alloc-id:fake -33583 _string_0f_87_jump_label/imm32/subx-name +33583 _string_0f_86_jump_label/imm32/subx-name 33584 0/imm32/no-rm32 33585 0/imm32/no-r32 33586 0/imm32/no-imm32 @@ -31964,17 +31964,17 @@ if ('onhashchange' in window) { 33589 0/imm32/no-xm32 33590 0/imm32/no-x32 33591 0x11/imm32/alloc-id:fake -33592 _Primitive-loop-if-<-named/imm32/next -33593 _Primitive-loop-if-<-named: # (payload primitive) +33592 _Primitive-loop-if-addr>-named/imm32/next +33593 _Primitive-loop-if-addr>-named: # (payload primitive) 33594 0x11/imm32/alloc-id:fake:payload 33595 0x11/imm32/alloc-id:fake -33596 _string-loop-if-</imm32/name +33596 _string-loop-if-addr>/imm32/name 33597 0x11/imm32/alloc-id:fake -33598 Single-lit-var/imm32/inouts +33598 Single-lit-var/imm32/inouts 33599 0/imm32/no-outputs 33600 0/imm32/no-outputs 33601 0x11/imm32/alloc-id:fake -33602 _string_0f_8c_jump_label/imm32/subx-name +33602 _string_0f_87_jump_label/imm32/subx-name 33603 0/imm32/no-rm32 33604 0/imm32/no-r32 33605 0/imm32/no-imm32 @@ -31983,17 +31983,17 @@ if ('onhashchange' in window) { 33608 0/imm32/no-xm32 33609 0/imm32/no-x32 33610 0x11/imm32/alloc-id:fake -33611 _Primitive-loop-if->=-named/imm32/next -33612 _Primitive-loop-if->=-named: # (payload primitive) +33611 _Primitive-loop-if-<-named/imm32/next +33612 _Primitive-loop-if-<-named: # (payload primitive) 33613 0x11/imm32/alloc-id:fake:payload 33614 0x11/imm32/alloc-id:fake -33615 _string-loop-if->=/imm32/name +33615 _string-loop-if-</imm32/name 33616 0x11/imm32/alloc-id:fake -33617 Single-lit-var/imm32/inouts +33617 Single-lit-var/imm32/inouts 33618 0/imm32/no-outputs 33619 0/imm32/no-outputs 33620 0x11/imm32/alloc-id:fake -33621 _string_0f_8d_jump_label/imm32/subx-name +33621 _string_0f_8c_jump_label/imm32/subx-name 33622 0/imm32/no-rm32 33623 0/imm32/no-r32 33624 0/imm32/no-imm32 @@ -32002,17 +32002,17 @@ if ('onhashchange' in window) { 33627 0/imm32/no-xm32 33628 0/imm32/no-x32 33629 0x11/imm32/alloc-id:fake -33630 _Primitive-loop-if-<=-named/imm32/next -33631 _Primitive-loop-if-<=-named: # (payload primitive) +33630 _Primitive-loop-if->=-named/imm32/next +33631 _Primitive-loop-if->=-named: # (payload primitive) 33632 0x11/imm32/alloc-id:fake:payload 33633 0x11/imm32/alloc-id:fake -33634 _string-loop-if-<=/imm32/name +33634 _string-loop-if->=/imm32/name 33635 0x11/imm32/alloc-id:fake -33636 Single-lit-var/imm32/inouts +33636 Single-lit-var/imm32/inouts 33637 0/imm32/no-outputs 33638 0/imm32/no-outputs 33639 0x11/imm32/alloc-id:fake -33640 _string_0f_8e_jump_label/imm32/subx-name +33640 _string_0f_8d_jump_label/imm32/subx-name 33641 0/imm32/no-rm32 33642 0/imm32/no-r32 33643 0/imm32/no-imm32 @@ -32021,17 +32021,17 @@ if ('onhashchange' in window) { 33646 0/imm32/no-xm32 33647 0/imm32/no-x32 33648 0x11/imm32/alloc-id:fake -33649 _Primitive-loop-if->-named/imm32/next -33650 _Primitive-loop-if->-named: # (payload primitive) +33649 _Primitive-loop-if-<=-named/imm32/next +33650 _Primitive-loop-if-<=-named: # (payload primitive) 33651 0x11/imm32/alloc-id:fake:payload 33652 0x11/imm32/alloc-id:fake -33653 _string-loop-if->/imm32/name +33653 _string-loop-if-<=/imm32/name 33654 0x11/imm32/alloc-id:fake -33655 Single-lit-var/imm32/inouts +33655 Single-lit-var/imm32/inouts 33656 0/imm32/no-outputs 33657 0/imm32/no-outputs 33658 0x11/imm32/alloc-id:fake -33659 _string_0f_8f_jump_label/imm32/subx-name +33659 _string_0f_8e_jump_label/imm32/subx-name 33660 0/imm32/no-rm32 33661 0/imm32/no-r32 33662 0/imm32/no-imm32 @@ -32040,17 +32040,17 @@ if ('onhashchange' in window) { 33665 0/imm32/no-xm32 33666 0/imm32/no-x32 33667 0x11/imm32/alloc-id:fake -33668 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break -33669 _Primitive-loop-named: # (payload primitive) +33668 _Primitive-loop-if->-named/imm32/next +33669 _Primitive-loop-if->-named: # (payload primitive) 33670 0x11/imm32/alloc-id:fake:payload 33671 0x11/imm32/alloc-id:fake -33672 _string-loop/imm32/name +33672 _string-loop-if->/imm32/name 33673 0x11/imm32/alloc-id:fake -33674 Single-lit-var/imm32/inouts +33674 Single-lit-var/imm32/inouts 33675 0/imm32/no-outputs 33676 0/imm32/no-outputs 33677 0x11/imm32/alloc-id:fake -33678 _string_e9_jump_label/imm32/subx-name +33678 _string_0f_8f_jump_label/imm32/subx-name 33679 0/imm32/no-rm32 33680 0/imm32/no-r32 33681 0/imm32/no-imm32 @@ -32059,37 +32059,37 @@ if ('onhashchange' in window) { 33684 0/imm32/no-xm32 33685 0/imm32/no-x32 33686 0x11/imm32/alloc-id:fake -33687 _Primitive-break-if-float</imm32/next -33688 # - branches based on floating-point comparisons -33689 _Primitive-break-if-float<: # (payload primitive) -33690 0x11/imm32/alloc-id:fake:payload -33691 0x11/imm32/alloc-id:fake -33692 _string-break-if-float</imm32/name -33693 0/imm32/no-inouts -33694 0/imm32/no-inouts +33687 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break +33688 _Primitive-loop-named: # (payload primitive) +33689 0x11/imm32/alloc-id:fake:payload +33690 0x11/imm32/alloc-id:fake +33691 _string-loop/imm32/name +33692 0x11/imm32/alloc-id:fake +33693 Single-lit-var/imm32/inouts +33694 0/imm32/no-outputs 33695 0/imm32/no-outputs -33696 0/imm32/no-outputs -33697 0x11/imm32/alloc-id:fake -33698 _string_0f_82_jump_break/imm32/subx-name -33699 0/imm32/no-rm32 -33700 0/imm32/no-r32 -33701 0/imm32/no-imm32 -33702 0/imm32/no-imm8 -33703 0/imm32/no-disp32 -33704 0/imm32/no-xm32 -33705 0/imm32/no-x32 -33706 0x11/imm32/alloc-id:fake -33707 _Primitive-break-if-float>=/imm32/next -33708 _Primitive-break-if-float>=: # (payload primitive) +33696 0x11/imm32/alloc-id:fake +33697 _string_e9_jump_label/imm32/subx-name +33698 0/imm32/no-rm32 +33699 0/imm32/no-r32 +33700 0/imm32/no-imm32 +33701 0/imm32/no-imm8 +33702 1/imm32/disp32-is-first-inout +33703 0/imm32/no-xm32 +33704 0/imm32/no-x32 +33705 0x11/imm32/alloc-id:fake +33706 _Primitive-break-if-float</imm32/next +33707 # - branches based on floating-point comparisons +33708 _Primitive-break-if-float<: # (payload primitive) 33709 0x11/imm32/alloc-id:fake:payload 33710 0x11/imm32/alloc-id:fake -33711 _string-break-if-float>=/imm32/name +33711 _string-break-if-float</imm32/name 33712 0/imm32/no-inouts 33713 0/imm32/no-inouts 33714 0/imm32/no-outputs 33715 0/imm32/no-outputs 33716 0x11/imm32/alloc-id:fake -33717 _string_0f_83_jump_break/imm32/subx-name +33717 _string_0f_82_jump_break/imm32/subx-name 33718 0/imm32/no-rm32 33719 0/imm32/no-r32 33720 0/imm32/no-imm32 @@ -32098,17 +32098,17 @@ if ('onhashchange' in window) { 33723 0/imm32/no-xm32 33724 0/imm32/no-x32 33725 0x11/imm32/alloc-id:fake -33726 _Primitive-break-if-float<=/imm32/next -33727 _Primitive-break-if-float<=: # (payload primitive) +33726 _Primitive-break-if-float>=/imm32/next +33727 _Primitive-break-if-float>=: # (payload primitive) 33728 0x11/imm32/alloc-id:fake:payload 33729 0x11/imm32/alloc-id:fake -33730 _string-break-if-float<=/imm32/name +33730 _string-break-if-float>=/imm32/name 33731 0/imm32/no-inouts 33732 0/imm32/no-inouts 33733 0/imm32/no-outputs 33734 0/imm32/no-outputs 33735 0x11/imm32/alloc-id:fake -33736 _string_0f_86_jump_break/imm32/subx-name +33736 _string_0f_83_jump_break/imm32/subx-name 33737 0/imm32/no-rm32 33738 0/imm32/no-r32 33739 0/imm32/no-imm32 @@ -32117,17 +32117,17 @@ if ('onhashchange' in window) { 33742 0/imm32/no-xm32 33743 0/imm32/no-x32 33744 0x11/imm32/alloc-id:fake -33745 _Primitive-break-if-float>/imm32/next -33746 _Primitive-break-if-float>: # (payload primitive) +33745 _Primitive-break-if-float<=/imm32/next +33746 _Primitive-break-if-float<=: # (payload primitive) 33747 0x11/imm32/alloc-id:fake:payload 33748 0x11/imm32/alloc-id:fake -33749 _string-break-if-float>/imm32/name +33749 _string-break-if-float<=/imm32/name 33750 0/imm32/no-inouts 33751 0/imm32/no-inouts 33752 0/imm32/no-outputs 33753 0/imm32/no-outputs 33754 0x11/imm32/alloc-id:fake -33755 _string_0f_87_jump_break/imm32/subx-name +33755 _string_0f_86_jump_break/imm32/subx-name 33756 0/imm32/no-rm32 33757 0/imm32/no-r32 33758 0/imm32/no-imm32 @@ -32136,17 +32136,17 @@ if ('onhashchange' in window) { 33761 0/imm32/no-xm32 33762 0/imm32/no-x32 33763 0x11/imm32/alloc-id:fake -33764 _Primitive-loop-if-float</imm32/next -33765 _Primitive-loop-if-float<: # (payload primitive) +33764 _Primitive-break-if-float>/imm32/next +33765 _Primitive-break-if-float>: # (payload primitive) 33766 0x11/imm32/alloc-id:fake:payload 33767 0x11/imm32/alloc-id:fake -33768 _string-loop-if-float</imm32/name +33768 _string-break-if-float>/imm32/name 33769 0/imm32/no-inouts 33770 0/imm32/no-inouts 33771 0/imm32/no-outputs 33772 0/imm32/no-outputs 33773 0x11/imm32/alloc-id:fake -33774 _string_0f_82_jump_loop/imm32/subx-name +33774 _string_0f_87_jump_break/imm32/subx-name 33775 0/imm32/no-rm32 33776 0/imm32/no-r32 33777 0/imm32/no-imm32 @@ -32155,17 +32155,17 @@ if ('onhashchange' in window) { 33780 0/imm32/no-xm32 33781 0/imm32/no-x32 33782 0x11/imm32/alloc-id:fake -33783 _Primitive-loop-if-float>=/imm32/next -33784 _Primitive-loop-if-float>=: # (payload primitive) +33783 _Primitive-loop-if-float</imm32/next +33784 _Primitive-loop-if-float<: # (payload primitive) 33785 0x11/imm32/alloc-id:fake:payload 33786 0x11/imm32/alloc-id:fake -33787 _string-loop-if-float>=/imm32/name +33787 _string-loop-if-float</imm32/name 33788 0/imm32/no-inouts 33789 0/imm32/no-inouts 33790 0/imm32/no-outputs 33791 0/imm32/no-outputs 33792 0x11/imm32/alloc-id:fake -33793 _string_0f_83_jump_loop/imm32/subx-name +33793 _string_0f_82_jump_loop/imm32/subx-name 33794 0/imm32/no-rm32 33795 0/imm32/no-r32 33796 0/imm32/no-imm32 @@ -32174,17 +32174,17 @@ if ('onhashchange' in window) { 33799 0/imm32/no-xm32 33800 0/imm32/no-x32 33801 0x11/imm32/alloc-id:fake -33802 _Primitive-loop-if-float<=/imm32/next -33803 _Primitive-loop-if-float<=: # (payload primitive) +33802 _Primitive-loop-if-float>=/imm32/next +33803 _Primitive-loop-if-float>=: # (payload primitive) 33804 0x11/imm32/alloc-id:fake:payload 33805 0x11/imm32/alloc-id:fake -33806 _string-loop-if-float<=/imm32/name +33806 _string-loop-if-float>=/imm32/name 33807 0/imm32/no-inouts 33808 0/imm32/no-inouts 33809 0/imm32/no-outputs 33810 0/imm32/no-outputs 33811 0x11/imm32/alloc-id:fake -33812 _string_0f_86_jump_loop/imm32/subx-name +33812 _string_0f_83_jump_loop/imm32/subx-name 33813 0/imm32/no-rm32 33814 0/imm32/no-r32 33815 0/imm32/no-imm32 @@ -32193,17 +32193,17 @@ if ('onhashchange' in window) { 33818 0/imm32/no-xm32 33819 0/imm32/no-x32 33820 0x11/imm32/alloc-id:fake -33821 _Primitive-loop-if-float>/imm32/next -33822 _Primitive-loop-if-float>: # (payload primitive) +33821 _Primitive-loop-if-float<=/imm32/next +33822 _Primitive-loop-if-float<=: # (payload primitive) 33823 0x11/imm32/alloc-id:fake:payload 33824 0x11/imm32/alloc-id:fake -33825 _string-loop-if-float>/imm32/name +33825 _string-loop-if-float<=/imm32/name 33826 0/imm32/no-inouts 33827 0/imm32/no-inouts 33828 0/imm32/no-outputs 33829 0/imm32/no-outputs 33830 0x11/imm32/alloc-id:fake -33831 _string_0f_87_jump_loop/imm32/subx-name +33831 _string_0f_86_jump_loop/imm32/subx-name 33832 0/imm32/no-rm32 33833 0/imm32/no-r32 33834 0/imm32/no-imm32 @@ -32212,36 +32212,36 @@ if ('onhashchange' in window) { 33837 0/imm32/no-xm32 33838 0/imm32/no-x32 33839 0x11/imm32/alloc-id:fake -33840 _Primitive-break-if-float<-named/imm32/next -33841 _Primitive-break-if-float<-named: # (payload primitive) +33840 _Primitive-loop-if-float>/imm32/next +33841 _Primitive-loop-if-float>: # (payload primitive) 33842 0x11/imm32/alloc-id:fake:payload 33843 0x11/imm32/alloc-id:fake -33844 _string-break-if-float</imm32/name -33845 0x11/imm32/alloc-id:fake -33846 Single-lit-var/imm32/inouts +33844 _string-loop-if-float>/imm32/name +33845 0/imm32/no-inouts +33846 0/imm32/no-inouts 33847 0/imm32/no-outputs 33848 0/imm32/no-outputs 33849 0x11/imm32/alloc-id:fake -33850 _string_0f_82_jump_label/imm32/subx-name +33850 _string_0f_87_jump_loop/imm32/subx-name 33851 0/imm32/no-rm32 33852 0/imm32/no-r32 33853 0/imm32/no-imm32 33854 0/imm32/no-imm8 -33855 1/imm32/disp32-is-first-inout +33855 0/imm32/no-disp32 33856 0/imm32/no-xm32 33857 0/imm32/no-x32 33858 0x11/imm32/alloc-id:fake -33859 _Primitive-break-if-float>=-named/imm32/next -33860 _Primitive-break-if-float>=-named: # (payload primitive) +33859 _Primitive-break-if-float<-named/imm32/next +33860 _Primitive-break-if-float<-named: # (payload primitive) 33861 0x11/imm32/alloc-id:fake:payload 33862 0x11/imm32/alloc-id:fake -33863 _string-break-if-float>=/imm32/name +33863 _string-break-if-float</imm32/name 33864 0x11/imm32/alloc-id:fake -33865 Single-lit-var/imm32/inouts +33865 Single-lit-var/imm32/inouts 33866 0/imm32/no-outputs 33867 0/imm32/no-outputs 33868 0x11/imm32/alloc-id:fake -33869 _string_0f_83_jump_label/imm32/subx-name +33869 _string_0f_82_jump_label/imm32/subx-name 33870 0/imm32/no-rm32 33871 0/imm32/no-r32 33872 0/imm32/no-imm32 @@ -32250,17 +32250,17 @@ if ('onhashchange' in window) { 33875 0/imm32/no-xm32 33876 0/imm32/no-x32 33877 0x11/imm32/alloc-id:fake -33878 _Primitive-break-if-float<=-named/imm32/next -33879 _Primitive-break-if-float<=-named: # (payload primitive) +33878 _Primitive-break-if-float>=-named/imm32/next +33879 _Primitive-break-if-float>=-named: # (payload primitive) 33880 0x11/imm32/alloc-id:fake:payload 33881 0x11/imm32/alloc-id:fake -33882 _string-break-if-float<=/imm32/name +33882 _string-break-if-float>=/imm32/name 33883 0x11/imm32/alloc-id:fake -33884 Single-lit-var/imm32/inouts +33884 Single-lit-var/imm32/inouts 33885 0/imm32/no-outputs 33886 0/imm32/no-outputs 33887 0x11/imm32/alloc-id:fake -33888 _string_0f_86_jump_label/imm32/subx-name +33888 _string_0f_83_jump_label/imm32/subx-name 33889 0/imm32/no-rm32 33890 0/imm32/no-r32 33891 0/imm32/no-imm32 @@ -32269,17 +32269,17 @@ if ('onhashchange' in window) { 33894 0/imm32/no-xm32 33895 0/imm32/no-x32 33896 0x11/imm32/alloc-id:fake -33897 _Primitive-break-if-float>-named/imm32/next -33898 _Primitive-break-if-float>-named: # (payload primitive) +33897 _Primitive-break-if-float<=-named/imm32/next +33898 _Primitive-break-if-float<=-named: # (payload primitive) 33899 0x11/imm32/alloc-id:fake:payload 33900 0x11/imm32/alloc-id:fake -33901 _string-break-if-float>/imm32/name +33901 _string-break-if-float<=/imm32/name 33902 0x11/imm32/alloc-id:fake -33903 Single-lit-var/imm32/inouts +33903 Single-lit-var/imm32/inouts 33904 0/imm32/no-outputs 33905 0/imm32/no-outputs 33906 0x11/imm32/alloc-id:fake -33907 _string_0f_87_jump_label/imm32/subx-name +33907 _string_0f_86_jump_label/imm32/subx-name 33908 0/imm32/no-rm32 33909 0/imm32/no-r32 33910 0/imm32/no-imm32 @@ -32288,17 +32288,17 @@ if ('onhashchange' in window) { 33913 0/imm32/no-xm32 33914 0/imm32/no-x32 33915 0x11/imm32/alloc-id:fake -33916 _Primitive-loop-if-float<-named/imm32/next -33917 _Primitive-loop-if-float<-named: # (payload primitive) +33916 _Primitive-break-if-float>-named/imm32/next +33917 _Primitive-break-if-float>-named: # (payload primitive) 33918 0x11/imm32/alloc-id:fake:payload 33919 0x11/imm32/alloc-id:fake -33920 _string-loop-if-float</imm32/name +33920 _string-break-if-float>/imm32/name 33921 0x11/imm32/alloc-id:fake -33922 Single-lit-var/imm32/inouts +33922 Single-lit-var/imm32/inouts 33923 0/imm32/no-outputs 33924 0/imm32/no-outputs 33925 0x11/imm32/alloc-id:fake -33926 _string_0f_82_jump_label/imm32/subx-name +33926 _string_0f_87_jump_label/imm32/subx-name 33927 0/imm32/no-rm32 33928 0/imm32/no-r32 33929 0/imm32/no-imm32 @@ -32307,17 +32307,17 @@ if ('onhashchange' in window) { 33932 0/imm32/no-xm32 33933 0/imm32/no-x32 33934 0x11/imm32/alloc-id:fake -33935 _Primitive-loop-if-float>=-named/imm32/next -33936 _Primitive-loop-if-float>=-named: # (payload primitive) +33935 _Primitive-loop-if-float<-named/imm32/next +33936 _Primitive-loop-if-float<-named: # (payload primitive) 33937 0x11/imm32/alloc-id:fake:payload 33938 0x11/imm32/alloc-id:fake -33939 _string-loop-if-float>=/imm32/name +33939 _string-loop-if-float</imm32/name 33940 0x11/imm32/alloc-id:fake -33941 Single-lit-var/imm32/inouts +33941 Single-lit-var/imm32/inouts 33942 0/imm32/no-outputs 33943 0/imm32/no-outputs 33944 0x11/imm32/alloc-id:fake -33945 _string_0f_83_jump_label/imm32/subx-name +33945 _string_0f_82_jump_label/imm32/subx-name 33946 0/imm32/no-rm32 33947 0/imm32/no-r32 33948 0/imm32/no-imm32 @@ -32326,17 +32326,17 @@ if ('onhashchange' in window) { 33951 0/imm32/no-xm32 33952 0/imm32/no-x32 33953 0x11/imm32/alloc-id:fake -33954 _Primitive-loop-if-float<=-named/imm32/next -33955 _Primitive-loop-if-float<=-named: # (payload primitive) +33954 _Primitive-loop-if-float>=-named/imm32/next +33955 _Primitive-loop-if-float>=-named: # (payload primitive) 33956 0x11/imm32/alloc-id:fake:payload 33957 0x11/imm32/alloc-id:fake -33958 _string-loop-if-float<=/imm32/name +33958 _string-loop-if-float>=/imm32/name 33959 0x11/imm32/alloc-id:fake -33960 Single-lit-var/imm32/inouts +33960 Single-lit-var/imm32/inouts 33961 0/imm32/no-outputs 33962 0/imm32/no-outputs 33963 0x11/imm32/alloc-id:fake -33964 _string_0f_86_jump_label/imm32/subx-name +33964 _string_0f_83_jump_label/imm32/subx-name 33965 0/imm32/no-rm32 33966 0/imm32/no-r32 33967 0/imm32/no-imm32 @@ -32345,17 +32345,17 @@ if ('onhashchange' in window) { 33970 0/imm32/no-xm32 33971 0/imm32/no-x32 33972 0x11/imm32/alloc-id:fake -33973 _Primitive-loop-if-float>-named/imm32/next -33974 _Primitive-loop-if-float>-named: # (payload primitive) +33973 _Primitive-loop-if-float<=-named/imm32/next +33974 _Primitive-loop-if-float<=-named: # (payload primitive) 33975 0x11/imm32/alloc-id:fake:payload 33976 0x11/imm32/alloc-id:fake -33977 _string-loop-if-float>/imm32/name +33977 _string-loop-if-float<=/imm32/name 33978 0x11/imm32/alloc-id:fake -33979 Single-lit-var/imm32/inouts +33979 Single-lit-var/imm32/inouts 33980 0/imm32/no-outputs 33981 0/imm32/no-outputs 33982 0x11/imm32/alloc-id:fake -33983 _string_0f_87_jump_label/imm32/subx-name +33983 _string_0f_86_jump_label/imm32/subx-name 33984 0/imm32/no-rm32 33985 0/imm32/no-r32 33986 0/imm32/no-imm32 @@ -32363,4740 +32363,4788 @@ if ('onhashchange' in window) { 33988 1/imm32/disp32-is-first-inout 33989 0/imm32/no-xm32 33990 0/imm32/no-x32 -33991 0/imm32/next -33992 0/imm32/next -33993 -33994 # string literals for Mu instructions -33995 _string-add: # (payload array byte) -33996 0x11/imm32/alloc-id:fake:payload -33997 # "add" -33998 0x3/imm32/size -33999 0x61/a 0x64/d 0x64/d -34000 _string-address: # (payload array byte) -34001 0x11/imm32/alloc-id:fake:payload -34002 # "address" -34003 0x7/imm32/size -34004 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s -34005 _string-add-to: # (payload array byte) -34006 0x11/imm32/alloc-id:fake:payload -34007 # "add-to" -34008 0x6/imm32/size -34009 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -34010 _string-and: # (payload array byte) -34011 0x11/imm32/alloc-id:fake:payload -34012 # "and" -34013 0x3/imm32/size -34014 0x61/a 0x6e/n 0x64/d -34015 _string-and-with: # (payload array byte) -34016 0x11/imm32/alloc-id:fake:payload -34017 # "and-with" -34018 0x8/imm32/size -34019 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -34020 _string-break: # (payload array byte) -34021 0x11/imm32/alloc-id:fake:payload -34022 # "break" -34023 0x5/imm32/size -34024 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k -34025 _string-break-if-<: # (payload array byte) -34026 0x11/imm32/alloc-id:fake:payload -34027 # "break-if-<" -34028 0xa/imm32/size -34029 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -34030 _string-break-if-<=: # (payload array byte) -34031 0x11/imm32/alloc-id:fake:payload -34032 # "break-if-<=" -34033 0xb/imm32/size -34034 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -34035 _string-break-if-=: # (payload array byte) -34036 0x11/imm32/alloc-id:fake:payload -34037 # "break-if-=" -34038 0xa/imm32/size -34039 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -34040 _string-break-if->: # (payload array byte) -34041 0x11/imm32/alloc-id:fake:payload -34042 # "break-if->" -34043 0xa/imm32/size -34044 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -34045 _string-break-if->=: # (payload array byte) -34046 0x11/imm32/alloc-id:fake:payload -34047 # "break-if->=" -34048 0xb/imm32/size -34049 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -34050 _string-break-if-!=: # (payload array byte) -34051 0x11/imm32/alloc-id:fake:payload -34052 # "break-if-!=" -34053 0xb/imm32/size -34054 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -34055 _string-break-if-addr<: # (payload array byte) -34056 0x11/imm32/alloc-id:fake:payload -34057 # "break-if-addr<" -34058 0xe/imm32/size -34059 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -34060 _string-break-if-addr<=: # (payload array byte) -34061 0x11/imm32/alloc-id:fake:payload -34062 # "break-if-addr<=" -34063 0xf/imm32/size -34064 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -34065 _string-break-if-addr>: # (payload array byte) -34066 0x11/imm32/alloc-id:fake:payload -34067 # "break-if-addr>" -34068 0xe/imm32/size -34069 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -34070 _string-break-if-addr>=: # (payload array byte) -34071 0x11/imm32/alloc-id:fake:payload -34072 # "break-if-addr>=" -34073 0xf/imm32/size -34074 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -34075 _string-break-if-float<: # (payload array byte) -34076 0x11/imm32/alloc-id:fake:payload -34077 # "break-if-float<" -34078 0xf/imm32/size -34079 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< -34080 _string-break-if-float<=: # (payload array byte) -34081 0x11/imm32/alloc-id:fake:payload -34082 # "break-if-float<=" -34083 0x10/imm32/size -34084 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< 0x3d/= -34085 _string-break-if-float>: # (payload array byte) -34086 0x11/imm32/alloc-id:fake:payload -34087 # "break-if-float>" -34088 0xf/imm32/size -34089 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> -34090 _string-break-if-float>=: # (payload array byte) -34091 0x11/imm32/alloc-id:fake:payload -34092 # "break-if-float>=" -34093 0x10/imm32/size -34094 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/= -34095 _string-break-if-carry: # (payload array byte) -34096 0x11/imm32/alloc-id:fake:payload -34097 # "break-if-carry" -34098 0xe/imm32/size -34099 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y -34100 _string-break-if-not-carry: # (payload array byte) -34101 0x11/imm32/alloc-id:fake:payload -34102 # "break-if-not-carry" -34103 0x12/imm32/size -34104 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y -34105 _string-break-if-overflow: # (payload array byte) -34106 0x11/imm32/alloc-id:fake:payload -34107 # "break-if-overflow" -34108 0x11/imm32/size -34109 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w -34110 _string-break-if-not-overflow: # (payload array byte) -34111 0x11/imm32/alloc-id:fake:payload -34112 # "break-if-not-overflow" -34113 0x15/imm32/size -34114 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w -34115 _string-compare: # (payload array byte) -34116 0x11/imm32/alloc-id:fake:payload -34117 # "compare" -34118 0x7/imm32/size -34119 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -34120 _string-copy: # (payload array byte) -34121 0x11/imm32/alloc-id:fake:payload -34122 # "copy" -34123 0x4/imm32/size -34124 0x63/c 0x6f/o 0x70/p 0x79/y -34125 _string-copy-to: # (payload array byte) -34126 0x11/imm32/alloc-id:fake:payload -34127 # "copy-to" -34128 0x7/imm32/size -34129 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o -34130 _string-copy-byte: -34131 0x11/imm32/alloc-id:fake:payload -34132 # "copy-byte" -34133 0x9/imm32/size -34134 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e -34135 _string-copy-byte-to: -34136 0x11/imm32/alloc-id:fake:payload -34137 # "copy-byte-to" -34138 0xc/imm32/size -34139 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x74/t 0x6f/o -34140 _string-decrement: # (payload array byte) -34141 0x11/imm32/alloc-id:fake:payload -34142 # "decrement" -34143 0x9/imm32/size -34144 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -34145 _string-increment: # (payload array byte) -34146 0x11/imm32/alloc-id:fake:payload -34147 # "increment" -34148 0x9/imm32/size -34149 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -34150 _string-loop: # (payload array byte) -34151 0x11/imm32/alloc-id:fake:payload -34152 # "loop" -34153 0x4/imm32/size -34154 0x6c/l 0x6f/o 0x6f/o 0x70/p -34155 _string-loop-if-<: # (payload array byte) -34156 0x11/imm32/alloc-id:fake:payload -34157 # "loop-if-<" -34158 0x9/imm32/size -34159 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -34160 _string-loop-if-<=: # (payload array byte) -34161 0x11/imm32/alloc-id:fake:payload -34162 # "loop-if-<=" -34163 0xa/imm32/size -34164 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -34165 _string-loop-if-=: # (payload array byte) -34166 0x11/imm32/alloc-id:fake:payload -34167 # "loop-if-=" -34168 0x9/imm32/size -34169 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -34170 _string-loop-if->: # (payload array byte) -34171 0x11/imm32/alloc-id:fake:payload -34172 # "loop-if->" -34173 0x9/imm32/size -34174 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -34175 _string-loop-if->=: # (payload array byte) -34176 0x11/imm32/alloc-id:fake:payload -34177 # "loop-if->=" -34178 0xa/imm32/size -34179 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -34180 _string-loop-if-!=: # (payload array byte) -34181 0x11/imm32/alloc-id:fake:payload -34182 # "loop-if-!=" -34183 0xa/imm32/size -34184 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -34185 _string-loop-if-addr<: # (payload array byte) -34186 0x11/imm32/alloc-id:fake:payload -34187 # "loop-if-addr<" -34188 0xd/imm32/size -34189 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -34190 _string-loop-if-addr<=: # (payload array byte) -34191 0x11/imm32/alloc-id:fake:payload -34192 # "loop-if-addr<=" -34193 0xe/imm32/size -34194 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -34195 _string-loop-if-addr>: # (payload array byte) -34196 0x11/imm32/alloc-id:fake:payload -34197 # "loop-if-addr>" -34198 0xd/imm32/size -34199 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -34200 _string-loop-if-addr>=: # (payload array byte) -34201 0x11/imm32/alloc-id:fake:payload -34202 # "loop-if-addr>=" -34203 0xe/imm32/size -34204 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -34205 _string-loop-if-float<: # (payload array byte) -34206 0x11/imm32/alloc-id:fake:payload -34207 # "loop-if-float<" -34208 0xe/imm32/size -34209 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< -34210 _string-loop-if-float<=: # (payload array byte) -34211 0x11/imm32/alloc-id:fake:payload -34212 # "loop-if-float<=" -34213 0xf/imm32/size -34214 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< 0x3d/= -34215 _string-loop-if-float>: # (payload array byte) -34216 0x11/imm32/alloc-id:fake:payload -34217 # "loop-if-float>" -34218 0xe/imm32/size -34219 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> -34220 _string-loop-if-float>=: # (payload array byte) -34221 0x11/imm32/alloc-id:fake:payload -34222 # "loop-if-float>=" -34223 0xf/imm32/size -34224 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/= -34225 _string-loop-if-carry: # (payload array byte) -34226 0x11/imm32/alloc-id:fake:payload -34227 # "loop-if-carry" -34228 0xd/imm32/size -34229 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y -34230 _string-loop-if-not-carry: # (payload array byte) -34231 0x11/imm32/alloc-id:fake:payload -34232 # "loop-if-not-carry" -34233 0x11/imm32/size -34234 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y -34235 _string-loop-if-overflow: # (payload array byte) -34236 0x11/imm32/alloc-id:fake:payload -34237 # "loop-if-overflow" -34238 0x10/imm32/size -34239 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w -34240 _string-loop-if-not-overflow: # (payload array byte) -34241 0x11/imm32/alloc-id:fake:payload -34242 # "loop-if-not-overflow" -34243 0x14/imm32/size -34244 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w -34245 _string-multiply: # (payload array byte) -34246 0x11/imm32/alloc-id:fake:payload -34247 # "multiply" -34248 0x8/imm32/size -34249 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -34250 _string-convert: # (payload array byte) -34251 0x11/imm32/alloc-id:fake:payload -34252 # "convert" -34253 0x7/imm32/size -34254 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t -34255 _string-truncate: # (payload array byte) -34256 0x11/imm32/alloc-id:fake:payload -34257 # "truncate" -34258 0x8/imm32/size -34259 0x74/t 0x72/r 0x75/u 0x6e/n 0x63/c 0x61/a 0x74/t 0x65/e -34260 _string-reinterpret: # (payload array byte) -34261 0x11/imm32/alloc-id:fake:payload -34262 # "reinterpret" -34263 0xb/imm32/size -34264 0x72/r 0x65/e 0x69/i 0x6e/n 0x74/t 0x65/e 0x72/r 0x70/p 0x72/r 0x65/e 0x74/t -34265 _string-divide: -34266 0x11/imm32/alloc-id:fake:payload -34267 # "divide" -34268 0x6/imm32/size -34269 0x64/d 0x69/i 0x76/v 0x69/i 0x64/d 0x65/e -34270 _string-max: -34271 0x11/imm32/alloc-id:fake:payload -34272 # "max" -34273 0x3/imm32/size -34274 0x6d/m 0x61/a 0x78/x -34275 _string-min: -34276 0x11/imm32/alloc-id:fake:payload -34277 # "min" -34278 0x3/imm32/size -34279 0x6d/m 0x69/i 0x6e/n -34280 _string-reciprocal: -34281 0x11/imm32/alloc-id:fake:payload -34282 # "reciprocal" -34283 0xa/imm32/size -34284 0x72/r 0x65/e 0x63/c 0x69/i 0x70/p 0x72/r 0x6f/o 0x63/c 0x61/a 0x6c/l -34285 _string-square-root: -34286 0x11/imm32/alloc-id:fake:payload -34287 # "square-root" -34288 0xb/imm32/size -34289 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t -34290 _string-inverse-square-root: -34291 0x11/imm32/alloc-id:fake:payload -34292 # "inverse-square-root" -34293 0x13/imm32/size -34294 0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/dash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t -34295 _string-negate: # (payload array byte) -34296 0x11/imm32/alloc-id:fake:payload -34297 # "negate" -34298 0x6/imm32/size -34299 0x6e/n 0x65/e 0x67/g 0x61/a 0x74/t 0x65/e -34300 _string-not: # (payload array byte) -34301 0x11/imm32/alloc-id:fake:payload -34302 # "not" -34303 0x3/imm32/size -34304 0x6e/n 0x6f/o 0x74/t -34305 _string-or: # (payload array byte) -34306 0x11/imm32/alloc-id:fake:payload -34307 # "or" -34308 0x2/imm32/size -34309 0x6f/o 0x72/r -34310 _string-or-with: # (payload array byte) -34311 0x11/imm32/alloc-id:fake:payload -34312 # "or-with" -34313 0x7/imm32/size -34314 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -34315 _string-subtract: # (payload array byte) -34316 0x11/imm32/alloc-id:fake:payload -34317 # "subtract" -34318 0x8/imm32/size -34319 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -34320 _string-subtract-from: # (payload array byte) -34321 0x11/imm32/alloc-id:fake:payload -34322 # "subtract-from" -34323 0xd/imm32/size -34324 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m -34325 _string-xor: # (payload array byte) -34326 0x11/imm32/alloc-id:fake:payload -34327 # "xor" -34328 0x3/imm32/size -34329 0x78/x 0x6f/o 0x72/r -34330 _string-xor-with: # (payload array byte) -34331 0x11/imm32/alloc-id:fake:payload -34332 # "xor-with" -34333 0x8/imm32/size -34334 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -34335 _string-shift-left: # (payload array byte) -34336 0x11/imm32/alloc-id:fake:payload -34337 # "shift-left" -34338 0xa/imm32/size -34339 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x6c/l 0x65/e 0x66/f 0x74/t -34340 _string-shift-right: # (payload array byte) -34341 0x11/imm32/alloc-id:fake:payload -34342 # "shift-right" -34343 0xb/imm32/size -34344 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t -34345 _string-shift-right-signed: # (payload array byte) -34346 0x11/imm32/alloc-id:fake:payload -34347 # "shift-right-signed" -34348 0x12/imm32/size -34349 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n 0x65/e 0x64/d -34350 -34351 # string literals for SubX instructions -34352 _string_01_add_to: # (payload array byte) -34353 0x11/imm32/alloc-id:fake:payload -34354 # "01/add-to" -34355 0x9/imm32/size -34356 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -34357 _string_03_add: # (payload array byte) -34358 0x11/imm32/alloc-id:fake:payload -34359 # "03/add" -34360 0x6/imm32/size -34361 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d -34362 _string_05_add_to_eax: # (payload array byte) -34363 0x11/imm32/alloc-id:fake:payload -34364 # "05/add-to-eax" -34365 0xd/imm32/size -34366 0x30/0 0x35/5 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x -34367 _string_09_or_with: # (payload array byte) -34368 0x11/imm32/alloc-id:fake:payload -34369 # "09/or-with" -34370 0xa/imm32/size -34371 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -34372 _string_0b_or: # (payload array byte) -34373 0x11/imm32/alloc-id:fake:payload -34374 # "0b/or" -34375 0x5/imm32/size -34376 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r -34377 _string_0d_or_with_eax: # (payload array byte) -34378 0x11/imm32/alloc-id:fake:payload -34379 # "0d/or-with-eax" -34380 0xe/imm32/size -34381 0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -34382 _string_0f_80_jump_label: # (payload array byte) -34383 0x11/imm32/alloc-id:fake:payload -34384 # "0f 80/jump-if-overflow" -34385 0x16/imm32/size -34386 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w -34387 _string_0f_80_jump_break: # (payload array byte) -34388 0x11/imm32/alloc-id:fake:payload -34389 # "0f 80/jump-if-overflow break/disp32" -34390 0x23/imm32/size -34391 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34392 _string_0f_80_jump_loop: # (payload array byte) -34393 0x11/imm32/alloc-id:fake:payload -34394 # "0f 80/jump-if-overflow loop/disp32" -34395 0x22/imm32/size -34396 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34397 _string_0f_81_jump_label: # (payload array byte) -34398 0x11/imm32/alloc-id:fake:payload -34399 # "0f 81/jump-if-not-overflow" -34400 0x1a/imm32/size -34401 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w -34402 _string_0f_81_jump_break: # (payload array byte) -34403 0x11/imm32/alloc-id:fake:payload -34404 # "0f 81/jump-if-not-overflow break/disp32" -34405 0x27/imm32/size -34406 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34407 _string_0f_81_jump_loop: # (payload array byte) -34408 0x11/imm32/alloc-id:fake:payload -34409 # "0f 81/jump-if-not-overflow loop/disp32" -34410 0x26/imm32/size -34411 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34412 _string_0f_82_jump_label: # (payload array byte) -34413 0x11/imm32/alloc-id:fake:payload -34414 # "0f 82/jump-if-addr<" -34415 0x13/imm32/size -34416 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< -34417 _string_0f_82_jump_break: # (payload array byte) -34418 0x11/imm32/alloc-id:fake:payload -34419 # "0f 82/jump-if-addr< break/disp32" -34420 0x20/imm32/size -34421 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34422 _string_0f_82_jump_loop: # (payload array byte) -34423 0x11/imm32/alloc-id:fake:payload -34424 # "0f 82/jump-if-addr< loop/disp32" -34425 0x1f/imm32/size -34426 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34427 _string_0f_83_jump_label: # (payload array byte) -34428 0x11/imm32/alloc-id:fake:payload -34429 # "0f 83/jump-if-addr>=" -34430 0x14/imm32/size -34431 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= -34432 _string_0f_83_jump_break: # (payload array byte) -34433 0x11/imm32/alloc-id:fake:payload -34434 # "0f 83/jump-if-addr>= break/disp32" -34435 0x21/imm32/size -34436 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34437 _string_0f_83_jump_loop: # (payload array byte) -34438 0x11/imm32/alloc-id:fake:payload -34439 # "0f 83/jump-if-addr>= loop/disp32" -34440 0x20/imm32/size -34441 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34442 _string_0f_84_jump_label: # (payload array byte) -34443 0x11/imm32/alloc-id:fake:payload -34444 # "0f 84/jump-if-=" -34445 0xf/imm32/size -34446 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -34447 _string_0f_84_jump_break: # (payload array byte) -34448 0x11/imm32/alloc-id:fake:payload -34449 # "0f 84/jump-if-= break/disp32" -34450 0x1c/imm32/size -34451 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34452 _string_0f_84_jump_loop: # (payload array byte) -34453 0x11/imm32/alloc-id:fake:payload -34454 # "0f 84/jump-if-= loop/disp32" -34455 0x1a/imm32/size -34456 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34457 _string_0f_85_jump_label: # (payload array byte) -34458 0x11/imm32/alloc-id:fake:payload -34459 # "0f 85/jump-if-!=" -34460 0x10/imm32/size -34461 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -34462 _string_0f_85_jump_break: # (payload array byte) -34463 0x11/imm32/alloc-id:fake:payload -34464 # "0f 85/jump-if-!= break/disp32" -34465 0x1d/imm32/size -34466 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34467 _string_0f_85_jump_loop: # (payload array byte) -34468 0x11/imm32/alloc-id:fake:payload -34469 # "0f 85/jump-if-!= loop/disp32" -34470 0x1c/imm32/size -34471 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34472 _string_0f_86_jump_label: # (payload array byte) -34473 0x11/imm32/alloc-id:fake:payload -34474 # "0f 86/jump-if-addr<=" -34475 0x14/imm32/size -34476 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= -34477 _string_0f_86_jump_break: # (payload array byte) -34478 0x11/imm32/alloc-id:fake:payload -34479 # "0f 86/jump-if-addr<= break/disp32" -34480 0x21/imm32/size -34481 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34482 _string_0f_86_jump_loop: # (payload array byte) -34483 0x11/imm32/alloc-id:fake:payload -34484 # "0f 86/jump-if-addr<= loop/disp32" -34485 0x20/imm32/size -34486 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34487 _string_0f_87_jump_label: # (payload array byte) -34488 0x11/imm32/alloc-id:fake:payload -34489 # "0f 87/jump-if-addr>" -34490 0x13/imm32/size -34491 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> -34492 _string_0f_87_jump_break: # (payload array byte) -34493 0x11/imm32/alloc-id:fake:payload -34494 # "0f 87/jump-if-addr> break/disp32" -34495 0x20/imm32/size -34496 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34497 _string_0f_87_jump_loop: # (payload array byte) -34498 0x11/imm32/alloc-id:fake:payload -34499 # "0f 87/jump-if-addr> loop/disp32" -34500 0x1f/imm32/size -34501 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34502 _string_0f_8c_jump_label: # (payload array byte) -34503 0x11/imm32/alloc-id:fake:payload -34504 # "0f 8c/jump-if-<" -34505 0xf/imm32/size -34506 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -34507 _string_0f_8c_jump_break: # (payload array byte) -34508 0x11/imm32/alloc-id:fake:payload -34509 # "0f 8c/jump-if-< break/disp32" -34510 0x1c/imm32/size -34511 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34512 _string_0f_8c_jump_loop: # (payload array byte) -34513 0x11/imm32/alloc-id:fake:payload -34514 # "0f 8c/jump-if-< loop/disp32" -34515 0x1b/imm32/size -34516 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34517 _string_0f_8d_jump_label: # (payload array byte) -34518 0x11/imm32/alloc-id:fake:payload -34519 # "0f 8d/jump-if->=" -34520 0x10/imm32/size -34521 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -34522 _string_0f_8d_jump_break: # (payload array byte) -34523 0x11/imm32/alloc-id:fake:payload -34524 # "0f 8d/jump-if->= break/disp32" -34525 0x1d/imm32/size -34526 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34527 _string_0f_8d_jump_loop: # (payload array byte) -34528 0x11/imm32/alloc-id:fake:payload -34529 # "0f 8d/jump-if->= loop/disp32" -34530 0x1c/imm32/size -34531 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34532 _string_0f_8e_jump_label: # (payload array byte) -34533 0x11/imm32/alloc-id:fake:payload -34534 # "0f 8e/jump-if-<=" -34535 0x10/imm32/size -34536 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -34537 _string_0f_8e_jump_break: # (payload array byte) -34538 0x11/imm32/alloc-id:fake:payload -34539 # "0f 8e/jump-if-<= break/disp32" -34540 0x1d/imm32/size -34541 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34542 _string_0f_8e_jump_loop: # (payload array byte) -34543 0x11/imm32/alloc-id:fake:payload -34544 # "0f 8e/jump-if-<= loop/disp32" -34545 0x1c/imm32/size -34546 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34547 _string_0f_8f_jump_label: # (payload array byte) -34548 0x11/imm32/alloc-id:fake:payload -34549 # "0f 8f/jump-if->" -34550 0xf/imm32/size -34551 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -34552 _string_0f_8f_jump_break: # (payload array byte) -34553 0x11/imm32/alloc-id:fake:payload -34554 # "0f 8f/jump-if-> break/disp32" -34555 0x1c/imm32/size -34556 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34557 _string_0f_8f_jump_loop: # (payload array byte) -34558 0x11/imm32/alloc-id:fake:payload -34559 # "0f 8f/jump-if-> loop/disp32" -34560 0x1b/imm32/size -34561 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34562 _string_0f_af_multiply: # (payload array byte) -34563 0x11/imm32/alloc-id:fake:payload -34564 # "0f af/multiply" -34565 0xe/imm32/size -34566 0x30/0 0x66/f 0x20/space 0x61/a 0x66/f 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -34567 _string_f3_0f_2a_convert_to_float: -34568 0x11/imm32/alloc-id:fake:payload -34569 # "f3 0f 2a/convert-to-float" -34570 0x19/imm32/size -34571 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t -34572 _string_f3_0f_2d_convert_to_int: -34573 0x11/imm32/alloc-id:fake:payload -34574 # "f3 0f 2d/convert-to-int" -34575 0x17/imm32/size -34576 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x69/i 0x6e/n 0x74/t -34577 _string_f3_0f_2c_truncate_to_int: -34578 0x11/imm32/alloc-id:fake:payload -34579 # "f3 0f 2c/truncate-to-int" -34580 0x18/imm32/size -34581 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x63/c 0x2f/slash 0x74/t 0x72/r 0x75/u 0x6e/n 0x63/c 0x61/a 0x74/t 0x65/e 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x69/i 0x6e/n 0x74/t -34582 _string_f3_0f_58_add: -34583 0x11/imm32/alloc-id:fake:payload -34584 # "f3 0f 58/add" -34585 0xc/imm32/size -34586 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x38/8 0x2f/slash 0x61/a 0x64/d 0x64/d -34587 _string_f3_0f_5c_subtract: -34588 0x11/imm32/alloc-id:fake:payload -34589 # "f3 0f 5c/subtract" -34590 0x11/imm32/size -34591 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x63/c 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -34592 _string_f3_0f_59_multiply: -34593 0x11/imm32/alloc-id:fake:payload -34594 # "f3 0f 59/multiply" -34595 0x11/imm32/size -34596 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x39/9 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -34597 _string_f3_0f_5e_divide: -34598 0x11/imm32/alloc-id:fake:payload -34599 # "f3 0f 5e/divide" -34600 0xf/imm32/size -34601 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x65/e 0x2f/slash 0x64/d 0x69/i 0x76/v 0x69/i 0x64/d 0x65/e -34602 _string_f3_0f_53_reciprocal: -34603 0x11/imm32/alloc-id:fake:payload -34604 # "f3 0f 53/reciprocal" -34605 0x13/imm32/size -34606 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x33/3 0x2f/slash 0x72/r 0x65/e 0x63/c 0x69/i 0x70/p 0x72/r 0x6f/o 0x63/c 0x61/a 0x6c/l -34607 _string_f3_0f_51_square_root: -34608 0x11/imm32/alloc-id:fake:payload -34609 # "f3 0f 51/square-root" -34610 0x14/imm32/size -34611 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x31/1 0x2f/slash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t -34612 _string_f3_0f_52_inverse_square_root: -34613 0x11/imm32/alloc-id:fake:payload -34614 # "f3 0f 52/inverse-square-root" -34615 0x1c/imm32/size -34616 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/dash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t -34617 _string_f3_0f_5d_min: -34618 0x11/imm32/alloc-id:fake:payload -34619 # "f3 0f 5d/min" -34620 0xc/imm32/size -34621 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x64/d 0x2f/slash 0x6d/m 0x69/i 0x6e/n -34622 _string_f3_0f_5f_max: -34623 0x11/imm32/alloc-id:fake:payload -34624 # "f3 0f 5f/max" -34625 0xc/imm32/size -34626 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x66/f 0x2f/slash 0x6d/m 0x61/a 0x78/x -34627 _string_f3_0f_10_copy: -34628 0x11/imm32/alloc-id:fake:payload -34629 # "f3 0f 10/copy" -34630 0xd/imm32/size -34631 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x31/1 0x30/0 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y -34632 _string_f3_0f_11_copy: -34633 0x11/imm32/alloc-id:fake:payload -34634 # "f3 0f 11/copy" -34635 0xd/imm32/size -34636 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x31/1 0x31/1 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y -34637 _string_0f_2f_compare: -34638 0x11/imm32/alloc-id:fake:payload -34639 # "0f 2f/compare" -34640 0xd/imm32/size -34641 0x30/0 0x66/f 0x20/space 0x32/2 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -34642 _string_21_and_with: # (payload array byte) -34643 0x11/imm32/alloc-id:fake:payload -34644 # "21/and-with" -34645 0xb/imm32/size -34646 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -34647 _string_23_and: # (payload array byte) -34648 0x11/imm32/alloc-id:fake:payload -34649 # "23/and" -34650 0x6/imm32/size -34651 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d -34652 _string_25_and_with_eax: # (payload array byte) -34653 0x11/imm32/alloc-id:fake:payload -34654 # "25/and-with-eax" -34655 0xf/imm32/size -34656 0x32/2 0x35/5 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -34657 _string_29_subtract_from: # (payload array byte) -34658 0x11/imm32/alloc-id:fake:payload -34659 # "29/subtract-from" -34660 0x10/imm32/size -34661 0x32/2 0x39/9 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m -34662 _string_2b_subtract: # (payload array byte) -34663 0x11/imm32/alloc-id:fake:payload -34664 # "2b/subtract" -34665 0xb/imm32/size -34666 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -34667 _string_2d_subtract_from_eax: # (payload array byte) -34668 0x11/imm32/alloc-id:fake:payload -34669 # "2d/subtract-from-eax" -34670 0x14/imm32/size -34671 0x32/2 0x64/d 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m 0x2d/dash 0x65/e 0x61/a 0x78/x -34672 _string_31_xor_with: # (payload array byte) -34673 0x11/imm32/alloc-id:fake:payload -34674 # "31/xor-with" -34675 0xb/imm32/size -34676 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -34677 _string_33_xor: # (payload array byte) -34678 0x11/imm32/alloc-id:fake:payload -34679 # "33/xor" -34680 0x6/imm32/size -34681 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r -34682 _string_35_xor_with_eax: # (payload array byte) -34683 0x11/imm32/alloc-id:fake:payload -34684 # "35/xor-with-eax" -34685 0xf/imm32/size -34686 0x33/3 0x35/5 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x -34687 _string_39_compare->: # (payload array byte) -34688 0x11/imm32/alloc-id:fake:payload -34689 # "39/compare->" -34690 0xc/imm32/size -34691 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> -34692 _string_3b_compare<-: # (payload array byte) -34693 0x11/imm32/alloc-id:fake:payload -34694 # "3b/compare<-" -34695 0xc/imm32/size -34696 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash -34697 _string_3d_compare_eax_with: # (payload array byte) -34698 0x11/imm32/alloc-id:fake:payload -34699 # "3d/compare-eax-with" -34700 0x13/imm32/size -34701 0x33/3 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x65/e 0x61/a 0x78/x 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -34702 _string_40_increment_eax: # (payload array byte) -34703 0x11/imm32/alloc-id:fake:payload -34704 # "40/increment-eax" -34705 0x10/imm32/size -34706 0x34/4 0x30/0 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x -34707 _string_41_increment_ecx: # (payload array byte) -34708 0x11/imm32/alloc-id:fake:payload -34709 # "41/increment-ecx" -34710 0x10/imm32/size -34711 0x34/4 0x31/1 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x -34712 _string_42_increment_edx: # (payload array byte) -34713 0x11/imm32/alloc-id:fake:payload -34714 # "42/increment-edx" -34715 0x10/imm32/size -34716 0x34/4 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x -34717 _string_43_increment_ebx: # (payload array byte) -34718 0x11/imm32/alloc-id:fake:payload -34719 # "43/increment-ebx" -34720 0x10/imm32/size -34721 0x34/4 0x33/3 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x -34722 _string_46_increment_esi: # (payload array byte) -34723 0x11/imm32/alloc-id:fake:payload -34724 # "46/increment-esi" -34725 0x10/imm32/size -34726 0x34/4 0x36/6 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i -34727 _string_47_increment_edi: # (payload array byte) -34728 0x11/imm32/alloc-id:fake:payload -34729 # "47/increment-edi" -34730 0x10/imm32/size -34731 0x34/4 0x37/7 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i -34732 _string_48_decrement_eax: # (payload array byte) -34733 0x11/imm32/alloc-id:fake:payload -34734 # "48/decrement-eax" -34735 0x10/imm32/size -34736 0x34/4 0x38/8 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x -34737 _string_49_decrement_ecx: # (payload array byte) -34738 0x11/imm32/alloc-id:fake:payload -34739 # "49/decrement-ecx" -34740 0x10/imm32/size -34741 0x34/4 0x39/9 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x -34742 _string_4a_decrement_edx: # (payload array byte) -34743 0x11/imm32/alloc-id:fake:payload -34744 # "4a/decrement-edx" -34745 0x10/imm32/size -34746 0x34/4 0x61/a 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x -34747 _string_4b_decrement_ebx: # (payload array byte) -34748 0x11/imm32/alloc-id:fake:payload -34749 # "4b/decrement-ebx" -34750 0x10/imm32/size -34751 0x34/4 0x62/b 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x -34752 _string_4e_decrement_esi: # (payload array byte) -34753 0x11/imm32/alloc-id:fake:payload -34754 # "4e/decrement-esi" -34755 0x10/imm32/size -34756 0x34/4 0x65/e 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i -34757 _string_4f_decrement_edi: # (payload array byte) -34758 0x11/imm32/alloc-id:fake:payload -34759 # "4f/decrement-edi" -34760 0x10/imm32/size -34761 0x34/4 0x66/f 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i -34762 _string_81_subop_add: # (payload array byte) -34763 0x11/imm32/alloc-id:fake:payload -34764 # "81 0/subop/add" -34765 0xe/imm32/size -34766 0x38/8 0x31/1 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x64/d 0x64/d -34767 _string_81_subop_or: # (payload array byte) -34768 0x11/imm32/alloc-id:fake:payload -34769 # "81 1/subop/or" -34770 0xd/imm32/size -34771 0x38/8 0x31/1 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6f/o 0x72/r -34772 _string_81_subop_and: # (payload array byte) -34773 0x11/imm32/alloc-id:fake:payload -34774 # "81 4/subop/and" -34775 0xe/imm32/size -34776 0x38/8 0x31/1 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x6e/n 0x64/d -34777 _string_81_subop_subtract: # (payload array byte) -34778 0x11/imm32/alloc-id:fake:payload -34779 # "81 5/subop/subtract" -34780 0x13/imm32/size -34781 0x38/8 0x31/1 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -34782 _string_81_subop_xor: # (payload array byte) -34783 0x11/imm32/alloc-id:fake:payload -34784 # "81 6/subop/xor" -34785 0xe/imm32/size -34786 0x38/8 0x31/1 0x20/space 0x36/6 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x78/x 0x6f/o 0x72/r -34787 _string_81_subop_compare: # (payload array byte) -34788 0x11/imm32/alloc-id:fake:payload -34789 # "81 7/subop/compare" -34790 0x12/imm32/size -34791 0x38/8 0x31/1 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -34792 _string_89_<-: # (payload array byte) -34793 0x11/imm32/alloc-id:fake:payload -34794 # "89/<-" -34795 0x5/imm32/size -34796 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash -34797 _string_8b_->: # (payload array byte) -34798 0x11/imm32/alloc-id:fake:payload -34799 # "8b/->" -34800 0x5/imm32/size -34801 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> -34802 _string_8a_copy_byte: -34803 0x11/imm32/alloc-id:fake:payload -34804 # "8a/byte->" -34805 0x9/imm32/size -34806 0x38/8 0x61/a 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x3e/> -34807 _string_88_copy_byte: -34808 0x11/imm32/alloc-id:fake:payload -34809 # "88/byte<-" -34810 0x9/imm32/size -34811 0x38/8 0x38/8 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/- -34812 _string_8d_copy_address: # (payload array byte) -34813 0x11/imm32/alloc-id:fake:payload -34814 # "8d/copy-address" -34815 0xf/imm32/size -34816 0x38/8 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s -34817 _string_b8_copy_to_eax: # (payload array byte) -34818 0x11/imm32/alloc-id:fake:payload -34819 # "b8/copy-to-eax" -34820 0xe/imm32/size -34821 0x62/b 0x38/8 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x -34822 _string_b9_copy_to_ecx: # (payload array byte) -34823 0x11/imm32/alloc-id:fake:payload -34824 # "b9/copy-to-ecx" -34825 0xe/imm32/size -34826 0x62/b 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x63/c 0x78/x -34827 _string_ba_copy_to_edx: # (payload array byte) -34828 0x11/imm32/alloc-id:fake:payload -34829 # "ba/copy-to-edx" -34830 0xe/imm32/size -34831 0x62/b 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x78/x -34832 _string_bb_copy_to_ebx: # (payload array byte) -34833 0x11/imm32/alloc-id:fake:payload -34834 # "bb/copy-to-ebx" -34835 0xe/imm32/size -34836 0x62/b 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x62/b 0x78/x -34837 _string_be_copy_to_esi: # (payload array byte) -34838 0x11/imm32/alloc-id:fake:payload -34839 # "be/copy-to-esi" -34840 0xe/imm32/size -34841 0x62/b 0x65/e 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x73/s 0x69/i -34842 _string_bf_copy_to_edi: # (payload array byte) -34843 0x11/imm32/alloc-id:fake:payload -34844 # "bf/copy-to-edi" -34845 0xe/imm32/size -34846 0x62/b 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x69/i -34847 _string_c7_subop_copy: # (payload array byte) -34848 0x11/imm32/alloc-id:fake:payload -34849 # "c7 0/subop/copy" -34850 0xf/imm32/size -34851 0x63/c 0x37/7 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y -34852 _string_e9_jump_label: # (payload array byte) -34853 0x11/imm32/alloc-id:fake:payload -34854 # "e9/jump" -34855 0x7/imm32/size -34856 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p -34857 _string_e9_jump_break: # (payload array byte) -34858 0x11/imm32/alloc-id:fake:payload -34859 # "e9/jump break/disp32" -34860 0x14/imm32/size -34861 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34862 _string_e9_jump_loop: # (payload array byte) -34863 0x11/imm32/alloc-id:fake:payload -34864 # "e9/jump loop/disp32" -34865 0x13/imm32/size -34866 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 -34867 _string_f7_subop_negate: -34868 0x11/imm32/alloc-id:fake:payload -34869 # "f7 3/subop/negate" -34870 0x11/imm32/size -34871 0x66/f 0x37/7 0x20/space 0x33/3 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6e/n 0x65/e 0x67/g 0x61/a 0x74/t 0x65/e -34872 _string_f7_subop_not: -34873 0x11/imm32/alloc-id:fake:payload -34874 # "f7 2/subop/not" -34875 0xe/imm32/size -34876 0x66/f 0x37/7 0x20/space 0x32/2 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6e/n 0x6f/o 0x74/t -34877 _string_ff_subop_increment: # (payload array byte) -34878 0x11/imm32/alloc-id:fake:payload -34879 # "ff 0/subop/increment" -34880 0x14/imm32/size -34881 0x66/f 0x66/f 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -34882 _string_ff_subop_decrement: # (payload array byte) -34883 0x11/imm32/alloc-id:fake:payload -34884 # "ff 1/subop/decrement" -34885 0x14/imm32/size -34886 0x66/f 0x66/f 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -34887 _string_c1_subop_shift_left: # (payload array byte) -34888 0x11/imm32/alloc-id:fake:payload -34889 # "c1/shift 4/subop/left" -34890 0x15/imm32/size -34891 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6c/l 0x65/e 0x66/f 0x74/t -34892 _string_c1_subop_shift_right_padding_zeroes: # (payload array byte) -34893 0x11/imm32/alloc-id:fake:payload -34894 # "c1/shift 5/subop/right-padding-zeroes" -34895 0x25/imm32/size -34896 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x61/a 0x64/d 0x64/d 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x7a/z 0x65/e 0x72/r 0x6f/o 0x65/e 0x73/s -34897 _string_c1_subop_shift_right_preserving_sign: # (payload array byte) -34898 0x11/imm32/alloc-id:fake:payload -34899 # "c1/shift 7/subop/right-preserving-sign" -34900 0x26/imm32/size -34901 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x72/r 0x65/e 0x73/s 0x65/e 0x72/r 0x76/v 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n -34902 -34903 Single-int-var-in-mem: # (payload list var) -34904 0x11/imm32/alloc-id:fake:payload -34905 0x11/imm32/alloc-id:fake -34906 Int-var-in-mem/imm32 -34907 0/imm32/next -34908 0/imm32/next -34909 -34910 Int-var-in-mem: # (payload var) -34911 0x11/imm32/alloc-id:fake:payload -34912 0/imm32/name -34913 0/imm32/name -34914 0x11/imm32/alloc-id:fake -34915 Type-int/imm32 -34916 1/imm32/some-block-depth -34917 1/imm32/some-stack-offset -34918 0/imm32/no-register -34919 0/imm32/no-register -34920 -34921 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -34922 Single-byte-var-in-mem: # (payload list var) +33991 0x11/imm32/alloc-id:fake +33992 _Primitive-loop-if-float>-named/imm32/next +33993 _Primitive-loop-if-float>-named: # (payload primitive) +33994 0x11/imm32/alloc-id:fake:payload +33995 0x11/imm32/alloc-id:fake +33996 _string-loop-if-float>/imm32/name +33997 0x11/imm32/alloc-id:fake +33998 Single-lit-var/imm32/inouts +33999 0/imm32/no-outputs +34000 0/imm32/no-outputs +34001 0x11/imm32/alloc-id:fake +34002 _string_0f_87_jump_label/imm32/subx-name +34003 0/imm32/no-rm32 +34004 0/imm32/no-r32 +34005 0/imm32/no-imm32 +34006 0/imm32/no-imm8 +34007 1/imm32/disp32-is-first-inout +34008 0/imm32/no-xm32 +34009 0/imm32/no-x32 +34010 0/imm32/next +34011 0/imm32/next +34012 +34013 # string literals for Mu instructions +34014 _string-add: # (payload array byte) +34015 0x11/imm32/alloc-id:fake:payload +34016 # "add" +34017 0x3/imm32/size +34018 0x61/a 0x64/d 0x64/d +34019 _string-address: # (payload array byte) +34020 0x11/imm32/alloc-id:fake:payload +34021 # "address" +34022 0x7/imm32/size +34023 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s +34024 _string-add-to: # (payload array byte) +34025 0x11/imm32/alloc-id:fake:payload +34026 # "add-to" +34027 0x6/imm32/size +34028 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +34029 _string-and: # (payload array byte) +34030 0x11/imm32/alloc-id:fake:payload +34031 # "and" +34032 0x3/imm32/size +34033 0x61/a 0x6e/n 0x64/d +34034 _string-and-with: # (payload array byte) +34035 0x11/imm32/alloc-id:fake:payload +34036 # "and-with" +34037 0x8/imm32/size +34038 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +34039 _string-break: # (payload array byte) +34040 0x11/imm32/alloc-id:fake:payload +34041 # "break" +34042 0x5/imm32/size +34043 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k +34044 _string-break-if-<: # (payload array byte) +34045 0x11/imm32/alloc-id:fake:payload +34046 # "break-if-<" +34047 0xa/imm32/size +34048 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +34049 _string-break-if-<=: # (payload array byte) +34050 0x11/imm32/alloc-id:fake:payload +34051 # "break-if-<=" +34052 0xb/imm32/size +34053 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +34054 _string-break-if-=: # (payload array byte) +34055 0x11/imm32/alloc-id:fake:payload +34056 # "break-if-=" +34057 0xa/imm32/size +34058 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +34059 _string-break-if->: # (payload array byte) +34060 0x11/imm32/alloc-id:fake:payload +34061 # "break-if->" +34062 0xa/imm32/size +34063 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +34064 _string-break-if->=: # (payload array byte) +34065 0x11/imm32/alloc-id:fake:payload +34066 # "break-if->=" +34067 0xb/imm32/size +34068 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +34069 _string-break-if-!=: # (payload array byte) +34070 0x11/imm32/alloc-id:fake:payload +34071 # "break-if-!=" +34072 0xb/imm32/size +34073 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +34074 _string-break-if-addr<: # (payload array byte) +34075 0x11/imm32/alloc-id:fake:payload +34076 # "break-if-addr<" +34077 0xe/imm32/size +34078 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +34079 _string-break-if-addr<=: # (payload array byte) +34080 0x11/imm32/alloc-id:fake:payload +34081 # "break-if-addr<=" +34082 0xf/imm32/size +34083 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +34084 _string-break-if-addr>: # (payload array byte) +34085 0x11/imm32/alloc-id:fake:payload +34086 # "break-if-addr>" +34087 0xe/imm32/size +34088 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +34089 _string-break-if-addr>=: # (payload array byte) +34090 0x11/imm32/alloc-id:fake:payload +34091 # "break-if-addr>=" +34092 0xf/imm32/size +34093 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +34094 _string-break-if-float<: # (payload array byte) +34095 0x11/imm32/alloc-id:fake:payload +34096 # "break-if-float<" +34097 0xf/imm32/size +34098 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< +34099 _string-break-if-float<=: # (payload array byte) +34100 0x11/imm32/alloc-id:fake:payload +34101 # "break-if-float<=" +34102 0x10/imm32/size +34103 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< 0x3d/= +34104 _string-break-if-float>: # (payload array byte) +34105 0x11/imm32/alloc-id:fake:payload +34106 # "break-if-float>" +34107 0xf/imm32/size +34108 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> +34109 _string-break-if-float>=: # (payload array byte) +34110 0x11/imm32/alloc-id:fake:payload +34111 # "break-if-float>=" +34112 0x10/imm32/size +34113 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/= +34114 _string-break-if-carry: # (payload array byte) +34115 0x11/imm32/alloc-id:fake:payload +34116 # "break-if-carry" +34117 0xe/imm32/size +34118 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y +34119 _string-break-if-not-carry: # (payload array byte) +34120 0x11/imm32/alloc-id:fake:payload +34121 # "break-if-not-carry" +34122 0x12/imm32/size +34123 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y +34124 _string-break-if-overflow: # (payload array byte) +34125 0x11/imm32/alloc-id:fake:payload +34126 # "break-if-overflow" +34127 0x11/imm32/size +34128 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w +34129 _string-break-if-not-overflow: # (payload array byte) +34130 0x11/imm32/alloc-id:fake:payload +34131 # "break-if-not-overflow" +34132 0x15/imm32/size +34133 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w +34134 _string-compare: # (payload array byte) +34135 0x11/imm32/alloc-id:fake:payload +34136 # "compare" +34137 0x7/imm32/size +34138 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +34139 _string-copy: # (payload array byte) +34140 0x11/imm32/alloc-id:fake:payload +34141 # "copy" +34142 0x4/imm32/size +34143 0x63/c 0x6f/o 0x70/p 0x79/y +34144 _string-copy-to: # (payload array byte) +34145 0x11/imm32/alloc-id:fake:payload +34146 # "copy-to" +34147 0x7/imm32/size +34148 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o +34149 _string-copy-byte: +34150 0x11/imm32/alloc-id:fake:payload +34151 # "copy-byte" +34152 0x9/imm32/size +34153 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e +34154 _string-copy-byte-to: +34155 0x11/imm32/alloc-id:fake:payload +34156 # "copy-byte-to" +34157 0xc/imm32/size +34158 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x74/t 0x6f/o +34159 _string-decrement: # (payload array byte) +34160 0x11/imm32/alloc-id:fake:payload +34161 # "decrement" +34162 0x9/imm32/size +34163 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +34164 _string-increment: # (payload array byte) +34165 0x11/imm32/alloc-id:fake:payload +34166 # "increment" +34167 0x9/imm32/size +34168 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +34169 _string-loop: # (payload array byte) +34170 0x11/imm32/alloc-id:fake:payload +34171 # "loop" +34172 0x4/imm32/size +34173 0x6c/l 0x6f/o 0x6f/o 0x70/p +34174 _string-loop-if-<: # (payload array byte) +34175 0x11/imm32/alloc-id:fake:payload +34176 # "loop-if-<" +34177 0x9/imm32/size +34178 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +34179 _string-loop-if-<=: # (payload array byte) +34180 0x11/imm32/alloc-id:fake:payload +34181 # "loop-if-<=" +34182 0xa/imm32/size +34183 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +34184 _string-loop-if-=: # (payload array byte) +34185 0x11/imm32/alloc-id:fake:payload +34186 # "loop-if-=" +34187 0x9/imm32/size +34188 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +34189 _string-loop-if->: # (payload array byte) +34190 0x11/imm32/alloc-id:fake:payload +34191 # "loop-if->" +34192 0x9/imm32/size +34193 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +34194 _string-loop-if->=: # (payload array byte) +34195 0x11/imm32/alloc-id:fake:payload +34196 # "loop-if->=" +34197 0xa/imm32/size +34198 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +34199 _string-loop-if-!=: # (payload array byte) +34200 0x11/imm32/alloc-id:fake:payload +34201 # "loop-if-!=" +34202 0xa/imm32/size +34203 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +34204 _string-loop-if-addr<: # (payload array byte) +34205 0x11/imm32/alloc-id:fake:payload +34206 # "loop-if-addr<" +34207 0xd/imm32/size +34208 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +34209 _string-loop-if-addr<=: # (payload array byte) +34210 0x11/imm32/alloc-id:fake:payload +34211 # "loop-if-addr<=" +34212 0xe/imm32/size +34213 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +34214 _string-loop-if-addr>: # (payload array byte) +34215 0x11/imm32/alloc-id:fake:payload +34216 # "loop-if-addr>" +34217 0xd/imm32/size +34218 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +34219 _string-loop-if-addr>=: # (payload array byte) +34220 0x11/imm32/alloc-id:fake:payload +34221 # "loop-if-addr>=" +34222 0xe/imm32/size +34223 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +34224 _string-loop-if-float<: # (payload array byte) +34225 0x11/imm32/alloc-id:fake:payload +34226 # "loop-if-float<" +34227 0xe/imm32/size +34228 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< +34229 _string-loop-if-float<=: # (payload array byte) +34230 0x11/imm32/alloc-id:fake:payload +34231 # "loop-if-float<=" +34232 0xf/imm32/size +34233 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< 0x3d/= +34234 _string-loop-if-float>: # (payload array byte) +34235 0x11/imm32/alloc-id:fake:payload +34236 # "loop-if-float>" +34237 0xe/imm32/size +34238 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> +34239 _string-loop-if-float>=: # (payload array byte) +34240 0x11/imm32/alloc-id:fake:payload +34241 # "loop-if-float>=" +34242 0xf/imm32/size +34243 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/= +34244 _string-loop-if-carry: # (payload array byte) +34245 0x11/imm32/alloc-id:fake:payload +34246 # "loop-if-carry" +34247 0xd/imm32/size +34248 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y +34249 _string-loop-if-not-carry: # (payload array byte) +34250 0x11/imm32/alloc-id:fake:payload +34251 # "loop-if-not-carry" +34252 0x11/imm32/size +34253 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y +34254 _string-loop-if-overflow: # (payload array byte) +34255 0x11/imm32/alloc-id:fake:payload +34256 # "loop-if-overflow" +34257 0x10/imm32/size +34258 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w +34259 _string-loop-if-not-overflow: # (payload array byte) +34260 0x11/imm32/alloc-id:fake:payload +34261 # "loop-if-not-overflow" +34262 0x14/imm32/size +34263 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w +34264 _string-multiply: # (payload array byte) +34265 0x11/imm32/alloc-id:fake:payload +34266 # "multiply" +34267 0x8/imm32/size +34268 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +34269 _string-convert: # (payload array byte) +34270 0x11/imm32/alloc-id:fake:payload +34271 # "convert" +34272 0x7/imm32/size +34273 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t +34274 _string-truncate: # (payload array byte) +34275 0x11/imm32/alloc-id:fake:payload +34276 # "truncate" +34277 0x8/imm32/size +34278 0x74/t 0x72/r 0x75/u 0x6e/n 0x63/c 0x61/a 0x74/t 0x65/e +34279 _string-reinterpret: # (payload array byte) +34280 0x11/imm32/alloc-id:fake:payload +34281 # "reinterpret" +34282 0xb/imm32/size +34283 0x72/r 0x65/e 0x69/i 0x6e/n 0x74/t 0x65/e 0x72/r 0x70/p 0x72/r 0x65/e 0x74/t +34284 _string-divide: +34285 0x11/imm32/alloc-id:fake:payload +34286 # "divide" +34287 0x6/imm32/size +34288 0x64/d 0x69/i 0x76/v 0x69/i 0x64/d 0x65/e +34289 _string-max: +34290 0x11/imm32/alloc-id:fake:payload +34291 # "max" +34292 0x3/imm32/size +34293 0x6d/m 0x61/a 0x78/x +34294 _string-min: +34295 0x11/imm32/alloc-id:fake:payload +34296 # "min" +34297 0x3/imm32/size +34298 0x6d/m 0x69/i 0x6e/n +34299 _string-reciprocal: +34300 0x11/imm32/alloc-id:fake:payload +34301 # "reciprocal" +34302 0xa/imm32/size +34303 0x72/r 0x65/e 0x63/c 0x69/i 0x70/p 0x72/r 0x6f/o 0x63/c 0x61/a 0x6c/l +34304 _string-square-root: +34305 0x11/imm32/alloc-id:fake:payload +34306 # "square-root" +34307 0xb/imm32/size +34308 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t +34309 _string-inverse-square-root: +34310 0x11/imm32/alloc-id:fake:payload +34311 # "inverse-square-root" +34312 0x13/imm32/size +34313 0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/dash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t +34314 _string-negate: # (payload array byte) +34315 0x11/imm32/alloc-id:fake:payload +34316 # "negate" +34317 0x6/imm32/size +34318 0x6e/n 0x65/e 0x67/g 0x61/a 0x74/t 0x65/e +34319 _string-not: # (payload array byte) +34320 0x11/imm32/alloc-id:fake:payload +34321 # "not" +34322 0x3/imm32/size +34323 0x6e/n 0x6f/o 0x74/t +34324 _string-or: # (payload array byte) +34325 0x11/imm32/alloc-id:fake:payload +34326 # "or" +34327 0x2/imm32/size +34328 0x6f/o 0x72/r +34329 _string-or-with: # (payload array byte) +34330 0x11/imm32/alloc-id:fake:payload +34331 # "or-with" +34332 0x7/imm32/size +34333 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +34334 _string-subtract: # (payload array byte) +34335 0x11/imm32/alloc-id:fake:payload +34336 # "subtract" +34337 0x8/imm32/size +34338 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +34339 _string-subtract-from: # (payload array byte) +34340 0x11/imm32/alloc-id:fake:payload +34341 # "subtract-from" +34342 0xd/imm32/size +34343 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m +34344 _string-xor: # (payload array byte) +34345 0x11/imm32/alloc-id:fake:payload +34346 # "xor" +34347 0x3/imm32/size +34348 0x78/x 0x6f/o 0x72/r +34349 _string-xor-with: # (payload array byte) +34350 0x11/imm32/alloc-id:fake:payload +34351 # "xor-with" +34352 0x8/imm32/size +34353 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +34354 _string-shift-left: # (payload array byte) +34355 0x11/imm32/alloc-id:fake:payload +34356 # "shift-left" +34357 0xa/imm32/size +34358 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x6c/l 0x65/e 0x66/f 0x74/t +34359 _string-shift-right: # (payload array byte) +34360 0x11/imm32/alloc-id:fake:payload +34361 # "shift-right" +34362 0xb/imm32/size +34363 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t +34364 _string-shift-right-signed: # (payload array byte) +34365 0x11/imm32/alloc-id:fake:payload +34366 # "shift-right-signed" +34367 0x12/imm32/size +34368 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n 0x65/e 0x64/d +34369 +34370 # string literals for SubX instructions +34371 _string_01_add_to: # (payload array byte) +34372 0x11/imm32/alloc-id:fake:payload +34373 # "01/add-to" +34374 0x9/imm32/size +34375 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +34376 _string_03_add: # (payload array byte) +34377 0x11/imm32/alloc-id:fake:payload +34378 # "03/add" +34379 0x6/imm32/size +34380 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d +34381 _string_05_add_to_eax: # (payload array byte) +34382 0x11/imm32/alloc-id:fake:payload +34383 # "05/add-to-eax" +34384 0xd/imm32/size +34385 0x30/0 0x35/5 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x +34386 _string_09_or_with: # (payload array byte) +34387 0x11/imm32/alloc-id:fake:payload +34388 # "09/or-with" +34389 0xa/imm32/size +34390 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +34391 _string_0b_or: # (payload array byte) +34392 0x11/imm32/alloc-id:fake:payload +34393 # "0b/or" +34394 0x5/imm32/size +34395 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r +34396 _string_0d_or_with_eax: # (payload array byte) +34397 0x11/imm32/alloc-id:fake:payload +34398 # "0d/or-with-eax" +34399 0xe/imm32/size +34400 0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +34401 _string_0f_80_jump_label: # (payload array byte) +34402 0x11/imm32/alloc-id:fake:payload +34403 # "0f 80/jump-if-overflow" +34404 0x16/imm32/size +34405 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w +34406 _string_0f_80_jump_break: # (payload array byte) +34407 0x11/imm32/alloc-id:fake:payload +34408 # "0f 80/jump-if-overflow break/disp32" +34409 0x23/imm32/size +34410 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34411 _string_0f_80_jump_loop: # (payload array byte) +34412 0x11/imm32/alloc-id:fake:payload +34413 # "0f 80/jump-if-overflow loop/disp32" +34414 0x22/imm32/size +34415 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34416 _string_0f_81_jump_label: # (payload array byte) +34417 0x11/imm32/alloc-id:fake:payload +34418 # "0f 81/jump-if-not-overflow" +34419 0x1a/imm32/size +34420 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w +34421 _string_0f_81_jump_break: # (payload array byte) +34422 0x11/imm32/alloc-id:fake:payload +34423 # "0f 81/jump-if-not-overflow break/disp32" +34424 0x27/imm32/size +34425 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34426 _string_0f_81_jump_loop: # (payload array byte) +34427 0x11/imm32/alloc-id:fake:payload +34428 # "0f 81/jump-if-not-overflow loop/disp32" +34429 0x26/imm32/size +34430 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34431 _string_0f_82_jump_label: # (payload array byte) +34432 0x11/imm32/alloc-id:fake:payload +34433 # "0f 82/jump-if-addr<" +34434 0x13/imm32/size +34435 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< +34436 _string_0f_82_jump_break: # (payload array byte) +34437 0x11/imm32/alloc-id:fake:payload +34438 # "0f 82/jump-if-addr< break/disp32" +34439 0x20/imm32/size +34440 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34441 _string_0f_82_jump_loop: # (payload array byte) +34442 0x11/imm32/alloc-id:fake:payload +34443 # "0f 82/jump-if-addr< loop/disp32" +34444 0x1f/imm32/size +34445 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34446 _string_0f_83_jump_label: # (payload array byte) +34447 0x11/imm32/alloc-id:fake:payload +34448 # "0f 83/jump-if-addr>=" +34449 0x14/imm32/size +34450 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= +34451 _string_0f_83_jump_break: # (payload array byte) +34452 0x11/imm32/alloc-id:fake:payload +34453 # "0f 83/jump-if-addr>= break/disp32" +34454 0x21/imm32/size +34455 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34456 _string_0f_83_jump_loop: # (payload array byte) +34457 0x11/imm32/alloc-id:fake:payload +34458 # "0f 83/jump-if-addr>= loop/disp32" +34459 0x20/imm32/size +34460 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34461 _string_0f_84_jump_label: # (payload array byte) +34462 0x11/imm32/alloc-id:fake:payload +34463 # "0f 84/jump-if-=" +34464 0xf/imm32/size +34465 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +34466 _string_0f_84_jump_break: # (payload array byte) +34467 0x11/imm32/alloc-id:fake:payload +34468 # "0f 84/jump-if-= break/disp32" +34469 0x1c/imm32/size +34470 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34471 _string_0f_84_jump_loop: # (payload array byte) +34472 0x11/imm32/alloc-id:fake:payload +34473 # "0f 84/jump-if-= loop/disp32" +34474 0x1a/imm32/size +34475 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34476 _string_0f_85_jump_label: # (payload array byte) +34477 0x11/imm32/alloc-id:fake:payload +34478 # "0f 85/jump-if-!=" +34479 0x10/imm32/size +34480 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +34481 _string_0f_85_jump_break: # (payload array byte) +34482 0x11/imm32/alloc-id:fake:payload +34483 # "0f 85/jump-if-!= break/disp32" +34484 0x1d/imm32/size +34485 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34486 _string_0f_85_jump_loop: # (payload array byte) +34487 0x11/imm32/alloc-id:fake:payload +34488 # "0f 85/jump-if-!= loop/disp32" +34489 0x1c/imm32/size +34490 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34491 _string_0f_86_jump_label: # (payload array byte) +34492 0x11/imm32/alloc-id:fake:payload +34493 # "0f 86/jump-if-addr<=" +34494 0x14/imm32/size +34495 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= +34496 _string_0f_86_jump_break: # (payload array byte) +34497 0x11/imm32/alloc-id:fake:payload +34498 # "0f 86/jump-if-addr<= break/disp32" +34499 0x21/imm32/size +34500 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34501 _string_0f_86_jump_loop: # (payload array byte) +34502 0x11/imm32/alloc-id:fake:payload +34503 # "0f 86/jump-if-addr<= loop/disp32" +34504 0x20/imm32/size +34505 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34506 _string_0f_87_jump_label: # (payload array byte) +34507 0x11/imm32/alloc-id:fake:payload +34508 # "0f 87/jump-if-addr>" +34509 0x13/imm32/size +34510 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> +34511 _string_0f_87_jump_break: # (payload array byte) +34512 0x11/imm32/alloc-id:fake:payload +34513 # "0f 87/jump-if-addr> break/disp32" +34514 0x20/imm32/size +34515 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34516 _string_0f_87_jump_loop: # (payload array byte) +34517 0x11/imm32/alloc-id:fake:payload +34518 # "0f 87/jump-if-addr> loop/disp32" +34519 0x1f/imm32/size +34520 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34521 _string_0f_8c_jump_label: # (payload array byte) +34522 0x11/imm32/alloc-id:fake:payload +34523 # "0f 8c/jump-if-<" +34524 0xf/imm32/size +34525 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +34526 _string_0f_8c_jump_break: # (payload array byte) +34527 0x11/imm32/alloc-id:fake:payload +34528 # "0f 8c/jump-if-< break/disp32" +34529 0x1c/imm32/size +34530 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34531 _string_0f_8c_jump_loop: # (payload array byte) +34532 0x11/imm32/alloc-id:fake:payload +34533 # "0f 8c/jump-if-< loop/disp32" +34534 0x1b/imm32/size +34535 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34536 _string_0f_8d_jump_label: # (payload array byte) +34537 0x11/imm32/alloc-id:fake:payload +34538 # "0f 8d/jump-if->=" +34539 0x10/imm32/size +34540 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +34541 _string_0f_8d_jump_break: # (payload array byte) +34542 0x11/imm32/alloc-id:fake:payload +34543 # "0f 8d/jump-if->= break/disp32" +34544 0x1d/imm32/size +34545 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34546 _string_0f_8d_jump_loop: # (payload array byte) +34547 0x11/imm32/alloc-id:fake:payload +34548 # "0f 8d/jump-if->= loop/disp32" +34549 0x1c/imm32/size +34550 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34551 _string_0f_8e_jump_label: # (payload array byte) +34552 0x11/imm32/alloc-id:fake:payload +34553 # "0f 8e/jump-if-<=" +34554 0x10/imm32/size +34555 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +34556 _string_0f_8e_jump_break: # (payload array byte) +34557 0x11/imm32/alloc-id:fake:payload +34558 # "0f 8e/jump-if-<= break/disp32" +34559 0x1d/imm32/size +34560 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34561 _string_0f_8e_jump_loop: # (payload array byte) +34562 0x11/imm32/alloc-id:fake:payload +34563 # "0f 8e/jump-if-<= loop/disp32" +34564 0x1c/imm32/size +34565 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34566 _string_0f_8f_jump_label: # (payload array byte) +34567 0x11/imm32/alloc-id:fake:payload +34568 # "0f 8f/jump-if->" +34569 0xf/imm32/size +34570 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +34571 _string_0f_8f_jump_break: # (payload array byte) +34572 0x11/imm32/alloc-id:fake:payload +34573 # "0f 8f/jump-if-> break/disp32" +34574 0x1c/imm32/size +34575 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34576 _string_0f_8f_jump_loop: # (payload array byte) +34577 0x11/imm32/alloc-id:fake:payload +34578 # "0f 8f/jump-if-> loop/disp32" +34579 0x1b/imm32/size +34580 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34581 _string_0f_af_multiply: # (payload array byte) +34582 0x11/imm32/alloc-id:fake:payload +34583 # "0f af/multiply" +34584 0xe/imm32/size +34585 0x30/0 0x66/f 0x20/space 0x61/a 0x66/f 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +34586 _string_f3_0f_2a_convert_to_float: +34587 0x11/imm32/alloc-id:fake:payload +34588 # "f3 0f 2a/convert-to-float" +34589 0x19/imm32/size +34590 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t +34591 _string_f3_0f_2d_convert_to_int: +34592 0x11/imm32/alloc-id:fake:payload +34593 # "f3 0f 2d/convert-to-int" +34594 0x17/imm32/size +34595 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x69/i 0x6e/n 0x74/t +34596 _string_f3_0f_2c_truncate_to_int: +34597 0x11/imm32/alloc-id:fake:payload +34598 # "f3 0f 2c/truncate-to-int" +34599 0x18/imm32/size +34600 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x63/c 0x2f/slash 0x74/t 0x72/r 0x75/u 0x6e/n 0x63/c 0x61/a 0x74/t 0x65/e 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x69/i 0x6e/n 0x74/t +34601 _string_f3_0f_58_add: +34602 0x11/imm32/alloc-id:fake:payload +34603 # "f3 0f 58/add" +34604 0xc/imm32/size +34605 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x38/8 0x2f/slash 0x61/a 0x64/d 0x64/d +34606 _string_f3_0f_5c_subtract: +34607 0x11/imm32/alloc-id:fake:payload +34608 # "f3 0f 5c/subtract" +34609 0x11/imm32/size +34610 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x63/c 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +34611 _string_f3_0f_59_multiply: +34612 0x11/imm32/alloc-id:fake:payload +34613 # "f3 0f 59/multiply" +34614 0x11/imm32/size +34615 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x39/9 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +34616 _string_f3_0f_5e_divide: +34617 0x11/imm32/alloc-id:fake:payload +34618 # "f3 0f 5e/divide" +34619 0xf/imm32/size +34620 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x65/e 0x2f/slash 0x64/d 0x69/i 0x76/v 0x69/i 0x64/d 0x65/e +34621 _string_f3_0f_53_reciprocal: +34622 0x11/imm32/alloc-id:fake:payload +34623 # "f3 0f 53/reciprocal" +34624 0x13/imm32/size +34625 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x33/3 0x2f/slash 0x72/r 0x65/e 0x63/c 0x69/i 0x70/p 0x72/r 0x6f/o 0x63/c 0x61/a 0x6c/l +34626 _string_f3_0f_51_square_root: +34627 0x11/imm32/alloc-id:fake:payload +34628 # "f3 0f 51/square-root" +34629 0x14/imm32/size +34630 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x31/1 0x2f/slash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t +34631 _string_f3_0f_52_inverse_square_root: +34632 0x11/imm32/alloc-id:fake:payload +34633 # "f3 0f 52/inverse-square-root" +34634 0x1c/imm32/size +34635 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/dash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t +34636 _string_f3_0f_5d_min: +34637 0x11/imm32/alloc-id:fake:payload +34638 # "f3 0f 5d/min" +34639 0xc/imm32/size +34640 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x64/d 0x2f/slash 0x6d/m 0x69/i 0x6e/n +34641 _string_f3_0f_5f_max: +34642 0x11/imm32/alloc-id:fake:payload +34643 # "f3 0f 5f/max" +34644 0xc/imm32/size +34645 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x66/f 0x2f/slash 0x6d/m 0x61/a 0x78/x +34646 _string_f3_0f_10_copy: +34647 0x11/imm32/alloc-id:fake:payload +34648 # "f3 0f 10/copy" +34649 0xd/imm32/size +34650 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x31/1 0x30/0 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y +34651 _string_f3_0f_11_copy: +34652 0x11/imm32/alloc-id:fake:payload +34653 # "f3 0f 11/copy" +34654 0xd/imm32/size +34655 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x31/1 0x31/1 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y +34656 _string_0f_2f_compare: +34657 0x11/imm32/alloc-id:fake:payload +34658 # "0f 2f/compare" +34659 0xd/imm32/size +34660 0x30/0 0x66/f 0x20/space 0x32/2 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +34661 _string_21_and_with: # (payload array byte) +34662 0x11/imm32/alloc-id:fake:payload +34663 # "21/and-with" +34664 0xb/imm32/size +34665 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +34666 _string_23_and: # (payload array byte) +34667 0x11/imm32/alloc-id:fake:payload +34668 # "23/and" +34669 0x6/imm32/size +34670 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d +34671 _string_25_and_with_eax: # (payload array byte) +34672 0x11/imm32/alloc-id:fake:payload +34673 # "25/and-with-eax" +34674 0xf/imm32/size +34675 0x32/2 0x35/5 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +34676 _string_29_subtract_from: # (payload array byte) +34677 0x11/imm32/alloc-id:fake:payload +34678 # "29/subtract-from" +34679 0x10/imm32/size +34680 0x32/2 0x39/9 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m +34681 _string_2b_subtract: # (payload array byte) +34682 0x11/imm32/alloc-id:fake:payload +34683 # "2b/subtract" +34684 0xb/imm32/size +34685 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +34686 _string_2d_subtract_from_eax: # (payload array byte) +34687 0x11/imm32/alloc-id:fake:payload +34688 # "2d/subtract-from-eax" +34689 0x14/imm32/size +34690 0x32/2 0x64/d 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m 0x2d/dash 0x65/e 0x61/a 0x78/x +34691 _string_31_xor_with: # (payload array byte) +34692 0x11/imm32/alloc-id:fake:payload +34693 # "31/xor-with" +34694 0xb/imm32/size +34695 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +34696 _string_33_xor: # (payload array byte) +34697 0x11/imm32/alloc-id:fake:payload +34698 # "33/xor" +34699 0x6/imm32/size +34700 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r +34701 _string_35_xor_with_eax: # (payload array byte) +34702 0x11/imm32/alloc-id:fake:payload +34703 # "35/xor-with-eax" +34704 0xf/imm32/size +34705 0x33/3 0x35/5 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x +34706 _string_39_compare->: # (payload array byte) +34707 0x11/imm32/alloc-id:fake:payload +34708 # "39/compare->" +34709 0xc/imm32/size +34710 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> +34711 _string_3b_compare<-: # (payload array byte) +34712 0x11/imm32/alloc-id:fake:payload +34713 # "3b/compare<-" +34714 0xc/imm32/size +34715 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash +34716 _string_3d_compare_eax_with: # (payload array byte) +34717 0x11/imm32/alloc-id:fake:payload +34718 # "3d/compare-eax-with" +34719 0x13/imm32/size +34720 0x33/3 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x65/e 0x61/a 0x78/x 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +34721 _string_40_increment_eax: # (payload array byte) +34722 0x11/imm32/alloc-id:fake:payload +34723 # "40/increment-eax" +34724 0x10/imm32/size +34725 0x34/4 0x30/0 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x +34726 _string_41_increment_ecx: # (payload array byte) +34727 0x11/imm32/alloc-id:fake:payload +34728 # "41/increment-ecx" +34729 0x10/imm32/size +34730 0x34/4 0x31/1 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x +34731 _string_42_increment_edx: # (payload array byte) +34732 0x11/imm32/alloc-id:fake:payload +34733 # "42/increment-edx" +34734 0x10/imm32/size +34735 0x34/4 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x +34736 _string_43_increment_ebx: # (payload array byte) +34737 0x11/imm32/alloc-id:fake:payload +34738 # "43/increment-ebx" +34739 0x10/imm32/size +34740 0x34/4 0x33/3 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x +34741 _string_46_increment_esi: # (payload array byte) +34742 0x11/imm32/alloc-id:fake:payload +34743 # "46/increment-esi" +34744 0x10/imm32/size +34745 0x34/4 0x36/6 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i +34746 _string_47_increment_edi: # (payload array byte) +34747 0x11/imm32/alloc-id:fake:payload +34748 # "47/increment-edi" +34749 0x10/imm32/size +34750 0x34/4 0x37/7 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i +34751 _string_48_decrement_eax: # (payload array byte) +34752 0x11/imm32/alloc-id:fake:payload +34753 # "48/decrement-eax" +34754 0x10/imm32/size +34755 0x34/4 0x38/8 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x +34756 _string_49_decrement_ecx: # (payload array byte) +34757 0x11/imm32/alloc-id:fake:payload +34758 # "49/decrement-ecx" +34759 0x10/imm32/size +34760 0x34/4 0x39/9 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x +34761 _string_4a_decrement_edx: # (payload array byte) +34762 0x11/imm32/alloc-id:fake:payload +34763 # "4a/decrement-edx" +34764 0x10/imm32/size +34765 0x34/4 0x61/a 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x +34766 _string_4b_decrement_ebx: # (payload array byte) +34767 0x11/imm32/alloc-id:fake:payload +34768 # "4b/decrement-ebx" +34769 0x10/imm32/size +34770 0x34/4 0x62/b 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x +34771 _string_4e_decrement_esi: # (payload array byte) +34772 0x11/imm32/alloc-id:fake:payload +34773 # "4e/decrement-esi" +34774 0x10/imm32/size +34775 0x34/4 0x65/e 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i +34776 _string_4f_decrement_edi: # (payload array byte) +34777 0x11/imm32/alloc-id:fake:payload +34778 # "4f/decrement-edi" +34779 0x10/imm32/size +34780 0x34/4 0x66/f 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i +34781 _string_81_subop_add: # (payload array byte) +34782 0x11/imm32/alloc-id:fake:payload +34783 # "81 0/subop/add" +34784 0xe/imm32/size +34785 0x38/8 0x31/1 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x64/d 0x64/d +34786 _string_81_subop_or: # (payload array byte) +34787 0x11/imm32/alloc-id:fake:payload +34788 # "81 1/subop/or" +34789 0xd/imm32/size +34790 0x38/8 0x31/1 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6f/o 0x72/r +34791 _string_81_subop_and: # (payload array byte) +34792 0x11/imm32/alloc-id:fake:payload +34793 # "81 4/subop/and" +34794 0xe/imm32/size +34795 0x38/8 0x31/1 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x6e/n 0x64/d +34796 _string_81_subop_subtract: # (payload array byte) +34797 0x11/imm32/alloc-id:fake:payload +34798 # "81 5/subop/subtract" +34799 0x13/imm32/size +34800 0x38/8 0x31/1 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +34801 _string_81_subop_xor: # (payload array byte) +34802 0x11/imm32/alloc-id:fake:payload +34803 # "81 6/subop/xor" +34804 0xe/imm32/size +34805 0x38/8 0x31/1 0x20/space 0x36/6 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x78/x 0x6f/o 0x72/r +34806 _string_81_subop_compare: # (payload array byte) +34807 0x11/imm32/alloc-id:fake:payload +34808 # "81 7/subop/compare" +34809 0x12/imm32/size +34810 0x38/8 0x31/1 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +34811 _string_89_<-: # (payload array byte) +34812 0x11/imm32/alloc-id:fake:payload +34813 # "89/<-" +34814 0x5/imm32/size +34815 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash +34816 _string_8b_->: # (payload array byte) +34817 0x11/imm32/alloc-id:fake:payload +34818 # "8b/->" +34819 0x5/imm32/size +34820 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> +34821 _string_8a_copy_byte: +34822 0x11/imm32/alloc-id:fake:payload +34823 # "8a/byte->" +34824 0x9/imm32/size +34825 0x38/8 0x61/a 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x3e/> +34826 _string_88_copy_byte: +34827 0x11/imm32/alloc-id:fake:payload +34828 # "88/byte<-" +34829 0x9/imm32/size +34830 0x38/8 0x38/8 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/- +34831 _string_8d_copy_address: # (payload array byte) +34832 0x11/imm32/alloc-id:fake:payload +34833 # "8d/copy-address" +34834 0xf/imm32/size +34835 0x38/8 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s +34836 _string_b8_copy_to_eax: # (payload array byte) +34837 0x11/imm32/alloc-id:fake:payload +34838 # "b8/copy-to-eax" +34839 0xe/imm32/size +34840 0x62/b 0x38/8 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x +34841 _string_b9_copy_to_ecx: # (payload array byte) +34842 0x11/imm32/alloc-id:fake:payload +34843 # "b9/copy-to-ecx" +34844 0xe/imm32/size +34845 0x62/b 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x63/c 0x78/x +34846 _string_ba_copy_to_edx: # (payload array byte) +34847 0x11/imm32/alloc-id:fake:payload +34848 # "ba/copy-to-edx" +34849 0xe/imm32/size +34850 0x62/b 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x78/x +34851 _string_bb_copy_to_ebx: # (payload array byte) +34852 0x11/imm32/alloc-id:fake:payload +34853 # "bb/copy-to-ebx" +34854 0xe/imm32/size +34855 0x62/b 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x62/b 0x78/x +34856 _string_be_copy_to_esi: # (payload array byte) +34857 0x11/imm32/alloc-id:fake:payload +34858 # "be/copy-to-esi" +34859 0xe/imm32/size +34860 0x62/b 0x65/e 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x73/s 0x69/i +34861 _string_bf_copy_to_edi: # (payload array byte) +34862 0x11/imm32/alloc-id:fake:payload +34863 # "bf/copy-to-edi" +34864 0xe/imm32/size +34865 0x62/b 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x69/i +34866 _string_c7_subop_copy: # (payload array byte) +34867 0x11/imm32/alloc-id:fake:payload +34868 # "c7 0/subop/copy" +34869 0xf/imm32/size +34870 0x63/c 0x37/7 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y +34871 _string_e9_jump_label: # (payload array byte) +34872 0x11/imm32/alloc-id:fake:payload +34873 # "e9/jump" +34874 0x7/imm32/size +34875 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p +34876 _string_e9_jump_break: # (payload array byte) +34877 0x11/imm32/alloc-id:fake:payload +34878 # "e9/jump break/disp32" +34879 0x14/imm32/size +34880 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34881 _string_e9_jump_loop: # (payload array byte) +34882 0x11/imm32/alloc-id:fake:payload +34883 # "e9/jump loop/disp32" +34884 0x13/imm32/size +34885 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2 +34886 _string_f7_subop_negate: +34887 0x11/imm32/alloc-id:fake:payload +34888 # "f7 3/subop/negate" +34889 0x11/imm32/size +34890 0x66/f 0x37/7 0x20/space 0x33/3 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6e/n 0x65/e 0x67/g 0x61/a 0x74/t 0x65/e +34891 _string_f7_subop_not: +34892 0x11/imm32/alloc-id:fake:payload +34893 # "f7 2/subop/not" +34894 0xe/imm32/size +34895 0x66/f 0x37/7 0x20/space 0x32/2 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6e/n 0x6f/o 0x74/t +34896 _string_ff_subop_increment: # (payload array byte) +34897 0x11/imm32/alloc-id:fake:payload +34898 # "ff 0/subop/increment" +34899 0x14/imm32/size +34900 0x66/f 0x66/f 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +34901 _string_ff_subop_decrement: # (payload array byte) +34902 0x11/imm32/alloc-id:fake:payload +34903 # "ff 1/subop/decrement" +34904 0x14/imm32/size +34905 0x66/f 0x66/f 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +34906 _string_c1_subop_shift_left: # (payload array byte) +34907 0x11/imm32/alloc-id:fake:payload +34908 # "c1/shift 4/subop/left" +34909 0x15/imm32/size +34910 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6c/l 0x65/e 0x66/f 0x74/t +34911 _string_c1_subop_shift_right_padding_zeroes: # (payload array byte) +34912 0x11/imm32/alloc-id:fake:payload +34913 # "c1/shift 5/subop/right-padding-zeroes" +34914 0x25/imm32/size +34915 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x61/a 0x64/d 0x64/d 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x7a/z 0x65/e 0x72/r 0x6f/o 0x65/e 0x73/s +34916 _string_c1_subop_shift_right_preserving_sign: # (payload array byte) +34917 0x11/imm32/alloc-id:fake:payload +34918 # "c1/shift 7/subop/right-preserving-sign" +34919 0x26/imm32/size +34920 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x72/r 0x65/e 0x73/s 0x65/e 0x72/r 0x76/v 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n +34921 +34922 Single-int-var-in-mem: # (payload list var) 34923 0x11/imm32/alloc-id:fake:payload 34924 0x11/imm32/alloc-id:fake -34925 Byte-var-in-mem/imm32 +34925 Int-var-in-mem/imm32 34926 0/imm32/next 34927 0/imm32/next 34928 -34929 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -34930 Byte-var-in-mem: # (payload var) -34931 0x11/imm32/alloc-id:fake:payload +34929 Int-var-in-mem: # (payload var) +34930 0x11/imm32/alloc-id:fake:payload +34931 0/imm32/name 34932 0/imm32/name -34933 0/imm32/name -34934 0x11/imm32/alloc-id:fake -34935 Type-byte/imm32 -34936 1/imm32/some-block-depth -34937 1/imm32/some-stack-offset +34933 0x11/imm32/alloc-id:fake +34934 Type-int/imm32 +34935 1/imm32/some-block-depth +34936 1/imm32/some-stack-offset +34937 0/imm32/no-register 34938 0/imm32/no-register -34939 0/imm32/no-register -34940 -34941 Two-args-int-stack-int-reg: # (payload list var) +34939 +34940 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +34941 Single-byte-var-in-mem: # (payload list var) 34942 0x11/imm32/alloc-id:fake:payload 34943 0x11/imm32/alloc-id:fake -34944 Int-var-in-mem/imm32 -34945 0x11/imm32/alloc-id:fake -34946 Single-int-var-in-some-register/imm32/next +34944 Byte-var-in-mem/imm32 +34945 0/imm32/next +34946 0/imm32/next 34947 -34948 Two-int-args-in-regs: # (payload list var) -34949 0x11/imm32/alloc-id:fake:payload -34950 0x11/imm32/alloc-id:fake -34951 Int-var-in-some-register/imm32 -34952 0x11/imm32/alloc-id:fake -34953 Single-int-var-in-some-register/imm32/next -34954 -34955 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -34956 Two-args-byte-stack-byte-reg: # (payload list var) -34957 0x11/imm32/alloc-id:fake:payload -34958 0x11/imm32/alloc-id:fake -34959 Byte-var-in-mem/imm32 -34960 0x11/imm32/alloc-id:fake -34961 Single-byte-var-in-some-register/imm32/next -34962 -34963 Two-args-int-reg-int-stack: # (payload list var) -34964 0x11/imm32/alloc-id:fake:payload -34965 0x11/imm32/alloc-id:fake -34966 Int-var-in-some-register/imm32 -34967 0x11/imm32/alloc-id:fake -34968 Single-int-var-in-mem/imm32/next -34969 -34970 Two-args-int-eax-int-literal: # (payload list var) -34971 0x11/imm32/alloc-id:fake:payload -34972 0x11/imm32/alloc-id:fake -34973 Int-var-in-eax/imm32 -34974 0x11/imm32/alloc-id:fake -34975 Single-lit-var/imm32/next -34976 -34977 Int-var-and-literal: # (payload list var) -34978 0x11/imm32/alloc-id:fake:payload +34948 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +34949 Byte-var-in-mem: # (payload var) +34950 0x11/imm32/alloc-id:fake:payload +34951 0/imm32/name +34952 0/imm32/name +34953 0x11/imm32/alloc-id:fake +34954 Type-byte/imm32 +34955 1/imm32/some-block-depth +34956 1/imm32/some-stack-offset +34957 0/imm32/no-register +34958 0/imm32/no-register +34959 +34960 Two-args-int-stack-int-reg: # (payload list var) +34961 0x11/imm32/alloc-id:fake:payload +34962 0x11/imm32/alloc-id:fake +34963 Int-var-in-mem/imm32 +34964 0x11/imm32/alloc-id:fake +34965 Single-int-var-in-some-register/imm32/next +34966 +34967 Two-int-args-in-regs: # (payload list var) +34968 0x11/imm32/alloc-id:fake:payload +34969 0x11/imm32/alloc-id:fake +34970 Int-var-in-some-register/imm32 +34971 0x11/imm32/alloc-id:fake +34972 Single-int-var-in-some-register/imm32/next +34973 +34974 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +34975 Two-args-byte-stack-byte-reg: # (payload list var) +34976 0x11/imm32/alloc-id:fake:payload +34977 0x11/imm32/alloc-id:fake +34978 Byte-var-in-mem/imm32 34979 0x11/imm32/alloc-id:fake -34980 Int-var-in-mem/imm32 -34981 0x11/imm32/alloc-id:fake -34982 Single-lit-var/imm32/next -34983 -34984 Int-var-in-register-and-literal: # (payload list var) -34985 0x11/imm32/alloc-id:fake:payload +34980 Single-byte-var-in-some-register/imm32/next +34981 +34982 Two-args-int-reg-int-stack: # (payload list var) +34983 0x11/imm32/alloc-id:fake:payload +34984 0x11/imm32/alloc-id:fake +34985 Int-var-in-some-register/imm32 34986 0x11/imm32/alloc-id:fake -34987 Int-var-in-some-register/imm32 -34988 0x11/imm32/alloc-id:fake -34989 Single-lit-var/imm32/next -34990 -34991 Two-float-args-in-regs: # (payload list var) -34992 0x11/imm32/alloc-id:fake:payload +34987 Single-int-var-in-mem/imm32/next +34988 +34989 Two-args-int-eax-int-literal: # (payload list var) +34990 0x11/imm32/alloc-id:fake:payload +34991 0x11/imm32/alloc-id:fake +34992 Int-var-in-eax/imm32 34993 0x11/imm32/alloc-id:fake -34994 Float-var-in-some-register/imm32 -34995 0x11/imm32/alloc-id:fake -34996 Single-float-var-in-some-register/imm32/next -34997 -34998 Two-args-float-reg-float-stack: # (payload list var) -34999 0x11/imm32/alloc-id:fake:payload +34994 Single-lit-var/imm32/next +34995 +34996 Int-var-and-literal: # (payload list var) +34997 0x11/imm32/alloc-id:fake:payload +34998 0x11/imm32/alloc-id:fake +34999 Int-var-in-mem/imm32 35000 0x11/imm32/alloc-id:fake -35001 Float-var-in-some-register/imm32 -35002 0x11/imm32/alloc-id:fake -35003 Single-float-var-in-mem/imm32/next -35004 -35005 Two-args-float-stack-float-reg: # (payload list var) -35006 0x11/imm32/alloc-id:fake:payload +35001 Single-lit-var/imm32/next +35002 +35003 Int-var-in-register-and-literal: # (payload list var) +35004 0x11/imm32/alloc-id:fake:payload +35005 0x11/imm32/alloc-id:fake +35006 Int-var-in-some-register/imm32 35007 0x11/imm32/alloc-id:fake -35008 Float-var-in-mem/imm32 -35009 0x11/imm32/alloc-id:fake -35010 Single-float-var-in-some-register/imm32/next -35011 -35012 Single-int-var-in-some-register: # (payload list var) -35013 0x11/imm32/alloc-id:fake:payload +35008 Single-lit-var/imm32/next +35009 +35010 Two-float-args-in-regs: # (payload list var) +35011 0x11/imm32/alloc-id:fake:payload +35012 0x11/imm32/alloc-id:fake +35013 Float-var-in-some-register/imm32 35014 0x11/imm32/alloc-id:fake -35015 Int-var-in-some-register/imm32 -35016 0/imm32/next -35017 0/imm32/next -35018 -35019 Single-addr-var-in-some-register: # (payload list var) -35020 0x11/imm32/alloc-id:fake:payload +35015 Single-float-var-in-some-register/imm32/next +35016 +35017 Two-args-float-reg-float-stack: # (payload list var) +35018 0x11/imm32/alloc-id:fake:payload +35019 0x11/imm32/alloc-id:fake +35020 Float-var-in-some-register/imm32 35021 0x11/imm32/alloc-id:fake -35022 Addr-var-in-some-register/imm32 -35023 0/imm32/next -35024 0/imm32/next -35025 -35026 Single-byte-var-in-some-register: # (payload list var) -35027 0x11/imm32/alloc-id:fake:payload +35022 Single-float-var-in-mem/imm32/next +35023 +35024 Two-args-float-stack-float-reg: # (payload list var) +35025 0x11/imm32/alloc-id:fake:payload +35026 0x11/imm32/alloc-id:fake +35027 Float-var-in-mem/imm32 35028 0x11/imm32/alloc-id:fake -35029 Byte-var-in-some-register/imm32 -35030 0/imm32/next -35031 0/imm32/next -35032 -35033 Int-var-in-some-register: # (payload var) -35034 0x11/imm32/alloc-id:fake:payload -35035 0/imm32/name -35036 0/imm32/name -35037 0x11/imm32/alloc-id:fake -35038 Type-int/imm32 -35039 1/imm32/some-block-depth -35040 0/imm32/no-stack-offset -35041 0x11/imm32/alloc-id:fake -35042 Any-register/imm32 -35043 -35044 Any-register: # (payload array byte) -35045 0x11/imm32/alloc-id:fake:payload -35046 1/imm32/size -35047 # data -35048 2a/asterisk -35049 -35050 Addr-var-in-some-register: # (payload var) -35051 0x11/imm32/alloc-id:fake:payload -35052 0/imm32/name -35053 0/imm32/name -35054 0x11/imm32/alloc-id:fake -35055 Type-addr/imm32 -35056 1/imm32/some-block-depth -35057 0/imm32/no-stack-offset -35058 0x11/imm32/alloc-id:fake -35059 Any-register/imm32 -35060 -35061 Byte-var-in-some-register: # (payload var) -35062 0x11/imm32/alloc-id:fake:payload -35063 0/imm32/name -35064 0/imm32/name -35065 0x11/imm32/alloc-id:fake -35066 Type-byte/imm32 -35067 1/imm32/some-block-depth -35068 0/imm32/no-stack-offset -35069 0x11/imm32/alloc-id:fake -35070 Any-register/imm32 -35071 -35072 Single-int-var-in-eax: # (payload list var) -35073 0x11/imm32/alloc-id:fake:payload -35074 0x11/imm32/alloc-id:fake -35075 Int-var-in-eax/imm32 -35076 0/imm32/next -35077 0/imm32/next -35078 -35079 Int-var-in-eax: -35080 0x11/imm32/alloc-id:fake:payload -35081 0/imm32/name +35029 Single-float-var-in-some-register/imm32/next +35030 +35031 Single-int-var-in-some-register: # (payload list var) +35032 0x11/imm32/alloc-id:fake:payload +35033 0x11/imm32/alloc-id:fake +35034 Int-var-in-some-register/imm32 +35035 0/imm32/next +35036 0/imm32/next +35037 +35038 Single-addr-var-in-some-register: # (payload list var) +35039 0x11/imm32/alloc-id:fake:payload +35040 0x11/imm32/alloc-id:fake +35041 Addr-var-in-some-register/imm32 +35042 0/imm32/next +35043 0/imm32/next +35044 +35045 Single-byte-var-in-some-register: # (payload list var) +35046 0x11/imm32/alloc-id:fake:payload +35047 0x11/imm32/alloc-id:fake +35048 Byte-var-in-some-register/imm32 +35049 0/imm32/next +35050 0/imm32/next +35051 +35052 Int-var-in-some-register: # (payload var) +35053 0x11/imm32/alloc-id:fake:payload +35054 0/imm32/name +35055 0/imm32/name +35056 0x11/imm32/alloc-id:fake +35057 Type-int/imm32 +35058 1/imm32/some-block-depth +35059 0/imm32/no-stack-offset +35060 0x11/imm32/alloc-id:fake +35061 Any-register/imm32 +35062 +35063 Any-register: # (payload array byte) +35064 0x11/imm32/alloc-id:fake:payload +35065 1/imm32/size +35066 # data +35067 2a/asterisk +35068 +35069 Addr-var-in-some-register: # (payload var) +35070 0x11/imm32/alloc-id:fake:payload +35071 0/imm32/name +35072 0/imm32/name +35073 0x11/imm32/alloc-id:fake +35074 Type-addr/imm32 +35075 1/imm32/some-block-depth +35076 0/imm32/no-stack-offset +35077 0x11/imm32/alloc-id:fake +35078 Any-register/imm32 +35079 +35080 Byte-var-in-some-register: # (payload var) +35081 0x11/imm32/alloc-id:fake:payload 35082 0/imm32/name -35083 0x11/imm32/alloc-id:fake -35084 Type-int/imm32 -35085 1/imm32/some-block-depth -35086 0/imm32/no-stack-offset -35087 0x11/imm32/alloc-id:fake -35088 $Mu-register-eax/imm32 # can't use Register-eax only to keep our buggy tools/treeshake.cc happy (TODO) -35089 -35090 Single-int-var-in-ecx: # (payload list var) -35091 0x11/imm32/alloc-id:fake:payload -35092 0x11/imm32/alloc-id:fake -35093 Int-var-in-ecx/imm32 -35094 0/imm32/next +35083 0/imm32/name +35084 0x11/imm32/alloc-id:fake +35085 Type-byte/imm32 +35086 1/imm32/some-block-depth +35087 0/imm32/no-stack-offset +35088 0x11/imm32/alloc-id:fake +35089 Any-register/imm32 +35090 +35091 Single-int-var-in-eax: # (payload list var) +35092 0x11/imm32/alloc-id:fake:payload +35093 0x11/imm32/alloc-id:fake +35094 Int-var-in-eax/imm32 35095 0/imm32/next -35096 -35097 Int-var-in-ecx: -35098 0x11/imm32/alloc-id:fake:payload -35099 0/imm32/name +35096 0/imm32/next +35097 +35098 Int-var-in-eax: +35099 0x11/imm32/alloc-id:fake:payload 35100 0/imm32/name -35101 0x11/imm32/alloc-id:fake -35102 Type-int/imm32 -35103 1/imm32/some-block-depth -35104 0/imm32/no-stack-offset -35105 0x11/imm32/alloc-id:fake -35106 $Register-ecx/imm32/register -35107 -35108 Single-int-var-in-edx: # (payload list var) -35109 0x11/imm32/alloc-id:fake:payload -35110 0x11/imm32/alloc-id:fake -35111 Int-var-in-edx/imm32 -35112 0/imm32/next +35101 0/imm32/name +35102 0x11/imm32/alloc-id:fake +35103 Type-int/imm32 +35104 1/imm32/some-block-depth +35105 0/imm32/no-stack-offset +35106 0x11/imm32/alloc-id:fake +35107 $Mu-register-eax/imm32 # can't use Register-eax only to keep our buggy tools/treeshake.cc happy (TODO) +35108 +35109 Single-int-var-in-ecx: # (payload list var) +35110 0x11/imm32/alloc-id:fake:payload +35111 0x11/imm32/alloc-id:fake +35112 Int-var-in-ecx/imm32 35113 0/imm32/next -35114 -35115 Int-var-in-edx: # (payload list var) -35116 0x11/imm32/alloc-id:fake:payload -35117 0/imm32/name +35114 0/imm32/next +35115 +35116 Int-var-in-ecx: +35117 0x11/imm32/alloc-id:fake:payload 35118 0/imm32/name -35119 0x11/imm32/alloc-id:fake -35120 Type-int/imm32 -35121 1/imm32/some-block-depth -35122 0/imm32/no-stack-offset -35123 0x11/imm32/alloc-id:fake -35124 $Register-edx/imm32/register -35125 -35126 Single-int-var-in-ebx: # (payload list var) -35127 0x11/imm32/alloc-id:fake:payload -35128 0x11/imm32/alloc-id:fake -35129 Int-var-in-ebx/imm32 -35130 0/imm32/next +35119 0/imm32/name +35120 0x11/imm32/alloc-id:fake +35121 Type-int/imm32 +35122 1/imm32/some-block-depth +35123 0/imm32/no-stack-offset +35124 0x11/imm32/alloc-id:fake +35125 $Register-ecx/imm32/register +35126 +35127 Single-int-var-in-edx: # (payload list var) +35128 0x11/imm32/alloc-id:fake:payload +35129 0x11/imm32/alloc-id:fake +35130 Int-var-in-edx/imm32 35131 0/imm32/next -35132 -35133 Int-var-in-ebx: # (payload list var) -35134 0x11/imm32/alloc-id:fake:payload -35135 0/imm32/name +35132 0/imm32/next +35133 +35134 Int-var-in-edx: # (payload list var) +35135 0x11/imm32/alloc-id:fake:payload 35136 0/imm32/name -35137 0x11/imm32/alloc-id:fake -35138 Type-int/imm32 -35139 1/imm32/some-block-depth -35140 0/imm32/no-stack-offset -35141 0x11/imm32/alloc-id:fake -35142 $Register-ebx/imm32/register -35143 -35144 Single-int-var-in-esi: # (payload list var) -35145 0x11/imm32/alloc-id:fake:payload -35146 0x11/imm32/alloc-id:fake -35147 Int-var-in-esi/imm32 -35148 0/imm32/next +35137 0/imm32/name +35138 0x11/imm32/alloc-id:fake +35139 Type-int/imm32 +35140 1/imm32/some-block-depth +35141 0/imm32/no-stack-offset +35142 0x11/imm32/alloc-id:fake +35143 $Register-edx/imm32/register +35144 +35145 Single-int-var-in-ebx: # (payload list var) +35146 0x11/imm32/alloc-id:fake:payload +35147 0x11/imm32/alloc-id:fake +35148 Int-var-in-ebx/imm32 35149 0/imm32/next -35150 -35151 Int-var-in-esi: # (payload list var) -35152 0x11/imm32/alloc-id:fake:payload -35153 0/imm32/name +35150 0/imm32/next +35151 +35152 Int-var-in-ebx: # (payload list var) +35153 0x11/imm32/alloc-id:fake:payload 35154 0/imm32/name -35155 0x11/imm32/alloc-id:fake -35156 Type-int/imm32 -35157 1/imm32/some-block-depth -35158 0/imm32/no-stack-offset -35159 0x11/imm32/alloc-id:fake -35160 $Register-esi/imm32/register -35161 -35162 Single-int-var-in-edi: # (payload list var) -35163 0x11/imm32/alloc-id:fake:payload -35164 0x11/imm32/alloc-id:fake -35165 Int-var-in-edi/imm32 -35166 0/imm32/next +35155 0/imm32/name +35156 0x11/imm32/alloc-id:fake +35157 Type-int/imm32 +35158 1/imm32/some-block-depth +35159 0/imm32/no-stack-offset +35160 0x11/imm32/alloc-id:fake +35161 $Register-ebx/imm32/register +35162 +35163 Single-int-var-in-esi: # (payload list var) +35164 0x11/imm32/alloc-id:fake:payload +35165 0x11/imm32/alloc-id:fake +35166 Int-var-in-esi/imm32 35167 0/imm32/next -35168 -35169 Int-var-in-edi: # (payload list var) -35170 0x11/imm32/alloc-id:fake:payload -35171 0/imm32/name +35168 0/imm32/next +35169 +35170 Int-var-in-esi: # (payload list var) +35171 0x11/imm32/alloc-id:fake:payload 35172 0/imm32/name -35173 0x11/imm32/alloc-id:fake -35174 Type-int/imm32 -35175 1/imm32/some-block-depth -35176 0/imm32/no-stack-offset -35177 0x11/imm32/alloc-id:fake -35178 $Register-edi/imm32/register -35179 -35180 Single-lit-var: # (payload list var) -35181 0x11/imm32/alloc-id:fake:payload -35182 0x11/imm32/alloc-id:fake -35183 Lit-var/imm32 -35184 0/imm32/next +35173 0/imm32/name +35174 0x11/imm32/alloc-id:fake +35175 Type-int/imm32 +35176 1/imm32/some-block-depth +35177 0/imm32/no-stack-offset +35178 0x11/imm32/alloc-id:fake +35179 $Register-esi/imm32/register +35180 +35181 Single-int-var-in-edi: # (payload list var) +35182 0x11/imm32/alloc-id:fake:payload +35183 0x11/imm32/alloc-id:fake +35184 Int-var-in-edi/imm32 35185 0/imm32/next -35186 -35187 Lit-var: # (payload var) -35188 0x11/imm32/alloc-id:fake:payload -35189 0/imm32/name +35186 0/imm32/next +35187 +35188 Int-var-in-edi: # (payload list var) +35189 0x11/imm32/alloc-id:fake:payload 35190 0/imm32/name -35191 0x11/imm32/alloc-id:fake -35192 Type-literal/imm32 -35193 1/imm32/some-block-depth -35194 0/imm32/no-stack-offset -35195 0/imm32/no-register -35196 0/imm32/no-register -35197 -35198 Single-float-var-in-mem: # (payload list var) -35199 0x11/imm32/alloc-id:fake:payload -35200 0x11/imm32/alloc-id:fake -35201 Float-var-in-mem/imm32 -35202 0/imm32/next +35191 0/imm32/name +35192 0x11/imm32/alloc-id:fake +35193 Type-int/imm32 +35194 1/imm32/some-block-depth +35195 0/imm32/no-stack-offset +35196 0x11/imm32/alloc-id:fake +35197 $Register-edi/imm32/register +35198 +35199 Single-lit-var: # (payload list var) +35200 0x11/imm32/alloc-id:fake:payload +35201 0x11/imm32/alloc-id:fake +35202 Lit-var/imm32 35203 0/imm32/next -35204 -35205 Float-var-in-mem: # (payload var) -35206 0x11/imm32/alloc-id:fake:payload -35207 0/imm32/name +35204 0/imm32/next +35205 +35206 Lit-var: # (payload var) +35207 0x11/imm32/alloc-id:fake:payload 35208 0/imm32/name -35209 0x11/imm32/alloc-id:fake -35210 Type-float/imm32 -35211 1/imm32/some-block-depth -35212 1/imm32/some-stack-offset -35213 0/imm32/no-register +35209 0/imm32/name +35210 0x11/imm32/alloc-id:fake +35211 Type-literal/imm32 +35212 1/imm32/some-block-depth +35213 0/imm32/no-stack-offset 35214 0/imm32/no-register -35215 -35216 Single-float-var-in-some-register: # (payload list var) -35217 0x11/imm32/alloc-id:fake:payload -35218 0x11/imm32/alloc-id:fake -35219 Float-var-in-some-register/imm32 -35220 0/imm32/next +35215 0/imm32/no-register +35216 +35217 Single-float-var-in-mem: # (payload list var) +35218 0x11/imm32/alloc-id:fake:payload +35219 0x11/imm32/alloc-id:fake +35220 Float-var-in-mem/imm32 35221 0/imm32/next -35222 -35223 Float-var-in-some-register: # (payload var) -35224 0x11/imm32/alloc-id:fake:payload -35225 0/imm32/name +35222 0/imm32/next +35223 +35224 Float-var-in-mem: # (payload var) +35225 0x11/imm32/alloc-id:fake:payload 35226 0/imm32/name -35227 0x11/imm32/alloc-id:fake -35228 Type-float/imm32 -35229 1/imm32/some-block-depth -35230 0/imm32/no-stack-offset -35231 0x11/imm32/alloc-id:fake -35232 Any-register/imm32 -35233 -35234 Type-int: # (payload type-tree) -35235 0x11/imm32/alloc-id:fake:payload -35236 1/imm32/is-atom -35237 1/imm32/value:int -35238 0/imm32/left:unused -35239 0/imm32/right:null -35240 0/imm32/right:null +35227 0/imm32/name +35228 0x11/imm32/alloc-id:fake +35229 Type-float/imm32 +35230 1/imm32/some-block-depth +35231 1/imm32/some-stack-offset +35232 0/imm32/no-register +35233 0/imm32/no-register +35234 +35235 Single-float-var-in-some-register: # (payload list var) +35236 0x11/imm32/alloc-id:fake:payload +35237 0x11/imm32/alloc-id:fake +35238 Float-var-in-some-register/imm32 +35239 0/imm32/next +35240 0/imm32/next 35241 -35242 Type-literal: # (payload type-tree) +35242 Float-var-in-some-register: # (payload var) 35243 0x11/imm32/alloc-id:fake:payload -35244 1/imm32/is-atom -35245 0/imm32/value:literal -35246 0/imm32/left:unused -35247 0/imm32/right:null -35248 0/imm32/right:null -35249 -35250 Type-addr: # (payload type-tree) -35251 0x11/imm32/alloc-id:fake:payload -35252 1/imm32/is-atom -35253 2/imm32/value:addr -35254 0/imm32/left:unused -35255 0/imm32/right:null -35256 0/imm32/right:null -35257 -35258 Type-byte: # (payload type-tree) -35259 0x11/imm32/alloc-id:fake:payload -35260 1/imm32/is-atom -35261 8/imm32/value:byte -35262 0/imm32/left:unused -35263 0/imm32/right:null -35264 0/imm32/right:null -35265 -35266 Type-float: # (payload type-tree) -35267 0x11/imm32/alloc-id:fake:payload -35268 1/imm32/is-atom -35269 0xf/imm32/value:float -35270 0/imm32/left:unused -35271 0/imm32/right:null -35272 0/imm32/right:null -35273 -35274 == code -35275 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) -35276 # . prologue -35277 55/push-ebp -35278 89/<- %ebp 4/r32/esp -35279 # . save registers -35280 50/push-eax -35281 51/push-ecx -35282 # ecx = primitive -35283 8b/-> *(ebp+0x10) 1/r32/ecx -35284 # emit primitive name -35285 (emit-indent *(ebp+8) *Curr-block-depth) -35286 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax -35287 (write-buffered *(ebp+8) %eax) -35288 # emit rm32 if necessary -35289 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32 -35290 # emit xm32 if necessary -35291 (emit-subx-rm32 *(ebp+8) *(ecx+0x34) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-xm32 -35292 # emit r32 if necessary -35293 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32 -35294 # emit x32 if necessary -35295 (emit-subx-x32 *(ebp+8) *(ecx+0x38) *(ebp+0xc)) # Primitive-subx-x32 -35296 # emit imm32 if necessary -35297 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32 -35298 # emit imm8 if necessary -35299 (emit-subx-imm8 *(ebp+8) *(ecx+0x2c) *(ebp+0xc)) # Primitive-subx-imm8 -35300 # emit disp32 if necessary -35301 (emit-subx-disp32 *(ebp+8) *(ecx+0x30) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32 -35302 (write-buffered *(ebp+8) Newline) -35303 $emit-subx-primitive:end: -35304 # . restore registers -35305 59/pop-to-ecx -35306 58/pop-to-eax -35307 # . epilogue -35308 89/<- %esp 5/r32/ebp -35309 5d/pop-to-ebp -35310 c3/return -35311 -35312 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -35313 # . prologue -35314 55/push-ebp -35315 89/<- %ebp 4/r32/esp -35316 # . save registers -35317 50/push-eax -35318 # if (l == 0) return -35319 81 7/subop/compare *(ebp+0xc) 0/imm32 -35320 74/jump-if-= $emit-subx-rm32:end/disp8 -35321 # var v/eax: (addr stmt-var) -35322 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax -35323 (emit-subx-var-as-rm32 *(ebp+8) %eax) -35324 $emit-subx-rm32:end: -35325 # . restore registers -35326 58/pop-to-eax -35327 # . epilogue -35328 89/<- %esp 5/r32/ebp -35329 5d/pop-to-ebp -35330 c3/return -35331 -35332 get-stmt-operand-from-arg-location: # stmt: (addr stmt), l: arg-location, err: (addr buffered-file), ed: (addr exit-descriptor) -> var/eax: (addr stmt-var) -35333 # . prologue -35334 55/push-ebp -35335 89/<- %ebp 4/r32/esp -35336 # . save registers -35337 51/push-ecx -35338 # eax = l -35339 8b/-> *(ebp+0xc) 0/r32/eax -35340 # ecx = stmt -35341 8b/-> *(ebp+8) 1/r32/ecx -35342 # if (l == 1) return stmt->inouts -35343 { -35344 3d/compare-eax-and 1/imm32 -35345 75/jump-if-!= break/disp8 -35346 $get-stmt-operand-from-arg-location:1: -35347 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -35348 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -35349 } -35350 # if (l == 2) return stmt->inouts->next -35351 { -35352 3d/compare-eax-and 2/imm32 -35353 75/jump-if-!= break/disp8 -35354 $get-stmt-operand-from-arg-location:2: -35355 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -35356 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -35357 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -35358 } -35359 # if (l == 3) return stmt->outputs -35360 { -35361 3d/compare-eax-and 3/imm32 -35362 75/jump-if-!= break/disp8 -35363 $get-stmt-operand-from-arg-location:3: -35364 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -35365 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -35366 } -35367 # abort -35368 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 -35369 $get-stmt-operand-from-arg-location:end: -35370 # . restore registers -35371 59/pop-to-ecx -35372 # . epilogue -35373 89/<- %esp 5/r32/ebp -35374 5d/pop-to-ebp -35375 c3/return -35376 -35377 $get-stmt-operand-from-arg-location:abort: -35378 # error("invalid arg-location " eax) -35379 (write-buffered *(ebp+0x10) "invalid arg-location ") -35380 (write-int32-hex-buffered *(ebp+0x10) %eax) -35381 (write-buffered *(ebp+0x10) Newline) -35382 (flush *(ebp+0x10)) -35383 (stop *(ebp+0x14) 1) -35384 # never gets here -35385 -35386 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -35387 # . prologue -35388 55/push-ebp -35389 89/<- %ebp 4/r32/esp -35390 # . save registers -35391 50/push-eax -35392 51/push-ecx -35393 # if (l == 0) return -35394 81 7/subop/compare *(ebp+0xc) 0/imm32 -35395 0f 84/jump-if-= $emit-subx-r32:end/disp32 -35396 # var v/eax: (addr stmt-var) -35397 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -35398 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -35399 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -35400 #? (write-buffered Stderr "looking up ") -35401 #? (write-buffered Stderr %eax) -35402 #? (write-buffered Stderr Newline) -35403 #? (flush Stderr) -35404 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) -35405 (write-buffered *(ebp+8) Space) -35406 (write-int32-hex-buffered *(ebp+8) *eax) -35407 (write-buffered *(ebp+8) "/r32") -35408 $emit-subx-r32:end: -35409 # . restore registers -35410 59/pop-to-ecx -35411 58/pop-to-eax -35412 # . epilogue -35413 89/<- %esp 5/r32/ebp -35414 5d/pop-to-ebp -35415 c3/return -35416 -35417 emit-subx-x32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -35418 # . prologue -35419 55/push-ebp -35420 89/<- %ebp 4/r32/esp -35421 # . save registers -35422 50/push-eax -35423 51/push-ecx -35424 # if (l == 0) return -35425 81 7/subop/compare *(ebp+0xc) 0/imm32 -35426 0f 84/jump-if-= $emit-subx-x32:end/disp32 -35427 # var v/eax: (addr stmt-var) -35428 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -35429 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -35430 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -35431 #? (write-buffered Stderr "looking up ") -35432 #? (write-buffered Stderr %eax) -35433 #? (write-buffered Stderr Newline) -35434 #? (flush Stderr) -35435 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) -35436 (write-buffered *(ebp+8) Space) -35437 (write-int32-hex-buffered *(ebp+8) *eax) -35438 (write-buffered *(ebp+8) "/x32") -35439 $emit-subx-x32:end: -35440 # . restore registers -35441 59/pop-to-ecx -35442 58/pop-to-eax -35443 # . epilogue -35444 89/<- %esp 5/r32/ebp -35445 5d/pop-to-ebp -35446 c3/return -35447 -35448 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -35449 # . prologue -35450 55/push-ebp -35451 89/<- %ebp 4/r32/esp -35452 # . save registers -35453 50/push-eax -35454 51/push-ecx -35455 # if (l == 0) return -35456 81 7/subop/compare *(ebp+0xc) 0/imm32 -35457 0f 84/jump-if-= $emit-subx-imm32:end/disp32 -35458 # var v/eax: (handle var) -35459 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -35460 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -35461 (lookup *eax *(eax+4)) # Var-name Var-name => eax -35462 (write-buffered *(ebp+8) Space) -35463 (write-buffered *(ebp+8) %eax) -35464 (write-buffered *(ebp+8) "/imm32") -35465 $emit-subx-imm32:end: -35466 # . restore registers -35467 59/pop-to-ecx -35468 58/pop-to-eax -35469 # . epilogue -35470 89/<- %esp 5/r32/ebp -35471 5d/pop-to-ebp -35472 c3/return -35473 -35474 emit-subx-imm8: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -35475 # . prologue -35476 55/push-ebp -35477 89/<- %ebp 4/r32/esp -35478 # . save registers -35479 50/push-eax -35480 51/push-ecx -35481 # if (l == 0) return -35482 81 7/subop/compare *(ebp+0xc) 0/imm32 -35483 0f 84/jump-if-= $emit-subx-imm32:end/disp32 -35484 # var v/eax: (handle var) -35485 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -35486 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -35487 (lookup *eax *(eax+4)) # Var-name Var-name => eax -35488 (write-buffered *(ebp+8) Space) -35489 (write-buffered *(ebp+8) %eax) -35490 (write-buffered *(ebp+8) "/imm8") -35491 $emit-subx-imm8:end: -35492 # . restore registers -35493 59/pop-to-ecx -35494 58/pop-to-eax -35495 # . epilogue -35496 89/<- %esp 5/r32/ebp -35497 5d/pop-to-ebp -35498 c3/return -35499 -35500 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -35501 # . prologue -35502 55/push-ebp -35503 89/<- %ebp 4/r32/esp -35504 # . save registers -35505 50/push-eax -35506 51/push-ecx -35507 # if (location == 0) return -35508 81 7/subop/compare *(ebp+0xc) 0/imm32 -35509 0f 84/jump-if-= $emit-subx-disp32:end/disp32 -35510 # var v/eax: (addr stmt-var) -35511 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax -35512 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -35513 (lookup *eax *(eax+4)) # Var-name Var-name => eax -35514 (write-buffered *(ebp+8) Space) -35515 (write-buffered *(ebp+8) %eax) -35516 # hack: if instruction operation starts with "break", emit ":break" -35517 # var name/ecx: (addr array byte) = lookup(stmt->operation) -35518 8b/-> *(ebp+0x10) 0/r32/eax -35519 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -35520 89/<- %ecx 0/r32/eax -35521 { -35522 (string-starts-with? %ecx "break") # => eax -35523 3d/compare-eax-and 0/imm32/false -35524 74/jump-if-= break/disp8 -35525 (write-buffered *(ebp+8) ":break") -35526 } -35527 # hack: if instruction operation starts with "loop", emit ":loop" -35528 { -35529 (string-starts-with? %ecx "loop") # => eax -35530 3d/compare-eax-and 0/imm32/false -35531 74/jump-if-= break/disp8 -35532 (write-buffered *(ebp+8) ":loop") -35533 } -35534 (write-buffered *(ebp+8) "/disp32") -35535 $emit-subx-disp32:end: -35536 # . restore registers -35537 59/pop-to-ecx -35538 58/pop-to-eax -35539 # . epilogue -35540 89/<- %esp 5/r32/ebp -35541 5d/pop-to-ebp -35542 c3/return -35543 -35544 emit-call: # out: (addr buffered-file), stmt: (addr stmt) -35545 # . prologue -35546 55/push-ebp -35547 89/<- %ebp 4/r32/esp -35548 # . save registers -35549 50/push-eax -35550 51/push-ecx -35551 # -35552 (emit-indent *(ebp+8) *Curr-block-depth) -35553 (write-buffered *(ebp+8) "(") -35554 # ecx = stmt -35555 8b/-> *(ebp+0xc) 1/r32/ecx -35556 # - emit function name -35557 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -35558 (write-buffered *(ebp+8) %eax) -35559 # - emit arguments -35560 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) -35561 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -35562 { -35563 # if (curr == null) break -35564 3d/compare-eax-and 0/imm32 -35565 74/jump-if-= break/disp8 -35566 # -35567 (emit-subx-call-operand *(ebp+8) %eax) -35568 # curr = lookup(curr->next) -35569 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -35570 eb/jump loop/disp8 -35571 } -35572 # -35573 (write-buffered *(ebp+8) ")\n") -35574 $emit-call:end: -35575 # . restore registers -35576 59/pop-to-ecx -35577 58/pop-to-eax -35578 # . epilogue -35579 89/<- %esp 5/r32/ebp -35580 5d/pop-to-ebp -35581 c3/return -35582 -35583 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) -35584 # shares code with emit-subx-var-as-rm32 -35585 # . prologue -35586 55/push-ebp -35587 89/<- %ebp 4/r32/esp -35588 # . save registers -35589 50/push-eax -35590 51/push-ecx -35591 56/push-esi -35592 # ecx = s -35593 8b/-> *(ebp+0xc) 1/r32/ecx -35594 # var operand/esi: (addr var) = lookup(s->value) -35595 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -35596 89/<- %esi 0/r32/eax -35597 # if (operand->register && !s->is-deref?) emit "%__" -35598 { -35599 $emit-subx-call-operand:check-for-register-direct: -35600 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -35601 74/jump-if-= break/disp8 -35602 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -35603 75/jump-if-!= break/disp8 -35604 $emit-subx-call-operand:register-direct: -35605 (write-buffered *(ebp+8) " %") -35606 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -35607 (write-buffered *(ebp+8) %eax) -35608 e9/jump $emit-subx-call-operand:end/disp32 -35609 } -35610 # else if (operand->register && s->is-deref?) emit "*__" -35611 { -35612 $emit-subx-call-operand:check-for-register-indirect: -35613 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -35614 74/jump-if-= break/disp8 -35615 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -35616 74/jump-if-= break/disp8 -35617 $emit-subx-call-operand:register-indirect: -35618 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) -35619 e9/jump $emit-subx-call-operand:end/disp32 -35620 } -35621 # else if (operand->stack-offset) emit "*(ebp+__)" -35622 { -35623 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -35624 74/jump-if-= break/disp8 -35625 $emit-subx-call-operand:stack: -35626 (emit-subx-call-operand-stack *(ebp+8) %esi) -35627 e9/jump $emit-subx-call-operand:end/disp32 -35628 } -35629 # else if (operand->type == literal) emit "__" -35630 { -35631 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -35632 81 7/subop/compare *(eax+4) 0/imm32 # Type-tree-value -35633 75/jump-if-!= break/disp8 -35634 $emit-subx-call-operand:literal: -35635 (write-buffered *(ebp+8) Space) -35636 (lookup *esi *(esi+4)) # Var-name Var-name => eax -35637 (write-buffered *(ebp+8) %eax) -35638 e9/jump $emit-subx-call-operand:end/disp32 -35639 } -35640 # else if (operand->type == literal-string) emit "__" -35641 { -35642 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -35643 81 7/subop/compare *(eax+4) 0x10/imm32 # Type-tree-value -35644 75/jump-if-!= break/disp8 -35645 $emit-subx-call-operand:literal-string: -35646 (write-buffered *(ebp+8) Space) -35647 (lookup *esi *(esi+4)) # Var-name Var-name => eax -35648 (write-buffered *(ebp+8) %eax) -35649 } -35650 $emit-subx-call-operand:end: -35651 # . restore registers -35652 5e/pop-to-esi -35653 59/pop-to-ecx -35654 58/pop-to-eax -35655 # . epilogue -35656 89/<- %esp 5/r32/ebp -35657 5d/pop-to-ebp -35658 c3/return -35659 -35660 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) -35661 # . prologue -35662 55/push-ebp -35663 89/<- %ebp 4/r32/esp -35664 # . save registers -35665 50/push-eax -35666 51/push-ecx -35667 56/push-esi -35668 # esi = v -35669 8b/-> *(ebp+0xc) 6/r32/esi -35670 # var size/ecx: int = size-of-deref(v) -35671 (size-of-deref %esi) # => eax -35672 89/<- %ecx 0/r32/eax -35673 # var reg-name/esi: (addr array byte) = lookup(v->register) -35674 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -35675 89/<- %esi 0/r32/eax -35676 # TODO: assert size is a multiple of 4 -35677 # var i/eax: int = 0 -35678 b8/copy-to-eax 0/imm32 -35679 { -35680 $emit-subx-call-operand-register-indirect:loop: -35681 # if (i >= size) break -35682 39/compare %eax 1/r32/ecx -35683 7d/jump-if->= break/disp8 -35684 # emit " *(" v->register "+" i ")" -35685 (write-buffered *(ebp+8) " *(") -35686 (write-buffered *(ebp+8) %esi) -35687 (write-buffered *(ebp+8) "+") -35688 (write-int32-hex-buffered *(ebp+8) %eax) -35689 (write-buffered *(ebp+8) ")") -35690 # i += 4 -35691 05/add-to-eax 4/imm32 -35692 # -35693 eb/jump loop/disp8 -35694 } -35695 $emit-subx-call-operand-register-indirect:end: -35696 # . restore registers -35697 5e/pop-to-esi -35698 59/pop-to-ecx -35699 58/pop-to-eax -35700 # . epilogue -35701 89/<- %esp 5/r32/ebp -35702 5d/pop-to-ebp -35703 c3/return -35704 -35705 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) -35706 # . prologue -35707 55/push-ebp -35708 89/<- %ebp 4/r32/esp -35709 # . save registers -35710 50/push-eax -35711 51/push-ecx -35712 56/push-esi -35713 # esi = v -35714 8b/-> *(ebp+0xc) 6/r32/esi -35715 # var curr/ecx: int = v->offset -35716 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset -35717 # var max/eax: int = v->offset + size-of(v) -35718 (size-of %esi) # => eax -35719 # TODO: assert size is a multiple of 4 -35720 01/add-to %eax 1/r32/ecx -35721 { -35722 $emit-subx-call-operand-stack:loop: -35723 # if (curr >= max) break -35724 39/compare %ecx 0/r32/eax -35725 7d/jump-if->= break/disp8 -35726 # emit " *(ebp+" curr ")" -35727 (write-buffered *(ebp+8) " *(ebp+") -35728 (write-int32-hex-buffered *(ebp+8) %ecx) -35729 (write-buffered *(ebp+8) ")") -35730 # i += 4 -35731 81 0/subop/add %ecx 4/imm32 -35732 # -35733 eb/jump loop/disp8 -35734 } -35735 $emit-subx-call-operand-stack:end: -35736 # . restore registers -35737 5e/pop-to-esi -35738 59/pop-to-ecx -35739 58/pop-to-eax -35740 # . epilogue -35741 89/<- %esp 5/r32/ebp -35742 5d/pop-to-ebp -35743 c3/return -35744 -35745 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) -35746 # . prologue -35747 55/push-ebp -35748 89/<- %ebp 4/r32/esp -35749 # . save registers -35750 50/push-eax -35751 51/push-ecx -35752 56/push-esi -35753 # ecx = s -35754 8b/-> *(ebp+0xc) 1/r32/ecx -35755 # var operand/esi: (addr var) = lookup(s->value) -35756 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -35757 89/<- %esi 0/r32/eax -35758 # if (operand->register && s->is-deref?) emit "*__" -35759 { -35760 $emit-subx-var-as-rm32:check-for-register-indirect: -35761 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -35762 74/jump-if-= break/disp8 -35763 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -35764 74/jump-if-= break/disp8 -35765 $emit-subx-var-as-rm32:register-indirect: -35766 (write-buffered *(ebp+8) " *") -35767 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -35768 (write-buffered *(ebp+8) %eax) -35769 e9/jump $emit-subx-var-as-rm32:end/disp32 -35770 } -35771 # if (operand->register && !s->is-deref?) emit "%__" -35772 { -35773 $emit-subx-var-as-rm32:check-for-register-direct: -35774 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -35775 74/jump-if-= break/disp8 -35776 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -35777 75/jump-if-!= break/disp8 -35778 $emit-subx-var-as-rm32:register-direct: -35779 (write-buffered *(ebp+8) " %") -35780 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -35781 (write-buffered *(ebp+8) %eax) -35782 e9/jump $emit-subx-var-as-rm32:end/disp32 -35783 } -35784 # else if (operand->stack-offset) emit "*(ebp+__)" -35785 { -35786 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -35787 74/jump-if-= break/disp8 -35788 $emit-subx-var-as-rm32:stack: -35789 (write-buffered *(ebp+8) Space) -35790 (write-buffered *(ebp+8) "*(ebp+") -35791 (write-int32-hex-buffered *(ebp+8) *(esi+0x14)) # Var-offset -35792 (write-buffered *(ebp+8) ")") -35793 } -35794 $emit-subx-var-as-rm32:end: -35795 # . restore registers -35796 5e/pop-to-esi -35797 59/pop-to-ecx -35798 58/pop-to-eax -35799 # . epilogue -35800 89/<- %esp 5/r32/ebp -35801 5d/pop-to-ebp -35802 c3/return -35803 -35804 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) -35805 # . prologue -35806 55/push-ebp -35807 89/<- %ebp 4/r32/esp -35808 # . save registers -35809 51/push-ecx -35810 # var curr/ecx: (addr primitive) = primitives -35811 8b/-> *(ebp+8) 1/r32/ecx -35812 { -35813 $find-matching-primitive:loop: -35814 # if (curr == null) break -35815 81 7/subop/compare %ecx 0/imm32 -35816 74/jump-if-= break/disp8 -35817 # if match(curr, stmt) return curr -35818 { -35819 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax -35820 3d/compare-eax-and 0/imm32/false -35821 74/jump-if-= break/disp8 -35822 89/<- %eax 1/r32/ecx -35823 eb/jump $find-matching-primitive:end/disp8 -35824 } -35825 $find-matching-primitive:next-primitive: -35826 # curr = curr->next -35827 (lookup *(ecx+0x3c) *(ecx+0x40)) # Primitive-next Primitive-next => eax -35828 89/<- %ecx 0/r32/eax -35829 # -35830 e9/jump loop/disp32 +35244 0/imm32/name +35245 0/imm32/name +35246 0x11/imm32/alloc-id:fake +35247 Type-float/imm32 +35248 1/imm32/some-block-depth +35249 0/imm32/no-stack-offset +35250 0x11/imm32/alloc-id:fake +35251 Any-register/imm32 +35252 +35253 Type-int: # (payload type-tree) +35254 0x11/imm32/alloc-id:fake:payload +35255 1/imm32/is-atom +35256 1/imm32/value:int +35257 0/imm32/left:unused +35258 0/imm32/right:null +35259 0/imm32/right:null +35260 +35261 Type-literal: # (payload type-tree) +35262 0x11/imm32/alloc-id:fake:payload +35263 1/imm32/is-atom +35264 0/imm32/value:literal +35265 0/imm32/left:unused +35266 0/imm32/right:null +35267 0/imm32/right:null +35268 +35269 Type-addr: # (payload type-tree) +35270 0x11/imm32/alloc-id:fake:payload +35271 1/imm32/is-atom +35272 2/imm32/value:addr +35273 0/imm32/left:unused +35274 0/imm32/right:null +35275 0/imm32/right:null +35276 +35277 Type-array: # (payload type-tree) +35278 0x11/imm32/alloc-id:fake:payload +35279 1/imm32/is-atom +35280 3/imm32/value:array +35281 0/imm32/left:unused +35282 0/imm32/right:null +35283 0/imm32/right:null +35284 +35285 Type-byte: # (payload type-tree) +35286 0x11/imm32/alloc-id:fake:payload +35287 1/imm32/is-atom +35288 8/imm32/value:byte +35289 0/imm32/left:unused +35290 0/imm32/right:null +35291 0/imm32/right:null +35292 +35293 Type-float: # (payload type-tree) +35294 0x11/imm32/alloc-id:fake:payload +35295 1/imm32/is-atom +35296 0xf/imm32/value:float +35297 0/imm32/left:unused +35298 0/imm32/right:null +35299 0/imm32/right:null +35300 +35301 Addr-type-string: # (addr type-tree) +35302 0/imm32/not-atom +35303 0x11/imm32/alloc-id:fake +35304 Type-addr/imm32/left +35305 0x11/imm32/alloc-id:fake +35306 _Addr-type-string:array/imm32/right +35307 _Addr-type-string:array: # (payload type-tree) +35308 0x11/imm32/alloc-id:fake:payload +35309 0/imm32/not-atom +35310 0x11/imm32/alloc-id:fake +35311 Type-array/imm32/left +35312 0x11/imm32/alloc-id:fake +35313 _Addr-type-string:byte/imm32/right +35314 _Addr-type-string:byte: # (payload type-tree) +35315 0x11/imm32/alloc-id:fake:payload +35316 0/imm32/not-atom +35317 0x11/imm32/alloc-id:fake +35318 Type-byte/imm32/left +35319 0/imm32/right:null +35320 0/imm32/right:null +35321 +35322 == code +35323 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) +35324 # . prologue +35325 55/push-ebp +35326 89/<- %ebp 4/r32/esp +35327 # . save registers +35328 50/push-eax +35329 51/push-ecx +35330 # ecx = primitive +35331 8b/-> *(ebp+0x10) 1/r32/ecx +35332 # emit primitive name +35333 (emit-indent *(ebp+8) *Curr-block-depth) +35334 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax +35335 (write-buffered *(ebp+8) %eax) +35336 # emit rm32 if necessary +35337 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32 +35338 # emit xm32 if necessary +35339 (emit-subx-rm32 *(ebp+8) *(ecx+0x34) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-xm32 +35340 # emit r32 if necessary +35341 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32 +35342 # emit x32 if necessary +35343 (emit-subx-x32 *(ebp+8) *(ecx+0x38) *(ebp+0xc)) # Primitive-subx-x32 +35344 # emit imm32 if necessary +35345 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32 +35346 # emit imm8 if necessary +35347 (emit-subx-imm8 *(ebp+8) *(ecx+0x2c) *(ebp+0xc)) # Primitive-subx-imm8 +35348 # emit disp32 if necessary +35349 (emit-subx-disp32 *(ebp+8) *(ecx+0x30) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32 +35350 (write-buffered *(ebp+8) Newline) +35351 $emit-subx-primitive:end: +35352 # . restore registers +35353 59/pop-to-ecx +35354 58/pop-to-eax +35355 # . epilogue +35356 89/<- %esp 5/r32/ebp +35357 5d/pop-to-ebp +35358 c3/return +35359 +35360 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +35361 # . prologue +35362 55/push-ebp +35363 89/<- %ebp 4/r32/esp +35364 # . save registers +35365 50/push-eax +35366 # if (l == 0) return +35367 81 7/subop/compare *(ebp+0xc) 0/imm32 +35368 74/jump-if-= $emit-subx-rm32:end/disp8 +35369 # var v/eax: (addr stmt-var) +35370 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax +35371 (emit-subx-var-as-rm32 *(ebp+8) %eax) +35372 $emit-subx-rm32:end: +35373 # . restore registers +35374 58/pop-to-eax +35375 # . epilogue +35376 89/<- %esp 5/r32/ebp +35377 5d/pop-to-ebp +35378 c3/return +35379 +35380 get-stmt-operand-from-arg-location: # stmt: (addr stmt), l: arg-location, err: (addr buffered-file), ed: (addr exit-descriptor) -> var/eax: (addr stmt-var) +35381 # . prologue +35382 55/push-ebp +35383 89/<- %ebp 4/r32/esp +35384 # . save registers +35385 51/push-ecx +35386 # eax = l +35387 8b/-> *(ebp+0xc) 0/r32/eax +35388 # ecx = stmt +35389 8b/-> *(ebp+8) 1/r32/ecx +35390 # if (l == 1) return stmt->inouts +35391 { +35392 3d/compare-eax-and 1/imm32 +35393 75/jump-if-!= break/disp8 +35394 $get-stmt-operand-from-arg-location:1: +35395 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +35396 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +35397 } +35398 # if (l == 2) return stmt->inouts->next +35399 { +35400 3d/compare-eax-and 2/imm32 +35401 75/jump-if-!= break/disp8 +35402 $get-stmt-operand-from-arg-location:2: +35403 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +35404 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +35405 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +35406 } +35407 # if (l == 3) return stmt->outputs +35408 { +35409 3d/compare-eax-and 3/imm32 +35410 75/jump-if-!= break/disp8 +35411 $get-stmt-operand-from-arg-location:3: +35412 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +35413 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +35414 } +35415 # abort +35416 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 +35417 $get-stmt-operand-from-arg-location:end: +35418 # . restore registers +35419 59/pop-to-ecx +35420 # . epilogue +35421 89/<- %esp 5/r32/ebp +35422 5d/pop-to-ebp +35423 c3/return +35424 +35425 $get-stmt-operand-from-arg-location:abort: +35426 # error("invalid arg-location " eax) +35427 (write-buffered *(ebp+0x10) "invalid arg-location ") +35428 (write-int32-hex-buffered *(ebp+0x10) %eax) +35429 (write-buffered *(ebp+0x10) Newline) +35430 (flush *(ebp+0x10)) +35431 (stop *(ebp+0x14) 1) +35432 # never gets here +35433 +35434 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +35435 # . prologue +35436 55/push-ebp +35437 89/<- %ebp 4/r32/esp +35438 # . save registers +35439 50/push-eax +35440 51/push-ecx +35441 # if (l == 0) return +35442 81 7/subop/compare *(ebp+0xc) 0/imm32 +35443 0f 84/jump-if-= $emit-subx-r32:end/disp32 +35444 # var v/eax: (addr stmt-var) +35445 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +35446 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +35447 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +35448 #? (write-buffered Stderr "looking up ") +35449 #? (write-buffered Stderr %eax) +35450 #? (write-buffered Stderr Newline) +35451 #? (flush Stderr) +35452 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) +35453 (write-buffered *(ebp+8) Space) +35454 (write-int32-hex-buffered *(ebp+8) *eax) +35455 (write-buffered *(ebp+8) "/r32") +35456 $emit-subx-r32:end: +35457 # . restore registers +35458 59/pop-to-ecx +35459 58/pop-to-eax +35460 # . epilogue +35461 89/<- %esp 5/r32/ebp +35462 5d/pop-to-ebp +35463 c3/return +35464 +35465 emit-subx-x32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +35466 # . prologue +35467 55/push-ebp +35468 89/<- %ebp 4/r32/esp +35469 # . save registers +35470 50/push-eax +35471 51/push-ecx +35472 # if (l == 0) return +35473 81 7/subop/compare *(ebp+0xc) 0/imm32 +35474 0f 84/jump-if-= $emit-subx-x32:end/disp32 +35475 # var v/eax: (addr stmt-var) +35476 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +35477 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +35478 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +35479 #? (write-buffered Stderr "looking up ") +35480 #? (write-buffered Stderr %eax) +35481 #? (write-buffered Stderr Newline) +35482 #? (flush Stderr) +35483 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) +35484 (write-buffered *(ebp+8) Space) +35485 (write-int32-hex-buffered *(ebp+8) *eax) +35486 (write-buffered *(ebp+8) "/x32") +35487 $emit-subx-x32:end: +35488 # . restore registers +35489 59/pop-to-ecx +35490 58/pop-to-eax +35491 # . epilogue +35492 89/<- %esp 5/r32/ebp +35493 5d/pop-to-ebp +35494 c3/return +35495 +35496 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +35497 # . prologue +35498 55/push-ebp +35499 89/<- %ebp 4/r32/esp +35500 # . save registers +35501 50/push-eax +35502 51/push-ecx +35503 # if (l == 0) return +35504 81 7/subop/compare *(ebp+0xc) 0/imm32 +35505 0f 84/jump-if-= $emit-subx-imm32:end/disp32 +35506 # var v/eax: (handle var) +35507 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +35508 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +35509 (lookup *eax *(eax+4)) # Var-name Var-name => eax +35510 (write-buffered *(ebp+8) Space) +35511 (write-buffered *(ebp+8) %eax) +35512 (write-buffered *(ebp+8) "/imm32") +35513 $emit-subx-imm32:end: +35514 # . restore registers +35515 59/pop-to-ecx +35516 58/pop-to-eax +35517 # . epilogue +35518 89/<- %esp 5/r32/ebp +35519 5d/pop-to-ebp +35520 c3/return +35521 +35522 emit-subx-imm8: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +35523 # . prologue +35524 55/push-ebp +35525 89/<- %ebp 4/r32/esp +35526 # . save registers +35527 50/push-eax +35528 51/push-ecx +35529 # if (l == 0) return +35530 81 7/subop/compare *(ebp+0xc) 0/imm32 +35531 0f 84/jump-if-= $emit-subx-imm32:end/disp32 +35532 # var v/eax: (handle var) +35533 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +35534 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +35535 (lookup *eax *(eax+4)) # Var-name Var-name => eax +35536 (write-buffered *(ebp+8) Space) +35537 (write-buffered *(ebp+8) %eax) +35538 (write-buffered *(ebp+8) "/imm8") +35539 $emit-subx-imm8:end: +35540 # . restore registers +35541 59/pop-to-ecx +35542 58/pop-to-eax +35543 # . epilogue +35544 89/<- %esp 5/r32/ebp +35545 5d/pop-to-ebp +35546 c3/return +35547 +35548 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +35549 # . prologue +35550 55/push-ebp +35551 89/<- %ebp 4/r32/esp +35552 # . save registers +35553 50/push-eax +35554 51/push-ecx +35555 # if (location == 0) return +35556 81 7/subop/compare *(ebp+0xc) 0/imm32 +35557 0f 84/jump-if-= $emit-subx-disp32:end/disp32 +35558 # var v/eax: (addr stmt-var) +35559 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax +35560 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +35561 (lookup *eax *(eax+4)) # Var-name Var-name => eax +35562 (write-buffered *(ebp+8) Space) +35563 (write-buffered *(ebp+8) %eax) +35564 # hack: if instruction operation starts with "break", emit ":break" +35565 # var name/ecx: (addr array byte) = lookup(stmt->operation) +35566 8b/-> *(ebp+0x10) 0/r32/eax +35567 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +35568 89/<- %ecx 0/r32/eax +35569 { +35570 (string-starts-with? %ecx "break") # => eax +35571 3d/compare-eax-and 0/imm32/false +35572 74/jump-if-= break/disp8 +35573 (write-buffered *(ebp+8) ":break") +35574 } +35575 # hack: if instruction operation starts with "loop", emit ":loop" +35576 { +35577 (string-starts-with? %ecx "loop") # => eax +35578 3d/compare-eax-and 0/imm32/false +35579 74/jump-if-= break/disp8 +35580 (write-buffered *(ebp+8) ":loop") +35581 } +35582 (write-buffered *(ebp+8) "/disp32") +35583 $emit-subx-disp32:end: +35584 # . restore registers +35585 59/pop-to-ecx +35586 58/pop-to-eax +35587 # . epilogue +35588 89/<- %esp 5/r32/ebp +35589 5d/pop-to-ebp +35590 c3/return +35591 +35592 emit-call: # out: (addr buffered-file), stmt: (addr stmt) +35593 # . prologue +35594 55/push-ebp +35595 89/<- %ebp 4/r32/esp +35596 # . save registers +35597 50/push-eax +35598 51/push-ecx +35599 # +35600 (emit-indent *(ebp+8) *Curr-block-depth) +35601 (write-buffered *(ebp+8) "(") +35602 # ecx = stmt +35603 8b/-> *(ebp+0xc) 1/r32/ecx +35604 # - emit function name +35605 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +35606 (write-buffered *(ebp+8) %eax) +35607 # - emit arguments +35608 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) +35609 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +35610 { +35611 # if (curr == null) break +35612 3d/compare-eax-and 0/imm32 +35613 74/jump-if-= break/disp8 +35614 # +35615 (emit-subx-call-operand *(ebp+8) %eax) +35616 # curr = lookup(curr->next) +35617 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +35618 eb/jump loop/disp8 +35619 } +35620 # +35621 (write-buffered *(ebp+8) ")\n") +35622 $emit-call:end: +35623 # . restore registers +35624 59/pop-to-ecx +35625 58/pop-to-eax +35626 # . epilogue +35627 89/<- %esp 5/r32/ebp +35628 5d/pop-to-ebp +35629 c3/return +35630 +35631 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) +35632 # shares code with emit-subx-var-as-rm32 +35633 # . prologue +35634 55/push-ebp +35635 89/<- %ebp 4/r32/esp +35636 # . save registers +35637 50/push-eax +35638 51/push-ecx +35639 56/push-esi +35640 # ecx = s +35641 8b/-> *(ebp+0xc) 1/r32/ecx +35642 # var operand/esi: (addr var) = lookup(s->value) +35643 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +35644 89/<- %esi 0/r32/eax +35645 # if (operand->register && !s->is-deref?) emit "%__" +35646 { +35647 $emit-subx-call-operand:check-for-register-direct: +35648 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +35649 74/jump-if-= break/disp8 +35650 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +35651 75/jump-if-!= break/disp8 +35652 $emit-subx-call-operand:register-direct: +35653 (write-buffered *(ebp+8) " %") +35654 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +35655 (write-buffered *(ebp+8) %eax) +35656 e9/jump $emit-subx-call-operand:end/disp32 +35657 } +35658 # else if (operand->register && s->is-deref?) emit "*__" +35659 { +35660 $emit-subx-call-operand:check-for-register-indirect: +35661 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +35662 74/jump-if-= break/disp8 +35663 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +35664 74/jump-if-= break/disp8 +35665 $emit-subx-call-operand:register-indirect: +35666 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) +35667 e9/jump $emit-subx-call-operand:end/disp32 +35668 } +35669 # else if (operand->stack-offset) emit "*(ebp+__)" +35670 { +35671 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +35672 74/jump-if-= break/disp8 +35673 $emit-subx-call-operand:stack: +35674 (emit-subx-call-operand-stack *(ebp+8) %esi) +35675 e9/jump $emit-subx-call-operand:end/disp32 +35676 } +35677 # else if (operand->type == literal) emit "__" +35678 { +35679 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +35680 81 7/subop/compare *(eax+4) 0/imm32 # Type-tree-value +35681 75/jump-if-!= break/disp8 +35682 $emit-subx-call-operand:literal: +35683 (write-buffered *(ebp+8) Space) +35684 (lookup *esi *(esi+4)) # Var-name Var-name => eax +35685 (write-buffered *(ebp+8) %eax) +35686 e9/jump $emit-subx-call-operand:end/disp32 +35687 } +35688 # else if (operand->type == literal-string) emit "__" +35689 { +35690 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +35691 81 7/subop/compare *(eax+4) 0x10/imm32 # Type-tree-value +35692 75/jump-if-!= break/disp8 +35693 $emit-subx-call-operand:literal-string: +35694 (write-buffered *(ebp+8) Space) +35695 (lookup *esi *(esi+4)) # Var-name Var-name => eax +35696 (write-buffered *(ebp+8) %eax) +35697 } +35698 $emit-subx-call-operand:end: +35699 # . restore registers +35700 5e/pop-to-esi +35701 59/pop-to-ecx +35702 58/pop-to-eax +35703 # . epilogue +35704 89/<- %esp 5/r32/ebp +35705 5d/pop-to-ebp +35706 c3/return +35707 +35708 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) +35709 # . prologue +35710 55/push-ebp +35711 89/<- %ebp 4/r32/esp +35712 # . save registers +35713 50/push-eax +35714 51/push-ecx +35715 56/push-esi +35716 # esi = v +35717 8b/-> *(ebp+0xc) 6/r32/esi +35718 # var size/ecx: int = size-of-deref(v) +35719 (size-of-deref %esi) # => eax +35720 89/<- %ecx 0/r32/eax +35721 # var reg-name/esi: (addr array byte) = lookup(v->register) +35722 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +35723 89/<- %esi 0/r32/eax +35724 # TODO: assert size is a multiple of 4 +35725 # var i/eax: int = 0 +35726 b8/copy-to-eax 0/imm32 +35727 { +35728 $emit-subx-call-operand-register-indirect:loop: +35729 # if (i >= size) break +35730 39/compare %eax 1/r32/ecx +35731 7d/jump-if->= break/disp8 +35732 # emit " *(" v->register "+" i ")" +35733 (write-buffered *(ebp+8) " *(") +35734 (write-buffered *(ebp+8) %esi) +35735 (write-buffered *(ebp+8) "+") +35736 (write-int32-hex-buffered *(ebp+8) %eax) +35737 (write-buffered *(ebp+8) ")") +35738 # i += 4 +35739 05/add-to-eax 4/imm32 +35740 # +35741 eb/jump loop/disp8 +35742 } +35743 $emit-subx-call-operand-register-indirect:end: +35744 # . restore registers +35745 5e/pop-to-esi +35746 59/pop-to-ecx +35747 58/pop-to-eax +35748 # . epilogue +35749 89/<- %esp 5/r32/ebp +35750 5d/pop-to-ebp +35751 c3/return +35752 +35753 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) +35754 # . prologue +35755 55/push-ebp +35756 89/<- %ebp 4/r32/esp +35757 # . save registers +35758 50/push-eax +35759 51/push-ecx +35760 56/push-esi +35761 # esi = v +35762 8b/-> *(ebp+0xc) 6/r32/esi +35763 # var curr/ecx: int = v->offset +35764 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset +35765 # var max/eax: int = v->offset + size-of(v) +35766 (size-of %esi) # => eax +35767 # TODO: assert size is a multiple of 4 +35768 01/add-to %eax 1/r32/ecx +35769 { +35770 $emit-subx-call-operand-stack:loop: +35771 # if (curr >= max) break +35772 39/compare %ecx 0/r32/eax +35773 7d/jump-if->= break/disp8 +35774 # emit " *(ebp+" curr ")" +35775 (write-buffered *(ebp+8) " *(ebp+") +35776 (write-int32-hex-buffered *(ebp+8) %ecx) +35777 (write-buffered *(ebp+8) ")") +35778 # i += 4 +35779 81 0/subop/add %ecx 4/imm32 +35780 # +35781 eb/jump loop/disp8 +35782 } +35783 $emit-subx-call-operand-stack:end: +35784 # . restore registers +35785 5e/pop-to-esi +35786 59/pop-to-ecx +35787 58/pop-to-eax +35788 # . epilogue +35789 89/<- %esp 5/r32/ebp +35790 5d/pop-to-ebp +35791 c3/return +35792 +35793 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) +35794 # . prologue +35795 55/push-ebp +35796 89/<- %ebp 4/r32/esp +35797 # . save registers +35798 50/push-eax +35799 51/push-ecx +35800 56/push-esi +35801 # ecx = s +35802 8b/-> *(ebp+0xc) 1/r32/ecx +35803 # var operand/esi: (addr var) = lookup(s->value) +35804 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +35805 89/<- %esi 0/r32/eax +35806 # if (operand->register && s->is-deref?) emit "*__" +35807 { +35808 $emit-subx-var-as-rm32:check-for-register-indirect: +35809 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +35810 74/jump-if-= break/disp8 +35811 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +35812 74/jump-if-= break/disp8 +35813 $emit-subx-var-as-rm32:register-indirect: +35814 (write-buffered *(ebp+8) " *") +35815 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +35816 (write-buffered *(ebp+8) %eax) +35817 e9/jump $emit-subx-var-as-rm32:end/disp32 +35818 } +35819 # if (operand->register && !s->is-deref?) emit "%__" +35820 { +35821 $emit-subx-var-as-rm32:check-for-register-direct: +35822 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +35823 74/jump-if-= break/disp8 +35824 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +35825 75/jump-if-!= break/disp8 +35826 $emit-subx-var-as-rm32:register-direct: +35827 (write-buffered *(ebp+8) " %") +35828 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +35829 (write-buffered *(ebp+8) %eax) +35830 e9/jump $emit-subx-var-as-rm32:end/disp32 35831 } -35832 # return null -35833 b8/copy-to-eax 0/imm32 -35834 $find-matching-primitive:end: -35835 # . restore registers -35836 59/pop-to-ecx -35837 # . epilogue -35838 89/<- %esp 5/r32/ebp -35839 5d/pop-to-ebp -35840 c3/return -35841 -35842 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean -35843 # A mu stmt matches a primitive if the name matches, all the inout vars -35844 # match, and all the output vars match. -35845 # Vars match if types match and registers match. -35846 # In addition, a stmt output matches a primitive's output if types match -35847 # and the primitive has a wildcard register. -35848 # . prologue -35849 55/push-ebp -35850 89/<- %ebp 4/r32/esp -35851 # . save registers -35852 51/push-ecx -35853 52/push-edx -35854 53/push-ebx -35855 56/push-esi -35856 57/push-edi -35857 # ecx = stmt -35858 8b/-> *(ebp+8) 1/r32/ecx -35859 # edx = primitive -35860 8b/-> *(ebp+0xc) 2/r32/edx -35861 { -35862 $mu-stmt-matches-primitive?:check-name: -35863 # if (primitive->name != stmt->operation) return false -35864 # . var esi: (addr array byte) = lookup(stmt->operation) -35865 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -35866 89/<- %esi 0/r32/eax -35867 # . var edi: (addr array byte) = lookup(primitive->name) -35868 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax -35869 #? (write-buffered Stderr %eax) -35870 #? (write-buffered Stderr Newline) -35871 #? (flush Stderr) -35872 89/<- %edi 0/r32/eax -35873 (string-equal? %esi %edi) # => eax -35874 3d/compare-eax-and 0/imm32/false -35875 75/jump-if-!= break/disp8 -35876 b8/copy-to-eax 0/imm32 -35877 e9/jump $mu-stmt-matches-primitive?:end/disp32 -35878 } -35879 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) -35880 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -35881 89/<- %esi 0/r32/eax -35882 # var curr2/edi: (addr list var) = lookup(primitive->inouts) -35883 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax -35884 89/<- %edi 0/r32/eax -35885 { -35886 $mu-stmt-matches-primitive?:inouts-loop: -35887 # if (curr == 0 && curr2 == 0) move on to check outputs -35888 { -35889 $mu-stmt-matches-primitive?:check-both-inouts-null: -35890 81 7/subop/compare %esi 0/imm32 -35891 75/jump-if-!= break/disp8 -35892 $mu-stmt-matches-primitive?:stmt-inout-null: -35893 81 7/subop/compare %edi 0/imm32 -35894 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 -35895 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: -35896 # return false -35897 b8/copy-to-eax 0/imm32/false -35898 e9/jump $mu-stmt-matches-primitive?:end/disp32 -35899 } -35900 # if (curr2 == 0) return false -35901 { -35902 $mu-stmt-matches-primitive?:check-prim-inout-null: -35903 81 7/subop/compare %edi 0/imm32 -35904 75/jump-if-!= break/disp8 -35905 $mu-stmt-matches-primitive?:prim-inout-null: -35906 b8/copy-to-eax 0/imm32/false -35907 e9/jump $mu-stmt-matches-primitive?:end/disp32 -35908 } -35909 # if (curr != curr2) return false -35910 { -35911 $mu-stmt-matches-primitive?:check-inouts-match: -35912 (lookup *edi *(edi+4)) # List-value List-value => eax -35913 (operand-matches-primitive? %esi %eax) # => eax -35914 3d/compare-eax-and 0/imm32/false -35915 75/jump-if-!= break/disp8 -35916 $mu-stmt-matches-primitive?:inouts-match: -35917 b8/copy-to-eax 0/imm32/false -35918 e9/jump $mu-stmt-matches-primitive?:end/disp32 -35919 } -35920 $mu-stmt-matches-primitive?:next-inout: -35921 # curr = lookup(curr->next) -35922 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -35923 89/<- %esi 0/r32/eax -35924 # curr2 = lookup(curr2->next) -35925 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -35926 89/<- %edi 0/r32/eax -35927 # -35928 e9/jump loop/disp32 -35929 } -35930 $mu-stmt-matches-primitive?:check-outputs: -35931 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) -35932 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -35933 89/<- %esi 0/r32/eax -35934 # var curr2/edi: (addr list var) = lookup(primitive->outputs) -35935 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax -35936 89/<- %edi 0/r32/eax -35937 { -35938 $mu-stmt-matches-primitive?:outputs-loop: -35939 # if (curr == 0) return (curr2 == 0) -35940 { -35941 $mu-stmt-matches-primitive?:check-both-outputs-null: -35942 81 7/subop/compare %esi 0/imm32 -35943 75/jump-if-!= break/disp8 -35944 { -35945 $mu-stmt-matches-primitive?:stmt-output-null: -35946 81 7/subop/compare %edi 0/imm32 -35947 75/jump-if-!= break/disp8 -35948 $mu-stmt-matches-primitive?:both-outputs-null: -35949 # return true -35950 b8/copy-to-eax 1/imm32 -35951 e9/jump $mu-stmt-matches-primitive?:end/disp32 -35952 } -35953 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: -35954 # return false -35955 b8/copy-to-eax 0/imm32 -35956 e9/jump $mu-stmt-matches-primitive?:end/disp32 -35957 } -35958 # if (curr2 == 0) return false -35959 { -35960 $mu-stmt-matches-primitive?:check-prim-output-null: -35961 81 7/subop/compare %edi 0/imm32 -35962 75/jump-if-!= break/disp8 -35963 $mu-stmt-matches-primitive?:prim-output-is-null: -35964 b8/copy-to-eax 0/imm32 -35965 e9/jump $mu-stmt-matches-primitive?:end/disp32 -35966 } -35967 # if (curr != curr2) return false -35968 { -35969 $mu-stmt-matches-primitive?:check-outputs-match: -35970 (lookup *edi *(edi+4)) # List-value List-value => eax -35971 (operand-matches-primitive? %esi %eax) # => eax -35972 3d/compare-eax-and 0/imm32/false -35973 75/jump-if-!= break/disp8 -35974 $mu-stmt-matches-primitive?:outputs-match: -35975 b8/copy-to-eax 0/imm32 -35976 e9/jump $mu-stmt-matches-primitive?:end/disp32 -35977 } -35978 $mu-stmt-matches-primitive?:next-output: -35979 # curr = lookup(curr->next) -35980 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -35981 89/<- %esi 0/r32/eax -35982 # curr2 = lookup(curr2->next) -35983 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -35984 89/<- %edi 0/r32/eax -35985 # -35986 e9/jump loop/disp32 -35987 } -35988 $mu-stmt-matches-primitive?:return-true: -35989 b8/copy-to-eax 1/imm32 -35990 $mu-stmt-matches-primitive?:end: -35991 # . restore registers -35992 5f/pop-to-edi -35993 5e/pop-to-esi -35994 5b/pop-to-ebx -35995 5a/pop-to-edx -35996 59/pop-to-ecx -35997 # . epilogue -35998 89/<- %esp 5/r32/ebp -35999 5d/pop-to-ebp -36000 c3/return -36001 -36002 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean -36003 # . prologue -36004 55/push-ebp -36005 89/<- %ebp 4/r32/esp -36006 # . save registers -36007 51/push-ecx -36008 52/push-edx -36009 53/push-ebx -36010 56/push-esi -36011 57/push-edi -36012 # ecx = s -36013 8b/-> *(ebp+8) 1/r32/ecx -36014 # var var/esi: (addr var) = lookup(s->value) -36015 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -36016 89/<- %esi 0/r32/eax -36017 # edi = prim-var -36018 8b/-> *(ebp+0xc) 7/r32/edi -36019 $operand-matches-primitive?:check-type: -36020 # if !category-match?(var->type, prim-var->type) return false -36021 # . var vtype/ebx: (addr type-tree) = lookup(var->type) -36022 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -36023 89/<- %ebx 0/r32/eax -36024 # . if s is deref, vtype = vtype->right -36025 { -36026 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -36027 74/jump-if-= break/disp8 -36028 $operand-matches-primitive?:is-deref: -36029 # . var t/eax: (addr type) -36030 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -36031 # . if !t->is-atom? t = t->left -36032 81 7/subop/compare *eax 0/imm32/false -36033 { -36034 75/jump-if-!= break/disp8 -36035 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -36036 } -36037 # . -36038 89/<- %ebx 0/r32/eax -36039 } -36040 # . var ptype/eax: (addr type-tree) = lookup(prim-var->type) -36041 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -36042 (subx-type-category-match? %ebx %eax) # => eax -36043 3d/compare-eax-and 0/imm32/false -36044 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 -36045 { -36046 $operand-matches-primitive?:check-register: -36047 # if prim-var is in memory and var is in register but dereference, match -36048 { -36049 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -36050 0f 85/jump-if-!= break/disp32 -36051 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -36052 74/jump-if-= break/disp8 -36053 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -36054 74/jump-if-= break/disp8 -36055 $operand-matches-primitive?:var-deref-match: -36056 e9/jump $operand-matches-primitive?:return-true/disp32 -36057 } -36058 # if prim-var is in register and var is in register but dereference, no match -36059 { -36060 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -36061 0f 84/jump-if-= break/disp32 -36062 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -36063 0f 84/jump-if-= break/disp32 -36064 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -36065 74/jump-if-= break/disp8 -36066 $operand-matches-primitive?:var-deref-no-match: -36067 e9/jump $operand-matches-primitive?:return-false/disp32 -36068 } -36069 # return false if var->register doesn't match prim-var->register -36070 { -36071 # if register addresses are equal, it's a match -36072 # var vreg/ebx: (addr array byte) = lookup(var->register) -36073 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -36074 89/<- %ebx 0/r32/eax -36075 # var preg/ecx: (addr array byte) = lookup(prim-var->register) -36076 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -36077 89/<- %ecx 0/r32/eax -36078 # if (vreg == preg) break -36079 39/compare %ecx 3/r32/ebx -36080 74/jump-if-= break/disp8 -36081 $operand-matches-primitive?:var-register-no-match: -36082 # if either address is 0, return false -36083 81 7/subop/compare %ebx 0/imm32 -36084 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -36085 81 7/subop/compare %ecx 0/imm32 -36086 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -36087 # if prim-var->register is wildcard, it's a match -36088 (string-equal? %ecx "*") # Any-register => eax -36089 3d/compare-eax-and 0/imm32/false -36090 75/jump-if-!= break/disp8 -36091 $operand-matches-primitive?:wildcard-no-match: -36092 # if string contents aren't equal, return false -36093 (string-equal? %ecx %ebx) # => eax -36094 3d/compare-eax-and 0/imm32/false -36095 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -36096 } -36097 } -36098 $operand-matches-primitive?:return-true: -36099 b8/copy-to-eax 1/imm32/true -36100 eb/jump $operand-matches-primitive?:end/disp8 -36101 $operand-matches-primitive?:return-false: -36102 b8/copy-to-eax 0/imm32/false -36103 $operand-matches-primitive?:end: -36104 # . restore registers -36105 5f/pop-to-edi -36106 5e/pop-to-esi -36107 5b/pop-to-ebx -36108 5a/pop-to-edx -36109 59/pop-to-ecx -36110 # . epilogue -36111 89/<- %esp 5/r32/ebp -36112 5d/pop-to-ebp -36113 c3/return -36114 -36115 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function) -36116 # . prologue -36117 55/push-ebp -36118 89/<- %ebp 4/r32/esp -36119 # . save registers -36120 51/push-ecx -36121 # var curr/ecx: (handle function) = functions -36122 8b/-> *(ebp+8) 1/r32/ecx -36123 { -36124 # if (curr == null) break -36125 81 7/subop/compare %ecx 0/imm32 -36126 74/jump-if-= break/disp8 -36127 #? (write-buffered Stderr "iter\n") -36128 #? (flush Stderr) -36129 # if match(stmt, curr) return curr -36130 { -36131 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax -36132 3d/compare-eax-and 0/imm32/false -36133 74/jump-if-= break/disp8 -36134 89/<- %eax 1/r32/ecx -36135 eb/jump $find-matching-function:end/disp8 -36136 } -36137 # curr = curr->next -36138 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax -36139 89/<- %ecx 0/r32/eax -36140 # -36141 eb/jump loop/disp8 -36142 } -36143 # return null -36144 b8/copy-to-eax 0/imm32 -36145 $find-matching-function:end: -36146 # . restore registers -36147 59/pop-to-ecx -36148 # . epilogue -36149 89/<- %esp 5/r32/ebp -36150 5d/pop-to-ebp -36151 c3/return -36152 -36153 # Just compare names; user-defined functions don't support overloading yet. -36154 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean -36155 # . prologue -36156 55/push-ebp -36157 89/<- %ebp 4/r32/esp -36158 # . save registers -36159 51/push-ecx -36160 # return function->name == stmt->operation -36161 # ecx = lookup(stmt->operation) -36162 8b/-> *(ebp+8) 0/r32/eax -36163 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -36164 89/<- %ecx 0/r32/eax -36165 # eax = lookup(function->name) -36166 8b/-> *(ebp+0xc) 0/r32/eax -36167 (lookup *eax *(eax+4)) # Function-name Function-name => eax -36168 (string-equal? %eax %ecx) # => eax -36169 $mu-stmt-matches-function?:end: -36170 # . restore registers -36171 59/pop-to-ecx -36172 # . epilogue -36173 89/<- %esp 5/r32/ebp -36174 5d/pop-to-ebp -36175 c3/return -36176 -36177 # Type-checking happens elsewhere. This method is for selecting between -36178 # primitives. -36179 subx-type-category-match?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean -36180 # . prologue -36181 55/push-ebp -36182 89/<- %ebp 4/r32/esp -36183 # . save registers -36184 51/push-ecx -36185 # var cata/ecx: int = type-category(a) -36186 (type-category *(ebp+8)) # => eax -36187 89/<- %ecx 0/r32/eax -36188 # var catb/eax: int = type-category(b) -36189 (type-category *(ebp+0xc)) # => eax -36190 # return cata == catb -36191 39/compare %eax 1/r32/ecx -36192 0f 94/set-byte-if-= %al -36193 25/and-eax-with 0xff/imm32 -36194 $subx-type-category-match?:end: -36195 # . restore registers -36196 59/pop-to-ecx -36197 # . epilogue -36198 89/<- %esp 5/r32/ebp -36199 5d/pop-to-ebp -36200 c3/return -36201 -36202 type-category: # a: (addr type-tree) -> result/eax: int +35832 # else if (operand->stack-offset) emit "*(ebp+__)" +35833 { +35834 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +35835 74/jump-if-= break/disp8 +35836 $emit-subx-var-as-rm32:stack: +35837 (write-buffered *(ebp+8) Space) +35838 (write-buffered *(ebp+8) "*(ebp+") +35839 (write-int32-hex-buffered *(ebp+8) *(esi+0x14)) # Var-offset +35840 (write-buffered *(ebp+8) ")") +35841 } +35842 $emit-subx-var-as-rm32:end: +35843 # . restore registers +35844 5e/pop-to-esi +35845 59/pop-to-ecx +35846 58/pop-to-eax +35847 # . epilogue +35848 89/<- %esp 5/r32/ebp +35849 5d/pop-to-ebp +35850 c3/return +35851 +35852 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) +35853 # . prologue +35854 55/push-ebp +35855 89/<- %ebp 4/r32/esp +35856 # . save registers +35857 51/push-ecx +35858 # var curr/ecx: (addr primitive) = primitives +35859 8b/-> *(ebp+8) 1/r32/ecx +35860 { +35861 $find-matching-primitive:loop: +35862 # if (curr == null) break +35863 81 7/subop/compare %ecx 0/imm32 +35864 74/jump-if-= break/disp8 +35865 # if match(curr, stmt) return curr +35866 { +35867 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax +35868 3d/compare-eax-and 0/imm32/false +35869 74/jump-if-= break/disp8 +35870 89/<- %eax 1/r32/ecx +35871 eb/jump $find-matching-primitive:end/disp8 +35872 } +35873 $find-matching-primitive:next-primitive: +35874 # curr = curr->next +35875 (lookup *(ecx+0x3c) *(ecx+0x40)) # Primitive-next Primitive-next => eax +35876 89/<- %ecx 0/r32/eax +35877 # +35878 e9/jump loop/disp32 +35879 } +35880 # return null +35881 b8/copy-to-eax 0/imm32 +35882 $find-matching-primitive:end: +35883 # . restore registers +35884 59/pop-to-ecx +35885 # . epilogue +35886 89/<- %esp 5/r32/ebp +35887 5d/pop-to-ebp +35888 c3/return +35889 +35890 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean +35891 # A mu stmt matches a primitive if the name matches, all the inout vars +35892 # match, and all the output vars match. +35893 # Vars match if types match and registers match. +35894 # In addition, a stmt output matches a primitive's output if types match +35895 # and the primitive has a wildcard register. +35896 # . prologue +35897 55/push-ebp +35898 89/<- %ebp 4/r32/esp +35899 # . save registers +35900 51/push-ecx +35901 52/push-edx +35902 53/push-ebx +35903 56/push-esi +35904 57/push-edi +35905 # ecx = stmt +35906 8b/-> *(ebp+8) 1/r32/ecx +35907 # edx = primitive +35908 8b/-> *(ebp+0xc) 2/r32/edx +35909 { +35910 $mu-stmt-matches-primitive?:check-name: +35911 # if (primitive->name != stmt->operation) return false +35912 # . var esi: (addr array byte) = lookup(stmt->operation) +35913 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +35914 89/<- %esi 0/r32/eax +35915 # . var edi: (addr array byte) = lookup(primitive->name) +35916 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax +35917 #? (write-buffered Stderr %eax) +35918 #? (write-buffered Stderr Newline) +35919 #? (flush Stderr) +35920 89/<- %edi 0/r32/eax +35921 (string-equal? %esi %edi) # => eax +35922 3d/compare-eax-and 0/imm32/false +35923 75/jump-if-!= break/disp8 +35924 b8/copy-to-eax 0/imm32 +35925 e9/jump $mu-stmt-matches-primitive?:end/disp32 +35926 } +35927 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) +35928 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +35929 89/<- %esi 0/r32/eax +35930 # var curr2/edi: (addr list var) = lookup(primitive->inouts) +35931 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax +35932 89/<- %edi 0/r32/eax +35933 { +35934 $mu-stmt-matches-primitive?:inouts-loop: +35935 # if (curr == 0 && curr2 == 0) move on to check outputs +35936 { +35937 $mu-stmt-matches-primitive?:check-both-inouts-null: +35938 81 7/subop/compare %esi 0/imm32 +35939 75/jump-if-!= break/disp8 +35940 $mu-stmt-matches-primitive?:stmt-inout-null: +35941 81 7/subop/compare %edi 0/imm32 +35942 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 +35943 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: +35944 # return false +35945 b8/copy-to-eax 0/imm32/false +35946 e9/jump $mu-stmt-matches-primitive?:end/disp32 +35947 } +35948 # if (curr2 == 0) return false +35949 { +35950 $mu-stmt-matches-primitive?:check-prim-inout-null: +35951 81 7/subop/compare %edi 0/imm32 +35952 75/jump-if-!= break/disp8 +35953 $mu-stmt-matches-primitive?:prim-inout-null: +35954 b8/copy-to-eax 0/imm32/false +35955 e9/jump $mu-stmt-matches-primitive?:end/disp32 +35956 } +35957 # if (curr != curr2) return false +35958 { +35959 $mu-stmt-matches-primitive?:check-inouts-match: +35960 (lookup *edi *(edi+4)) # List-value List-value => eax +35961 (operand-matches-primitive? %esi %eax) # => eax +35962 3d/compare-eax-and 0/imm32/false +35963 75/jump-if-!= break/disp8 +35964 $mu-stmt-matches-primitive?:inouts-match: +35965 b8/copy-to-eax 0/imm32/false +35966 e9/jump $mu-stmt-matches-primitive?:end/disp32 +35967 } +35968 $mu-stmt-matches-primitive?:next-inout: +35969 # curr = lookup(curr->next) +35970 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +35971 89/<- %esi 0/r32/eax +35972 # curr2 = lookup(curr2->next) +35973 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +35974 89/<- %edi 0/r32/eax +35975 # +35976 e9/jump loop/disp32 +35977 } +35978 $mu-stmt-matches-primitive?:check-outputs: +35979 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) +35980 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +35981 89/<- %esi 0/r32/eax +35982 # var curr2/edi: (addr list var) = lookup(primitive->outputs) +35983 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax +35984 89/<- %edi 0/r32/eax +35985 { +35986 $mu-stmt-matches-primitive?:outputs-loop: +35987 # if (curr == 0) return (curr2 == 0) +35988 { +35989 $mu-stmt-matches-primitive?:check-both-outputs-null: +35990 81 7/subop/compare %esi 0/imm32 +35991 75/jump-if-!= break/disp8 +35992 { +35993 $mu-stmt-matches-primitive?:stmt-output-null: +35994 81 7/subop/compare %edi 0/imm32 +35995 75/jump-if-!= break/disp8 +35996 $mu-stmt-matches-primitive?:both-outputs-null: +35997 # return true +35998 b8/copy-to-eax 1/imm32 +35999 e9/jump $mu-stmt-matches-primitive?:end/disp32 +36000 } +36001 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: +36002 # return false +36003 b8/copy-to-eax 0/imm32 +36004 e9/jump $mu-stmt-matches-primitive?:end/disp32 +36005 } +36006 # if (curr2 == 0) return false +36007 { +36008 $mu-stmt-matches-primitive?:check-prim-output-null: +36009 81 7/subop/compare %edi 0/imm32 +36010 75/jump-if-!= break/disp8 +36011 $mu-stmt-matches-primitive?:prim-output-is-null: +36012 b8/copy-to-eax 0/imm32 +36013 e9/jump $mu-stmt-matches-primitive?:end/disp32 +36014 } +36015 # if (curr != curr2) return false +36016 { +36017 $mu-stmt-matches-primitive?:check-outputs-match: +36018 (lookup *edi *(edi+4)) # List-value List-value => eax +36019 (operand-matches-primitive? %esi %eax) # => eax +36020 3d/compare-eax-and 0/imm32/false +36021 75/jump-if-!= break/disp8 +36022 $mu-stmt-matches-primitive?:outputs-match: +36023 b8/copy-to-eax 0/imm32 +36024 e9/jump $mu-stmt-matches-primitive?:end/disp32 +36025 } +36026 $mu-stmt-matches-primitive?:next-output: +36027 # curr = lookup(curr->next) +36028 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +36029 89/<- %esi 0/r32/eax +36030 # curr2 = lookup(curr2->next) +36031 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +36032 89/<- %edi 0/r32/eax +36033 # +36034 e9/jump loop/disp32 +36035 } +36036 $mu-stmt-matches-primitive?:return-true: +36037 b8/copy-to-eax 1/imm32 +36038 $mu-stmt-matches-primitive?:end: +36039 # . restore registers +36040 5f/pop-to-edi +36041 5e/pop-to-esi +36042 5b/pop-to-ebx +36043 5a/pop-to-edx +36044 59/pop-to-ecx +36045 # . epilogue +36046 89/<- %esp 5/r32/ebp +36047 5d/pop-to-ebp +36048 c3/return +36049 +36050 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean +36051 # . prologue +36052 55/push-ebp +36053 89/<- %ebp 4/r32/esp +36054 # . save registers +36055 51/push-ecx +36056 52/push-edx +36057 53/push-ebx +36058 56/push-esi +36059 57/push-edi +36060 # ecx = s +36061 8b/-> *(ebp+8) 1/r32/ecx +36062 # var var/esi: (addr var) = lookup(s->value) +36063 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +36064 89/<- %esi 0/r32/eax +36065 # edi = prim-var +36066 8b/-> *(ebp+0xc) 7/r32/edi +36067 $operand-matches-primitive?:check-type: +36068 # if !category-match?(var->type, prim-var->type) return false +36069 # . var vtype/ebx: (addr type-tree) = lookup(var->type) +36070 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +36071 89/<- %ebx 0/r32/eax +36072 # . if s is deref, vtype = vtype->right +36073 { +36074 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +36075 74/jump-if-= break/disp8 +36076 $operand-matches-primitive?:is-deref: +36077 # . var t/eax: (addr type) +36078 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +36079 # . if !t->is-atom? t = t->left +36080 81 7/subop/compare *eax 0/imm32/false +36081 { +36082 75/jump-if-!= break/disp8 +36083 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +36084 } +36085 # . +36086 89/<- %ebx 0/r32/eax +36087 } +36088 # . var ptype/eax: (addr type-tree) = lookup(prim-var->type) +36089 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +36090 (subx-type-category-match? %ebx %eax) # => eax +36091 3d/compare-eax-and 0/imm32/false +36092 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 +36093 { +36094 $operand-matches-primitive?:check-register: +36095 # if prim-var is in memory and var is in register but dereference, match +36096 { +36097 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +36098 0f 85/jump-if-!= break/disp32 +36099 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +36100 74/jump-if-= break/disp8 +36101 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +36102 74/jump-if-= break/disp8 +36103 $operand-matches-primitive?:var-deref-match: +36104 e9/jump $operand-matches-primitive?:return-true/disp32 +36105 } +36106 # if prim-var is in register and var is in register but dereference, no match +36107 { +36108 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +36109 0f 84/jump-if-= break/disp32 +36110 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +36111 0f 84/jump-if-= break/disp32 +36112 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +36113 74/jump-if-= break/disp8 +36114 $operand-matches-primitive?:var-deref-no-match: +36115 e9/jump $operand-matches-primitive?:return-false/disp32 +36116 } +36117 # return false if var->register doesn't match prim-var->register +36118 { +36119 # if register addresses are equal, it's a match +36120 # var vreg/ebx: (addr array byte) = lookup(var->register) +36121 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +36122 89/<- %ebx 0/r32/eax +36123 # var preg/ecx: (addr array byte) = lookup(prim-var->register) +36124 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +36125 89/<- %ecx 0/r32/eax +36126 # if (vreg == preg) break +36127 39/compare %ecx 3/r32/ebx +36128 74/jump-if-= break/disp8 +36129 $operand-matches-primitive?:var-register-no-match: +36130 # if either address is 0, return false +36131 81 7/subop/compare %ebx 0/imm32 +36132 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +36133 81 7/subop/compare %ecx 0/imm32 +36134 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +36135 # if prim-var->register is wildcard, it's a match +36136 (string-equal? %ecx "*") # Any-register => eax +36137 3d/compare-eax-and 0/imm32/false +36138 75/jump-if-!= break/disp8 +36139 $operand-matches-primitive?:wildcard-no-match: +36140 # if string contents aren't equal, return false +36141 (string-equal? %ecx %ebx) # => eax +36142 3d/compare-eax-and 0/imm32/false +36143 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +36144 } +36145 } +36146 $operand-matches-primitive?:return-true: +36147 b8/copy-to-eax 1/imm32/true +36148 eb/jump $operand-matches-primitive?:end/disp8 +36149 $operand-matches-primitive?:return-false: +36150 b8/copy-to-eax 0/imm32/false +36151 $operand-matches-primitive?:end: +36152 # . restore registers +36153 5f/pop-to-edi +36154 5e/pop-to-esi +36155 5b/pop-to-ebx +36156 5a/pop-to-edx +36157 59/pop-to-ecx +36158 # . epilogue +36159 89/<- %esp 5/r32/ebp +36160 5d/pop-to-ebp +36161 c3/return +36162 +36163 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function) +36164 # . prologue +36165 55/push-ebp +36166 89/<- %ebp 4/r32/esp +36167 # . save registers +36168 51/push-ecx +36169 # var curr/ecx: (handle function) = functions +36170 8b/-> *(ebp+8) 1/r32/ecx +36171 { +36172 # if (curr == null) break +36173 81 7/subop/compare %ecx 0/imm32 +36174 74/jump-if-= break/disp8 +36175 #? (write-buffered Stderr "iter\n") +36176 #? (flush Stderr) +36177 # if match(stmt, curr) return curr +36178 { +36179 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax +36180 3d/compare-eax-and 0/imm32/false +36181 74/jump-if-= break/disp8 +36182 89/<- %eax 1/r32/ecx +36183 eb/jump $find-matching-function:end/disp8 +36184 } +36185 # curr = curr->next +36186 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax +36187 89/<- %ecx 0/r32/eax +36188 # +36189 eb/jump loop/disp8 +36190 } +36191 # return null +36192 b8/copy-to-eax 0/imm32 +36193 $find-matching-function:end: +36194 # . restore registers +36195 59/pop-to-ecx +36196 # . epilogue +36197 89/<- %esp 5/r32/ebp +36198 5d/pop-to-ebp +36199 c3/return +36200 +36201 # Just compare names; user-defined functions don't support overloading yet. +36202 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean 36203 # . prologue 36204 55/push-ebp 36205 89/<- %ebp 4/r32/esp 36206 # . save registers 36207 51/push-ecx -36208 # var lit?/ecx: boolean = literal-type?(a) -36209 (simple-mu-type? *(ebp+8) 0) # literal => eax -36210 89/<- %ecx 0/r32/eax -36211 # var float?/eax: int = float?(a) -36212 (simple-mu-type? *(ebp+8) 0xf) # => eax -36213 # set bits for lit? and float? -36214 c1/shift 4/subop/left %ecx 1/imm8 -36215 09/or %eax 1/r32/ecx -36216 $type-category:end: -36217 # . restore registers -36218 59/pop-to-ecx -36219 # . epilogue -36220 89/<- %esp 5/r32/ebp -36221 5d/pop-to-ebp -36222 c3/return -36223 -36224 simple-mu-type?: # a: (addr type-tree), n: type-id -> result/eax: boolean -36225 # . prologue -36226 55/push-ebp -36227 89/<- %ebp 4/r32/esp -36228 # . save registers -36229 51/push-ecx -36230 # ecx = n -36231 8b/-> *(ebp+0xc) 1/r32/ecx -36232 # return (a->value == n) -36233 8b/-> *(ebp+8) 0/r32/eax -36234 39/compare *(eax+4) 1/r32/ecx # Type-tree-value -36235 0f 94/set-byte-if-= %al -36236 25/and-eax-with 0xff/imm32 -36237 $simple-mu-type?:end: -36238 # . restore registers -36239 59/pop-to-ecx -36240 # . epilogue -36241 89/<- %esp 5/r32/ebp -36242 5d/pop-to-ebp -36243 c3/return -36244 -36245 mu-addr-type?: # a: (addr type-tree) -> result/eax: boolean -36246 # . prologue -36247 55/push-ebp -36248 89/<- %ebp 4/r32/esp -36249 # eax = a -36250 8b/-> *(ebp+8) 0/r32/eax -36251 # if (!a->is-atom?) a = a->left -36252 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -36253 { -36254 75/jump-if-!= break/disp8 -36255 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -36256 } -36257 # return (a->value == addr) -36258 81 7/subop/compare *(eax+4) 2/imm32/addr # Type-tree-value -36259 0f 94/set-byte-if-= %al -36260 25/and-eax-with 0xff/imm32 -36261 $mu-addr-type?:end: -36262 # . epilogue -36263 89/<- %esp 5/r32/ebp -36264 5d/pop-to-ebp -36265 c3/return -36266 -36267 mu-array-type?: # a: (addr type-tree) -> result/eax: boolean -36268 # . prologue -36269 55/push-ebp -36270 89/<- %ebp 4/r32/esp -36271 # eax = a -36272 8b/-> *(ebp+8) 0/r32/eax -36273 # if (!a->is-atom?) a = a->left -36274 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -36275 { -36276 75/jump-if-!= break/disp8 -36277 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -36278 } -36279 # return (a->value == array) -36280 81 7/subop/compare *(eax+4) 3/imm32/array # Type-tree-value -36281 0f 94/set-byte-if-= %al -36282 25/and-eax-with 0xff/imm32 -36283 $mu-array-type?:end: -36284 # . epilogue -36285 89/<- %esp 5/r32/ebp -36286 5d/pop-to-ebp -36287 c3/return -36288 -36289 mu-string-type?: # a: (addr type-tree) -> result/eax: boolean -36290 # . prologue -36291 55/push-ebp -36292 89/<- %ebp 4/r32/esp -36293 # . save registers -36294 56/push-esi -36295 # esi = a -36296 8b/-> *(ebp+8) 6/r32/esi -36297 # if (a->is-atom?) return false -36298 81 7/subop/compare *esi 0/imm32/false # Type-tree-is-atom -36299 0f 85/jump-if-!= $mu-string-type?:return-false/disp32 -36300 # if a is not an addr, return false -36301 (mu-addr-type? %esi) # => eax -36302 3d/compare-eax-with 0/imm32/false -36303 0f 84/jump-if-= $mu-string-type?:end/disp32 # eax changes var -36304 # if a is not an array, return false -36305 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax -36306 (mu-array-type? %eax) # => eax -36307 3d/compare-eax-with 0/imm32/false -36308 74/jump-if-= $mu-string-type?:end/disp8 # eax changes var -36309 # var p/eax: (addr type-tree) = payload of a -36310 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax -36311 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -36312 # if p is an atom, return false -36313 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -36314 75/jump-if-!= $mu-string-type?:return-false/disp8 -36315 # return (p == byte) -36316 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -36317 (simple-mu-type? %eax 8) # byte => eax -36318 eb/jump $mu-string-type?:end/disp8 -36319 $mu-string-type?:return-false: -36320 b8/copy-to-eax 0/imm32/false -36321 $mu-string-type?:end: -36322 # . restore registers -36323 5e/pop-to-esi -36324 # . epilogue -36325 89/<- %esp 5/r32/ebp -36326 5d/pop-to-ebp -36327 c3/return -36328 -36329 mu-stream-type?: # a: (addr type-tree) -> result/eax: boolean -36330 # . prologue -36331 55/push-ebp -36332 89/<- %ebp 4/r32/esp -36333 # eax = a -36334 8b/-> *(ebp+8) 0/r32/eax -36335 # if (!a->is-atom?) a = a->left -36336 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -36337 { -36338 75/jump-if-!= break/disp8 -36339 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -36340 } -36341 # return (a->value == stream) -36342 81 7/subop/compare *(eax+4) 0xb/imm32/stream # Type-tree-value -36343 0f 94/set-byte-if-= %al -36344 25/and-eax-with 0xff/imm32 -36345 $mu-stream-type?:end: -36346 # . epilogue -36347 89/<- %esp 5/r32/ebp -36348 5d/pop-to-ebp -36349 c3/return -36350 -36351 test-emit-subx-stmt-primitive: -36352 # Primitive operation on a variable on the stack. -36353 # increment foo -36354 # => -36355 # ff 0/subop/increment *(ebp-8) -36356 # -36357 # There's a variable on the var stack as follows: -36358 # name: 'foo' -36359 # type: int -36360 # stack-offset: -8 -36361 # -36362 # There's a primitive with this info: -36363 # name: 'increment' -36364 # inouts: int/mem -36365 # value: 'ff 0/subop/increment' -36366 # -36367 # . prologue -36368 55/push-ebp -36369 89/<- %ebp 4/r32/esp -36370 # setup -36371 (clear-stream _test-output-stream) -36372 (clear-stream $_test-output-buffered-file->buffer) -36373 # simulate allocated payloads starting with an initial fake alloc-id (0x11) -36374 $test-emit-subx-stmt-primitive:initialize-type: -36375 # var type/ecx: (payload type-tree) = int -36376 68/push 0/imm32/right:null -36377 68/push 0/imm32/right:null -36378 68/push 0/imm32/left:unused -36379 68/push 1/imm32/value:int -36380 68/push 1/imm32/is-atom?:true -36381 68/push 0x11/imm32/alloc-id:fake:payload -36382 89/<- %ecx 4/r32/esp -36383 $test-emit-subx-stmt-primitive:initialize-var: -36384 # var var-foo/ecx: (payload var) = var(type) -36385 68/push 0/imm32/no-register -36386 68/push 0/imm32/no-register -36387 68/push -8/imm32/stack-offset -36388 68/push 1/imm32/block-depth -36389 51/push-ecx/type -36390 68/push 0x11/imm32/alloc-id:fake -36391 68/push 0/imm32/name -36392 68/push 0/imm32/name -36393 68/push 0x11/imm32/alloc-id:fake:payload -36394 89/<- %ecx 4/r32/esp -36395 $test-emit-subx-stmt-primitive:initialize-var-name: -36396 # var-foo->name = "foo" -36397 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -36398 (copy-array Heap "foo" %eax) -36399 $test-emit-subx-stmt-primitive:initialize-stmt-var: -36400 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -36401 68/push 0/imm32/is-deref:false -36402 68/push 0/imm32/next -36403 68/push 0/imm32/next -36404 51/push-ecx/var-foo -36405 68/push 0x11/imm32/alloc-id:fake -36406 68/push 0x11/imm32/alloc-id:fake:payload -36407 89/<- %ebx 4/r32/esp -36408 $test-emit-subx-stmt-primitive:initialize-stmt: -36409 # var stmt/esi: (addr statement) -36410 68/push 0/imm32/no-outputs -36411 68/push 0/imm32/no-outputs -36412 53/push-ebx/inouts -36413 68/push 0x11/imm32/alloc-id:fake -36414 68/push 0/imm32/operation -36415 68/push 0/imm32/operation -36416 68/push 1/imm32/tag -36417 89/<- %esi 4/r32/esp -36418 $test-emit-subx-stmt-primitive:initialize-stmt-operation: -36419 # stmt->operation = "increment" -36420 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -36421 (copy-array Heap "increment" %eax) -36422 $test-emit-subx-stmt-primitive:initialize-primitive: -36423 # var primitives/ebx: (addr primitive) -36424 68/push 0/imm32/next -36425 68/push 0/imm32/next -36426 68/push 0/imm32/no-x32 -36427 68/push 0/imm32/no-xm32 -36428 68/push 0/imm32/no-disp32 -36429 68/push 0/imm32/no-imm8 -36430 68/push 0/imm32/no-imm32 -36431 68/push 0/imm32/no-r32 -36432 68/push 1/imm32/rm32-is-first-inout -36433 68/push 0/imm32/subx-name -36434 68/push 0/imm32/subx-name -36435 68/push 0/imm32/no-outputs -36436 68/push 0/imm32/no-outputs -36437 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +36208 # return function->name == stmt->operation +36209 # ecx = lookup(stmt->operation) +36210 8b/-> *(ebp+8) 0/r32/eax +36211 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +36212 89/<- %ecx 0/r32/eax +36213 # eax = lookup(function->name) +36214 8b/-> *(ebp+0xc) 0/r32/eax +36215 (lookup *eax *(eax+4)) # Function-name Function-name => eax +36216 (string-equal? %eax %ecx) # => eax +36217 $mu-stmt-matches-function?:end: +36218 # . restore registers +36219 59/pop-to-ecx +36220 # . epilogue +36221 89/<- %esp 5/r32/ebp +36222 5d/pop-to-ebp +36223 c3/return +36224 +36225 # Type-checking happens elsewhere. This method is for selecting between +36226 # primitives. +36227 subx-type-category-match?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean +36228 # . prologue +36229 55/push-ebp +36230 89/<- %ebp 4/r32/esp +36231 # . save registers +36232 51/push-ecx +36233 # var cata/ecx: int = type-category(a) +36234 (type-category *(ebp+8)) # => eax +36235 89/<- %ecx 0/r32/eax +36236 # var catb/eax: int = type-category(b) +36237 (type-category *(ebp+0xc)) # => eax +36238 # return cata == catb +36239 39/compare %eax 1/r32/ecx +36240 0f 94/set-byte-if-= %al +36241 25/and-eax-with 0xff/imm32 +36242 $subx-type-category-match?:end: +36243 # . restore registers +36244 59/pop-to-ecx +36245 # . epilogue +36246 89/<- %esp 5/r32/ebp +36247 5d/pop-to-ebp +36248 c3/return +36249 +36250 type-category: # a: (addr type-tree) -> result/eax: int +36251 # . prologue +36252 55/push-ebp +36253 89/<- %ebp 4/r32/esp +36254 # . save registers +36255 51/push-ecx +36256 # var lit?/ecx: boolean = literal-type?(a) +36257 (simple-mu-type? *(ebp+8) 0) # literal => eax +36258 89/<- %ecx 0/r32/eax +36259 # var float?/eax: int = float?(a) +36260 (simple-mu-type? *(ebp+8) 0xf) # => eax +36261 # set bits for lit? and float? +36262 c1/shift 4/subop/left %ecx 1/imm8 +36263 09/or %eax 1/r32/ecx +36264 $type-category:end: +36265 # . restore registers +36266 59/pop-to-ecx +36267 # . epilogue +36268 89/<- %esp 5/r32/ebp +36269 5d/pop-to-ebp +36270 c3/return +36271 +36272 simple-mu-type?: # a: (addr type-tree), n: type-id -> result/eax: boolean +36273 # . prologue +36274 55/push-ebp +36275 89/<- %ebp 4/r32/esp +36276 # . save registers +36277 51/push-ecx +36278 # ecx = n +36279 8b/-> *(ebp+0xc) 1/r32/ecx +36280 # return (a->value == n) +36281 8b/-> *(ebp+8) 0/r32/eax +36282 39/compare *(eax+4) 1/r32/ecx # Type-tree-value +36283 0f 94/set-byte-if-= %al +36284 25/and-eax-with 0xff/imm32 +36285 $simple-mu-type?:end: +36286 # . restore registers +36287 59/pop-to-ecx +36288 # . epilogue +36289 89/<- %esp 5/r32/ebp +36290 5d/pop-to-ebp +36291 c3/return +36292 +36293 mu-addr-type?: # a: (addr type-tree) -> result/eax: boolean +36294 # . prologue +36295 55/push-ebp +36296 89/<- %ebp 4/r32/esp +36297 # eax = a +36298 8b/-> *(ebp+8) 0/r32/eax +36299 # if (!a->is-atom?) a = a->left +36300 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +36301 { +36302 75/jump-if-!= break/disp8 +36303 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +36304 } +36305 # return (a->value == addr) +36306 81 7/subop/compare *(eax+4) 2/imm32/addr # Type-tree-value +36307 0f 94/set-byte-if-= %al +36308 25/and-eax-with 0xff/imm32 +36309 $mu-addr-type?:end: +36310 # . epilogue +36311 89/<- %esp 5/r32/ebp +36312 5d/pop-to-ebp +36313 c3/return +36314 +36315 mu-array-type?: # a: (addr type-tree) -> result/eax: boolean +36316 # . prologue +36317 55/push-ebp +36318 89/<- %ebp 4/r32/esp +36319 # eax = a +36320 8b/-> *(ebp+8) 0/r32/eax +36321 # if (!a->is-atom?) a = a->left +36322 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +36323 { +36324 75/jump-if-!= break/disp8 +36325 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +36326 } +36327 # return (a->value == array) +36328 81 7/subop/compare *(eax+4) 3/imm32/array # Type-tree-value +36329 0f 94/set-byte-if-= %al +36330 25/and-eax-with 0xff/imm32 +36331 $mu-array-type?:end: +36332 # . epilogue +36333 89/<- %esp 5/r32/ebp +36334 5d/pop-to-ebp +36335 c3/return +36336 +36337 mu-string-type?: # a: (addr type-tree) -> result/eax: boolean +36338 # . prologue +36339 55/push-ebp +36340 89/<- %ebp 4/r32/esp +36341 # . save registers +36342 56/push-esi +36343 # esi = a +36344 8b/-> *(ebp+8) 6/r32/esi +36345 # if (a->is-atom?) return false +36346 81 7/subop/compare *esi 0/imm32/false # Type-tree-is-atom +36347 0f 85/jump-if-!= $mu-string-type?:return-false/disp32 +36348 # if a is not an addr, return false +36349 (mu-addr-type? %esi) # => eax +36350 3d/compare-eax-with 0/imm32/false +36351 0f 84/jump-if-= $mu-string-type?:end/disp32 # eax changes var +36352 # if a is not an array, return false +36353 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax +36354 (mu-array-type? %eax) # => eax +36355 3d/compare-eax-with 0/imm32/false +36356 74/jump-if-= $mu-string-type?:end/disp8 # eax changes var +36357 # var p/eax: (addr type-tree) = payload of a +36358 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax +36359 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +36360 # if p is an atom, return false +36361 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +36362 75/jump-if-!= $mu-string-type?:return-false/disp8 +36363 # return (p == byte) +36364 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +36365 (simple-mu-type? %eax 8) # byte => eax +36366 eb/jump $mu-string-type?:end/disp8 +36367 $mu-string-type?:return-false: +36368 b8/copy-to-eax 0/imm32/false +36369 $mu-string-type?:end: +36370 # . restore registers +36371 5e/pop-to-esi +36372 # . epilogue +36373 89/<- %esp 5/r32/ebp +36374 5d/pop-to-ebp +36375 c3/return +36376 +36377 mu-stream-type?: # a: (addr type-tree) -> result/eax: boolean +36378 # . prologue +36379 55/push-ebp +36380 89/<- %ebp 4/r32/esp +36381 # eax = a +36382 8b/-> *(ebp+8) 0/r32/eax +36383 # if (!a->is-atom?) a = a->left +36384 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +36385 { +36386 75/jump-if-!= break/disp8 +36387 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +36388 } +36389 # return (a->value == stream) +36390 81 7/subop/compare *(eax+4) 0xb/imm32/stream # Type-tree-value +36391 0f 94/set-byte-if-= %al +36392 25/and-eax-with 0xff/imm32 +36393 $mu-stream-type?:end: +36394 # . epilogue +36395 89/<- %esp 5/r32/ebp +36396 5d/pop-to-ebp +36397 c3/return +36398 +36399 test-emit-subx-stmt-primitive: +36400 # Primitive operation on a variable on the stack. +36401 # increment foo +36402 # => +36403 # ff 0/subop/increment *(ebp-8) +36404 # +36405 # There's a variable on the var stack as follows: +36406 # name: 'foo' +36407 # type: int +36408 # stack-offset: -8 +36409 # +36410 # There's a primitive with this info: +36411 # name: 'increment' +36412 # inouts: int/mem +36413 # value: 'ff 0/subop/increment' +36414 # +36415 # . prologue +36416 55/push-ebp +36417 89/<- %ebp 4/r32/esp +36418 # setup +36419 (clear-stream _test-output-stream) +36420 (clear-stream $_test-output-buffered-file->buffer) +36421 # simulate allocated payloads starting with an initial fake alloc-id (0x11) +36422 $test-emit-subx-stmt-primitive:initialize-type: +36423 # var type/ecx: (payload type-tree) = int +36424 68/push 0/imm32/right:null +36425 68/push 0/imm32/right:null +36426 68/push 0/imm32/left:unused +36427 68/push 1/imm32/value:int +36428 68/push 1/imm32/is-atom?:true +36429 68/push 0x11/imm32/alloc-id:fake:payload +36430 89/<- %ecx 4/r32/esp +36431 $test-emit-subx-stmt-primitive:initialize-var: +36432 # var var-foo/ecx: (payload var) = var(type) +36433 68/push 0/imm32/no-register +36434 68/push 0/imm32/no-register +36435 68/push -8/imm32/stack-offset +36436 68/push 1/imm32/block-depth +36437 51/push-ecx/type 36438 68/push 0x11/imm32/alloc-id:fake 36439 68/push 0/imm32/name 36440 68/push 0/imm32/name -36441 89/<- %ebx 4/r32/esp -36442 $test-emit-subx-stmt-primitive:initialize-primitive-name: -36443 # primitives->name = "increment" -36444 (copy-array Heap "increment" %ebx) # Primitive-name -36445 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: -36446 # primitives->subx-name = "ff 0/subop/increment" -36447 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -36448 (copy-array Heap "ff 0/subop/increment" %eax) -36449 # convert -36450 c7 0/subop/copy *Curr-block-depth 0/imm32 -36451 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0) -36452 (flush _test-output-buffered-file) -36453 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -36459 # check output -36460 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") -36461 # . epilogue -36462 89/<- %esp 5/r32/ebp -36463 5d/pop-to-ebp -36464 c3/return -36465 -36466 test-emit-subx-stmt-primitive-register: -36467 # Primitive operation on a variable in a register. -36468 # foo <- increment -36469 # => -36470 # ff 0/subop/increment %eax # sub-optimal, but should suffice -36471 # -36472 # There's a variable on the var stack as follows: -36473 # name: 'foo' -36474 # type: int -36475 # register: 'eax' -36476 # -36477 # There's a primitive with this info: -36478 # name: 'increment' -36479 # out: int/reg -36480 # value: 'ff 0/subop/increment' -36481 # -36482 # . prologue -36483 55/push-ebp -36484 89/<- %ebp 4/r32/esp -36485 # setup -36486 (clear-stream _test-output-stream) -36487 (clear-stream $_test-output-buffered-file->buffer) -36488 $test-emit-subx-stmt-primitive-register:initialize-type: -36489 # var type/ecx: (payload type-tree) = int -36490 68/push 0/imm32/right:null -36491 68/push 0/imm32/right:null -36492 68/push 0/imm32/left:unused -36493 68/push 1/imm32/value:int -36494 68/push 1/imm32/is-atom?:true -36495 68/push 0x11/imm32/alloc-id:fake:payload -36496 89/<- %ecx 4/r32/esp -36497 $test-emit-subx-stmt-primitive-register:initialize-var: -36498 # var var-foo/ecx: (payload var) -36499 68/push 0/imm32/register -36500 68/push 0/imm32/register -36501 68/push 0/imm32/no-stack-offset -36502 68/push 1/imm32/block-depth -36503 51/push-ecx -36504 68/push 0x11/imm32/alloc-id:fake -36505 68/push 0/imm32/name -36506 68/push 0/imm32/name -36507 68/push 0x11/imm32/alloc-id:fake:payload -36508 89/<- %ecx 4/r32/esp -36509 $test-emit-subx-stmt-primitive-register:initialize-var-name: -36510 # var-foo->name = "foo" -36511 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -36512 (copy-array Heap "foo" %eax) -36513 $test-emit-subx-stmt-primitive-register:initialize-var-register: -36514 # var-foo->register = "eax" -36515 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -36516 (copy-array Heap "eax" %eax) -36517 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: -36518 # var operand/ebx: (payload stmt-var) -36519 68/push 0/imm32/is-deref:false -36520 68/push 0/imm32/next -36521 68/push 0/imm32/next -36522 51/push-ecx/var-foo -36523 68/push 0x11/imm32/alloc-id:fake -36524 68/push 0x11/imm32/alloc-id:fake:payload -36525 89/<- %ebx 4/r32/esp -36526 $test-emit-subx-stmt-primitive-register:initialize-stmt: -36527 # var stmt/esi: (addr statement) -36528 53/push-ebx/outputs -36529 68/push 0x11/imm32/alloc-id:fake -36530 68/push 0/imm32/no-inouts -36531 68/push 0/imm32/no-inouts -36532 68/push 0/imm32/operation -36533 68/push 0/imm32/operation -36534 68/push 1/imm32 -36535 89/<- %esi 4/r32/esp -36536 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: -36537 # stmt->operation = "increment" -36538 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -36539 (copy-array Heap "increment" %eax) -36540 $test-emit-subx-stmt-primitive-register:initialize-formal-var: -36541 # var formal-var/ebx: (payload var) -36542 68/push 0/imm32/register -36543 68/push 0/imm32/register -36544 68/push 0/imm32/no-stack-offset -36545 68/push 1/imm32/block-depth -36546 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -36547 68/push 0x11/imm32/alloc-id:fake -36548 68/push 0/imm32/name -36549 68/push 0/imm32/name -36550 68/push 0x11/imm32/alloc-id:fake:payload -36551 89/<- %ebx 4/r32/esp -36552 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: -36553 # formal-var->name = "dummy" -36554 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -36555 (copy-array Heap "dummy" %eax) -36556 $test-emit-subx-stmt-primitive-register:initialize-formal-register: -36557 # formal-var->register = "*" -36558 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -36559 (copy-array Heap "*" %eax) # Any-register -36560 $test-emit-subx-stmt-primitive-register:initialize-var-list: -36561 # var formal-outputs/ebx: (payload list var) -36562 68/push 0/imm32/next -36563 68/push 0/imm32/next -36564 53/push-ebx/formal-var -36565 68/push 0x11/imm32/alloc-id:fake -36566 68/push 0x11/imm32/alloc-id:fake:payload -36567 89/<- %ebx 4/r32/esp -36568 $test-emit-subx-stmt-primitive-register:initialize-primitive: -36569 # var primitives/ebx: (addr primitive) -36570 68/push 0/imm32/next -36571 68/push 0/imm32/next -36572 68/push 0/imm32/no-x32 -36573 68/push 0/imm32/no-xm32 -36574 68/push 0/imm32/no-disp32 -36575 68/push 0/imm32/no-imm8 -36576 68/push 0/imm32/no-imm32 -36577 68/push 0/imm32/no-r32 -36578 68/push 3/imm32/rm32-is-first-output -36579 68/push 0/imm32/subx-name -36580 68/push 0/imm32/subx-name -36581 53/push-ebx/outputs -36582 68/push 0x11/imm32/alloc-id:fake -36583 68/push 0/imm32/no-inouts -36584 68/push 0/imm32/no-inouts -36585 68/push 0/imm32/name -36586 68/push 0/imm32/name -36587 89/<- %ebx 4/r32/esp -36588 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: -36589 # primitives->name = "increment" -36590 (copy-array Heap "increment" %ebx) # Primitive-name -36591 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: -36592 # primitives->subx-name = "ff 0/subop/increment" -36593 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -36594 (copy-array Heap "ff 0/subop/increment" %eax) -36595 # convert -36596 c7 0/subop/copy *Curr-block-depth 0/imm32 -36597 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0) -36598 (flush _test-output-buffered-file) -36599 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -36605 # check output -36606 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") -36607 # . epilogue -36608 89/<- %esp 5/r32/ebp -36609 5d/pop-to-ebp -36610 c3/return -36611 -36612 test-emit-subx-stmt-select-primitive: -36613 # Select the right primitive between overloads. -36614 # foo <- increment -36615 # => -36616 # ff 0/subop/increment %eax # sub-optimal, but should suffice -36617 # -36618 # There's a variable on the var stack as follows: -36619 # name: 'foo' -36620 # type: int -36621 # register: 'eax' -36622 # -36623 # There's two primitives, as follows: -36624 # - name: 'increment' -36625 # out: int/reg -36626 # value: 'ff 0/subop/increment' -36627 # - name: 'increment' -36628 # inout: int/mem -36629 # value: 'ff 0/subop/increment' -36630 # -36631 # . prologue -36632 55/push-ebp -36633 89/<- %ebp 4/r32/esp -36634 # setup -36635 (clear-stream _test-output-stream) -36636 (clear-stream $_test-output-buffered-file->buffer) -36637 $test-emit-subx-stmt-select-primitive:initialize-type: -36638 # var type/ecx: (payload type-tree) = int -36639 68/push 0/imm32/right:null -36640 68/push 0/imm32/right:null -36641 68/push 0/imm32/left:unused -36642 68/push 1/imm32/value:int -36643 68/push 1/imm32/is-atom?:true -36644 68/push 0x11/imm32/alloc-id:fake:payload -36645 89/<- %ecx 4/r32/esp -36646 $test-emit-subx-stmt-select-primitive:initialize-var: -36647 # var var-foo/ecx: (payload var) -36648 68/push 0/imm32/register -36649 68/push 0/imm32/register -36650 68/push 0/imm32/no-stack-offset -36651 68/push 1/imm32/block-depth -36652 51/push-ecx -36653 68/push 0x11/imm32/alloc-id:fake -36654 68/push 0/imm32/name -36655 68/push 0/imm32/name -36656 68/push 0x11/imm32/alloc-id:fake:payload -36657 89/<- %ecx 4/r32/esp -36658 $test-emit-subx-stmt-select-primitive:initialize-var-name: -36659 # var-foo->name = "foo" -36660 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -36661 (copy-array Heap "foo" %eax) -36662 $test-emit-subx-stmt-select-primitive:initialize-var-register: -36663 # var-foo->register = "eax" -36664 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -36665 (copy-array Heap "eax" %eax) -36666 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: -36667 # var operand/ebx: (payload stmt-var) -36668 68/push 0/imm32/is-deref:false -36669 68/push 0/imm32/next -36670 68/push 0/imm32/next -36671 51/push-ecx/var-foo -36672 68/push 0x11/imm32/alloc-id:fake -36673 68/push 0x11/imm32/alloc-id:fake:payload -36674 89/<- %ebx 4/r32/esp -36675 $test-emit-subx-stmt-select-primitive:initialize-stmt: -36676 # var stmt/esi: (addr statement) -36677 53/push-ebx/outputs -36678 68/push 0x11/imm32/alloc-id:fake -36679 68/push 0/imm32/no-inouts -36680 68/push 0/imm32/no-inouts -36681 68/push 0/imm32/operation -36682 68/push 0/imm32/operation -36683 68/push 1/imm32 -36684 89/<- %esi 4/r32/esp -36685 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: -36686 # stmt->operation = "increment" -36687 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -36688 (copy-array Heap "increment" %eax) -36689 $test-emit-subx-stmt-select-primitive:initialize-formal-var: -36690 # var formal-var/ebx: (payload var) -36691 68/push 0/imm32/register -36692 68/push 0/imm32/register -36693 68/push 0/imm32/no-stack-offset -36694 68/push 1/imm32/block-depth -36695 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -36696 68/push 0x11/imm32/alloc-id:fake -36697 68/push 0/imm32/name -36698 68/push 0/imm32/name -36699 68/push 0x11/imm32/alloc-id:fake:payload -36700 89/<- %ebx 4/r32/esp -36701 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: -36702 # formal-var->name = "dummy" -36703 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -36704 (copy-array Heap "dummy" %eax) -36705 $test-emit-subx-stmt-select-primitive:initialize-formal-register: -36706 # formal-var->register = "*" -36707 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -36708 (copy-array Heap "*" %eax) # Any-register -36709 $test-emit-subx-stmt-select-primitive:initialize-var-list: -36710 # var formal-outputs/ebx: (payload list var) -36711 68/push 0/imm32/next -36712 68/push 0/imm32/next -36713 53/push-ebx/formal-var -36714 68/push 0x11/imm32/alloc-id:fake -36715 68/push 0x11/imm32/alloc-id:fake:payload -36716 89/<- %ebx 4/r32/esp -36717 $test-emit-subx-stmt-select-primitive:initialize-primitive2: -36718 # var primitive2/edi: (payload primitive) -36719 68/push 0/imm32/next -36720 68/push 0/imm32/next -36721 68/push 0/imm32/no-x32 -36722 68/push 0/imm32/no-xm32 -36723 68/push 0/imm32/no-disp32 -36724 68/push 0/imm32/no-imm8 -36725 68/push 0/imm32/no-imm32 -36726 68/push 0/imm32/no-r32 -36727 68/push 3/imm32/rm32-is-first-output -36728 68/push 0/imm32/subx-name -36729 68/push 0/imm32/subx-name -36730 53/push-ebx/outputs -36731 68/push 0x11/imm32/alloc-id:fake -36732 68/push 0/imm32/no-inouts -36733 68/push 0/imm32/no-inouts -36734 68/push 0/imm32/name -36735 68/push 0/imm32/name -36736 68/push 0x11/imm32/alloc-id:fake:payload -36737 89/<- %edi 4/r32/esp -36738 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: -36739 # primitives->name = "increment" -36740 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -36741 (copy-array Heap "increment" %eax) -36742 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: -36743 # primitives->subx-name = "ff 0/subop/increment" -36744 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -36745 (copy-array Heap "ff 0/subop/increment" %eax) -36746 $test-emit-subx-stmt-select-primitive:initialize-primitive: -36747 # var primitives/ebx: (addr primitive) -36748 57/push-edi -36749 68/push 0x11/imm32/alloc-id:fake -36750 68/push 0/imm32/no-x32 -36751 68/push 0/imm32/no-xm32 -36752 68/push 0/imm32/no-disp32 -36753 68/push 0/imm32/no-imm8 -36754 68/push 0/imm32/no-imm32 -36755 68/push 0/imm32/no-r32 -36756 68/push 1/imm32/rm32-is-first-inout -36757 68/push 0/imm32/subx-name -36758 68/push 0/imm32/subx-name -36759 68/push 0/imm32/no-outputs -36760 68/push 0/imm32/no-outputs -36761 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +36441 68/push 0x11/imm32/alloc-id:fake:payload +36442 89/<- %ecx 4/r32/esp +36443 $test-emit-subx-stmt-primitive:initialize-var-name: +36444 # var-foo->name = "foo" +36445 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +36446 (copy-array Heap "foo" %eax) +36447 $test-emit-subx-stmt-primitive:initialize-stmt-var: +36448 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +36449 68/push 0/imm32/is-deref:false +36450 68/push 0/imm32/next +36451 68/push 0/imm32/next +36452 51/push-ecx/var-foo +36453 68/push 0x11/imm32/alloc-id:fake +36454 68/push 0x11/imm32/alloc-id:fake:payload +36455 89/<- %ebx 4/r32/esp +36456 $test-emit-subx-stmt-primitive:initialize-stmt: +36457 # var stmt/esi: (addr statement) +36458 68/push 0/imm32/no-outputs +36459 68/push 0/imm32/no-outputs +36460 53/push-ebx/inouts +36461 68/push 0x11/imm32/alloc-id:fake +36462 68/push 0/imm32/operation +36463 68/push 0/imm32/operation +36464 68/push 1/imm32/tag +36465 89/<- %esi 4/r32/esp +36466 $test-emit-subx-stmt-primitive:initialize-stmt-operation: +36467 # stmt->operation = "increment" +36468 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +36469 (copy-array Heap "increment" %eax) +36470 $test-emit-subx-stmt-primitive:initialize-primitive: +36471 # var primitives/ebx: (addr primitive) +36472 68/push 0/imm32/next +36473 68/push 0/imm32/next +36474 68/push 0/imm32/no-x32 +36475 68/push 0/imm32/no-xm32 +36476 68/push 0/imm32/no-disp32 +36477 68/push 0/imm32/no-imm8 +36478 68/push 0/imm32/no-imm32 +36479 68/push 0/imm32/no-r32 +36480 68/push 1/imm32/rm32-is-first-inout +36481 68/push 0/imm32/subx-name +36482 68/push 0/imm32/subx-name +36483 68/push 0/imm32/no-outputs +36484 68/push 0/imm32/no-outputs +36485 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +36486 68/push 0x11/imm32/alloc-id:fake +36487 68/push 0/imm32/name +36488 68/push 0/imm32/name +36489 89/<- %ebx 4/r32/esp +36490 $test-emit-subx-stmt-primitive:initialize-primitive-name: +36491 # primitives->name = "increment" +36492 (copy-array Heap "increment" %ebx) # Primitive-name +36493 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: +36494 # primitives->subx-name = "ff 0/subop/increment" +36495 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +36496 (copy-array Heap "ff 0/subop/increment" %eax) +36497 # convert +36498 c7 0/subop/copy *Curr-block-depth 0/imm32 +36499 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0) +36500 (flush _test-output-buffered-file) +36501 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +36507 # check output +36508 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") +36509 # . epilogue +36510 89/<- %esp 5/r32/ebp +36511 5d/pop-to-ebp +36512 c3/return +36513 +36514 test-emit-subx-stmt-primitive-register: +36515 # Primitive operation on a variable in a register. +36516 # foo <- increment +36517 # => +36518 # ff 0/subop/increment %eax # sub-optimal, but should suffice +36519 # +36520 # There's a variable on the var stack as follows: +36521 # name: 'foo' +36522 # type: int +36523 # register: 'eax' +36524 # +36525 # There's a primitive with this info: +36526 # name: 'increment' +36527 # out: int/reg +36528 # value: 'ff 0/subop/increment' +36529 # +36530 # . prologue +36531 55/push-ebp +36532 89/<- %ebp 4/r32/esp +36533 # setup +36534 (clear-stream _test-output-stream) +36535 (clear-stream $_test-output-buffered-file->buffer) +36536 $test-emit-subx-stmt-primitive-register:initialize-type: +36537 # var type/ecx: (payload type-tree) = int +36538 68/push 0/imm32/right:null +36539 68/push 0/imm32/right:null +36540 68/push 0/imm32/left:unused +36541 68/push 1/imm32/value:int +36542 68/push 1/imm32/is-atom?:true +36543 68/push 0x11/imm32/alloc-id:fake:payload +36544 89/<- %ecx 4/r32/esp +36545 $test-emit-subx-stmt-primitive-register:initialize-var: +36546 # var var-foo/ecx: (payload var) +36547 68/push 0/imm32/register +36548 68/push 0/imm32/register +36549 68/push 0/imm32/no-stack-offset +36550 68/push 1/imm32/block-depth +36551 51/push-ecx +36552 68/push 0x11/imm32/alloc-id:fake +36553 68/push 0/imm32/name +36554 68/push 0/imm32/name +36555 68/push 0x11/imm32/alloc-id:fake:payload +36556 89/<- %ecx 4/r32/esp +36557 $test-emit-subx-stmt-primitive-register:initialize-var-name: +36558 # var-foo->name = "foo" +36559 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +36560 (copy-array Heap "foo" %eax) +36561 $test-emit-subx-stmt-primitive-register:initialize-var-register: +36562 # var-foo->register = "eax" +36563 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +36564 (copy-array Heap "eax" %eax) +36565 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: +36566 # var operand/ebx: (payload stmt-var) +36567 68/push 0/imm32/is-deref:false +36568 68/push 0/imm32/next +36569 68/push 0/imm32/next +36570 51/push-ecx/var-foo +36571 68/push 0x11/imm32/alloc-id:fake +36572 68/push 0x11/imm32/alloc-id:fake:payload +36573 89/<- %ebx 4/r32/esp +36574 $test-emit-subx-stmt-primitive-register:initialize-stmt: +36575 # var stmt/esi: (addr statement) +36576 53/push-ebx/outputs +36577 68/push 0x11/imm32/alloc-id:fake +36578 68/push 0/imm32/no-inouts +36579 68/push 0/imm32/no-inouts +36580 68/push 0/imm32/operation +36581 68/push 0/imm32/operation +36582 68/push 1/imm32 +36583 89/<- %esi 4/r32/esp +36584 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: +36585 # stmt->operation = "increment" +36586 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +36587 (copy-array Heap "increment" %eax) +36588 $test-emit-subx-stmt-primitive-register:initialize-formal-var: +36589 # var formal-var/ebx: (payload var) +36590 68/push 0/imm32/register +36591 68/push 0/imm32/register +36592 68/push 0/imm32/no-stack-offset +36593 68/push 1/imm32/block-depth +36594 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +36595 68/push 0x11/imm32/alloc-id:fake +36596 68/push 0/imm32/name +36597 68/push 0/imm32/name +36598 68/push 0x11/imm32/alloc-id:fake:payload +36599 89/<- %ebx 4/r32/esp +36600 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: +36601 # formal-var->name = "dummy" +36602 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +36603 (copy-array Heap "dummy" %eax) +36604 $test-emit-subx-stmt-primitive-register:initialize-formal-register: +36605 # formal-var->register = "*" +36606 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +36607 (copy-array Heap "*" %eax) # Any-register +36608 $test-emit-subx-stmt-primitive-register:initialize-var-list: +36609 # var formal-outputs/ebx: (payload list var) +36610 68/push 0/imm32/next +36611 68/push 0/imm32/next +36612 53/push-ebx/formal-var +36613 68/push 0x11/imm32/alloc-id:fake +36614 68/push 0x11/imm32/alloc-id:fake:payload +36615 89/<- %ebx 4/r32/esp +36616 $test-emit-subx-stmt-primitive-register:initialize-primitive: +36617 # var primitives/ebx: (addr primitive) +36618 68/push 0/imm32/next +36619 68/push 0/imm32/next +36620 68/push 0/imm32/no-x32 +36621 68/push 0/imm32/no-xm32 +36622 68/push 0/imm32/no-disp32 +36623 68/push 0/imm32/no-imm8 +36624 68/push 0/imm32/no-imm32 +36625 68/push 0/imm32/no-r32 +36626 68/push 3/imm32/rm32-is-first-output +36627 68/push 0/imm32/subx-name +36628 68/push 0/imm32/subx-name +36629 53/push-ebx/outputs +36630 68/push 0x11/imm32/alloc-id:fake +36631 68/push 0/imm32/no-inouts +36632 68/push 0/imm32/no-inouts +36633 68/push 0/imm32/name +36634 68/push 0/imm32/name +36635 89/<- %ebx 4/r32/esp +36636 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: +36637 # primitives->name = "increment" +36638 (copy-array Heap "increment" %ebx) # Primitive-name +36639 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: +36640 # primitives->subx-name = "ff 0/subop/increment" +36641 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +36642 (copy-array Heap "ff 0/subop/increment" %eax) +36643 # convert +36644 c7 0/subop/copy *Curr-block-depth 0/imm32 +36645 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0) +36646 (flush _test-output-buffered-file) +36647 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +36653 # check output +36654 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") +36655 # . epilogue +36656 89/<- %esp 5/r32/ebp +36657 5d/pop-to-ebp +36658 c3/return +36659 +36660 test-emit-subx-stmt-select-primitive: +36661 # Select the right primitive between overloads. +36662 # foo <- increment +36663 # => +36664 # ff 0/subop/increment %eax # sub-optimal, but should suffice +36665 # +36666 # There's a variable on the var stack as follows: +36667 # name: 'foo' +36668 # type: int +36669 # register: 'eax' +36670 # +36671 # There's two primitives, as follows: +36672 # - name: 'increment' +36673 # out: int/reg +36674 # value: 'ff 0/subop/increment' +36675 # - name: 'increment' +36676 # inout: int/mem +36677 # value: 'ff 0/subop/increment' +36678 # +36679 # . prologue +36680 55/push-ebp +36681 89/<- %ebp 4/r32/esp +36682 # setup +36683 (clear-stream _test-output-stream) +36684 (clear-stream $_test-output-buffered-file->buffer) +36685 $test-emit-subx-stmt-select-primitive:initialize-type: +36686 # var type/ecx: (payload type-tree) = int +36687 68/push 0/imm32/right:null +36688 68/push 0/imm32/right:null +36689 68/push 0/imm32/left:unused +36690 68/push 1/imm32/value:int +36691 68/push 1/imm32/is-atom?:true +36692 68/push 0x11/imm32/alloc-id:fake:payload +36693 89/<- %ecx 4/r32/esp +36694 $test-emit-subx-stmt-select-primitive:initialize-var: +36695 # var var-foo/ecx: (payload var) +36696 68/push 0/imm32/register +36697 68/push 0/imm32/register +36698 68/push 0/imm32/no-stack-offset +36699 68/push 1/imm32/block-depth +36700 51/push-ecx +36701 68/push 0x11/imm32/alloc-id:fake +36702 68/push 0/imm32/name +36703 68/push 0/imm32/name +36704 68/push 0x11/imm32/alloc-id:fake:payload +36705 89/<- %ecx 4/r32/esp +36706 $test-emit-subx-stmt-select-primitive:initialize-var-name: +36707 # var-foo->name = "foo" +36708 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +36709 (copy-array Heap "foo" %eax) +36710 $test-emit-subx-stmt-select-primitive:initialize-var-register: +36711 # var-foo->register = "eax" +36712 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +36713 (copy-array Heap "eax" %eax) +36714 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: +36715 # var operand/ebx: (payload stmt-var) +36716 68/push 0/imm32/is-deref:false +36717 68/push 0/imm32/next +36718 68/push 0/imm32/next +36719 51/push-ecx/var-foo +36720 68/push 0x11/imm32/alloc-id:fake +36721 68/push 0x11/imm32/alloc-id:fake:payload +36722 89/<- %ebx 4/r32/esp +36723 $test-emit-subx-stmt-select-primitive:initialize-stmt: +36724 # var stmt/esi: (addr statement) +36725 53/push-ebx/outputs +36726 68/push 0x11/imm32/alloc-id:fake +36727 68/push 0/imm32/no-inouts +36728 68/push 0/imm32/no-inouts +36729 68/push 0/imm32/operation +36730 68/push 0/imm32/operation +36731 68/push 1/imm32 +36732 89/<- %esi 4/r32/esp +36733 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: +36734 # stmt->operation = "increment" +36735 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +36736 (copy-array Heap "increment" %eax) +36737 $test-emit-subx-stmt-select-primitive:initialize-formal-var: +36738 # var formal-var/ebx: (payload var) +36739 68/push 0/imm32/register +36740 68/push 0/imm32/register +36741 68/push 0/imm32/no-stack-offset +36742 68/push 1/imm32/block-depth +36743 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +36744 68/push 0x11/imm32/alloc-id:fake +36745 68/push 0/imm32/name +36746 68/push 0/imm32/name +36747 68/push 0x11/imm32/alloc-id:fake:payload +36748 89/<- %ebx 4/r32/esp +36749 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: +36750 # formal-var->name = "dummy" +36751 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +36752 (copy-array Heap "dummy" %eax) +36753 $test-emit-subx-stmt-select-primitive:initialize-formal-register: +36754 # formal-var->register = "*" +36755 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +36756 (copy-array Heap "*" %eax) # Any-register +36757 $test-emit-subx-stmt-select-primitive:initialize-var-list: +36758 # var formal-outputs/ebx: (payload list var) +36759 68/push 0/imm32/next +36760 68/push 0/imm32/next +36761 53/push-ebx/formal-var 36762 68/push 0x11/imm32/alloc-id:fake -36763 68/push 0/imm32/name -36764 68/push 0/imm32/name -36765 89/<- %ebx 4/r32/esp -36766 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: -36767 # primitives->name = "increment" -36768 (copy-array Heap "increment" %ebx) # Primitive-name -36769 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: -36770 # primitives->subx-name = "ff 0/subop/increment" -36771 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -36772 (copy-array Heap "ff 0/subop/increment" %eax) -36773 # convert -36774 c7 0/subop/copy *Curr-block-depth 0/imm32 -36775 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0) -36776 (flush _test-output-buffered-file) -36777 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -36783 # check output -36784 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") -36785 # . epilogue -36786 89/<- %esp 5/r32/ebp -36787 5d/pop-to-ebp -36788 c3/return -36789 -36790 test-emit-subx-stmt-select-primitive-2: -36791 # Select the right primitive between overloads. -36792 # increment foo -36793 # => -36794 # ff 0/subop/increment %eax # sub-optimal, but should suffice -36795 # -36796 # There's a variable on the var stack as follows: -36797 # name: 'foo' -36798 # type: int -36799 # register: 'eax' -36800 # -36801 # There's two primitives, as follows: -36802 # - name: 'increment' -36803 # out: int/reg -36804 # value: 'ff 0/subop/increment' -36805 # - name: 'increment' -36806 # inout: int/mem -36807 # value: 'ff 0/subop/increment' -36808 # -36809 # . prologue -36810 55/push-ebp -36811 89/<- %ebp 4/r32/esp -36812 # setup -36813 (clear-stream _test-output-stream) -36814 (clear-stream $_test-output-buffered-file->buffer) -36815 $test-emit-subx-stmt-select-primitive-2:initialize-type: -36816 # var type/ecx: (payload type-tree) = int -36817 68/push 0/imm32/right:null -36818 68/push 0/imm32/right:null -36819 68/push 0/imm32/left:unused -36820 68/push 1/imm32/value:int -36821 68/push 1/imm32/is-atom?:true -36822 68/push 0x11/imm32/alloc-id:fake:payload -36823 89/<- %ecx 4/r32/esp -36824 $test-emit-subx-stmt-select-primitive-2:initialize-var: -36825 # var var-foo/ecx: (payload var) -36826 68/push 0/imm32/register -36827 68/push 0/imm32/register -36828 68/push 0/imm32/no-stack-offset -36829 68/push 1/imm32/block-depth -36830 51/push-ecx -36831 68/push 0x11/imm32/alloc-id:fake -36832 68/push 0/imm32/name -36833 68/push 0/imm32/name -36834 68/push 0x11/imm32/alloc-id:fake:payload -36835 89/<- %ecx 4/r32/esp -36836 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: -36837 # var-foo->name = "foo" -36838 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -36839 (copy-array Heap "foo" %eax) -36840 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: -36841 # var-foo->register = "eax" -36842 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -36843 (copy-array Heap "eax" %eax) -36844 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: -36845 # var operand/ebx: (payload stmt-var) -36846 68/push 0/imm32/is-deref:false -36847 68/push 0/imm32/next -36848 68/push 0/imm32/next -36849 51/push-ecx/var-foo -36850 68/push 0x11/imm32/alloc-id:fake -36851 68/push 0x11/imm32/alloc-id:fake:payload -36852 89/<- %ebx 4/r32/esp -36853 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: -36854 # var stmt/esi: (addr statement) -36855 68/push 0/imm32/no-outputs -36856 68/push 0/imm32/no-outputs -36857 53/push-ebx/inouts -36858 68/push 0x11/imm32/alloc-id:fake -36859 68/push 0/imm32/operation -36860 68/push 0/imm32/operation -36861 68/push 1/imm32 -36862 89/<- %esi 4/r32/esp -36863 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: -36864 # stmt->operation = "increment" -36865 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -36866 (copy-array Heap "increment" %eax) -36867 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: -36868 # var formal-var/ebx: (payload var) -36869 68/push 0/imm32/register -36870 68/push 0/imm32/register -36871 68/push 0/imm32/no-stack-offset -36872 68/push 1/imm32/block-depth -36873 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -36874 68/push 0x11/imm32/alloc-id:fake -36875 68/push 0/imm32/name -36876 68/push 0/imm32/name -36877 68/push 0x11/imm32/alloc-id:fake:payload -36878 89/<- %ebx 4/r32/esp -36879 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: -36880 # formal-var->name = "dummy" -36881 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -36882 (copy-array Heap "dummy" %eax) -36883 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: -36884 # formal-var->register = "*" -36885 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -36886 (copy-array Heap "*" %eax) # Any-register -36887 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: -36888 # var formal-outputs/ebx: (payload list stmt-var) -36889 68/push 0/imm32/next -36890 68/push 0/imm32/next -36891 53/push-ebx/formal-var -36892 68/push 0x11/imm32/alloc-id:fake -36893 68/push 0x11/imm32/alloc-id:fake:payload -36894 89/<- %ebx 4/r32/esp -36895 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: -36896 # var primitive2/edi: (payload primitive) -36897 68/push 0/imm32/next -36898 68/push 0/imm32/next -36899 68/push 0/imm32/no-x32 -36900 68/push 0/imm32/no-xm32 -36901 68/push 0/imm32/no-disp32 -36902 68/push 0/imm32/no-imm8 -36903 68/push 0/imm32/no-imm32 -36904 68/push 0/imm32/no-r32 -36905 68/push 3/imm32/rm32-is-first-output -36906 68/push 0/imm32/subx-name -36907 68/push 0/imm32/subx-name -36908 53/push-ebx/outputs -36909 68/push 0x11/imm32/alloc-id:fake -36910 68/push 0/imm32/no-inouts -36911 68/push 0/imm32/no-inouts -36912 68/push 0/imm32/name -36913 68/push 0/imm32/name -36914 68/push 0x11/imm32/alloc-id:fake:payload -36915 89/<- %edi 4/r32/esp -36916 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: -36917 # primitives->name = "increment" -36918 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -36919 (copy-array Heap "increment" %eax) -36920 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: -36921 # primitives->subx-name = "ff 0/subop/increment" -36922 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -36923 (copy-array Heap "ff 0/subop/increment" %eax) -36924 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: -36925 # var primitives/ebx: (addr primitive) -36926 57/push-edi -36927 68/push 0x11/imm32/alloc-id:fake -36928 68/push 0/imm32/no-x32 -36929 68/push 0/imm32/no-xm32 -36930 68/push 0/imm32/no-disp32 -36931 68/push 0/imm32/no-imm8 -36932 68/push 0/imm32/no-imm32 -36933 68/push 0/imm32/no-r32 -36934 68/push 1/imm32/rm32-is-first-inout -36935 68/push 0/imm32/subx-name -36936 68/push 0/imm32/subx-name -36937 68/push 0/imm32/no-outputs -36938 68/push 0/imm32/no-outputs -36939 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +36763 68/push 0x11/imm32/alloc-id:fake:payload +36764 89/<- %ebx 4/r32/esp +36765 $test-emit-subx-stmt-select-primitive:initialize-primitive2: +36766 # var primitive2/edi: (payload primitive) +36767 68/push 0/imm32/next +36768 68/push 0/imm32/next +36769 68/push 0/imm32/no-x32 +36770 68/push 0/imm32/no-xm32 +36771 68/push 0/imm32/no-disp32 +36772 68/push 0/imm32/no-imm8 +36773 68/push 0/imm32/no-imm32 +36774 68/push 0/imm32/no-r32 +36775 68/push 3/imm32/rm32-is-first-output +36776 68/push 0/imm32/subx-name +36777 68/push 0/imm32/subx-name +36778 53/push-ebx/outputs +36779 68/push 0x11/imm32/alloc-id:fake +36780 68/push 0/imm32/no-inouts +36781 68/push 0/imm32/no-inouts +36782 68/push 0/imm32/name +36783 68/push 0/imm32/name +36784 68/push 0x11/imm32/alloc-id:fake:payload +36785 89/<- %edi 4/r32/esp +36786 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: +36787 # primitives->name = "increment" +36788 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +36789 (copy-array Heap "increment" %eax) +36790 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: +36791 # primitives->subx-name = "ff 0/subop/increment" +36792 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +36793 (copy-array Heap "ff 0/subop/increment" %eax) +36794 $test-emit-subx-stmt-select-primitive:initialize-primitive: +36795 # var primitives/ebx: (addr primitive) +36796 57/push-edi +36797 68/push 0x11/imm32/alloc-id:fake +36798 68/push 0/imm32/no-x32 +36799 68/push 0/imm32/no-xm32 +36800 68/push 0/imm32/no-disp32 +36801 68/push 0/imm32/no-imm8 +36802 68/push 0/imm32/no-imm32 +36803 68/push 0/imm32/no-r32 +36804 68/push 1/imm32/rm32-is-first-inout +36805 68/push 0/imm32/subx-name +36806 68/push 0/imm32/subx-name +36807 68/push 0/imm32/no-outputs +36808 68/push 0/imm32/no-outputs +36809 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +36810 68/push 0x11/imm32/alloc-id:fake +36811 68/push 0/imm32/name +36812 68/push 0/imm32/name +36813 89/<- %ebx 4/r32/esp +36814 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: +36815 # primitives->name = "increment" +36816 (copy-array Heap "increment" %ebx) # Primitive-name +36817 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: +36818 # primitives->subx-name = "ff 0/subop/increment" +36819 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +36820 (copy-array Heap "ff 0/subop/increment" %eax) +36821 # convert +36822 c7 0/subop/copy *Curr-block-depth 0/imm32 +36823 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0) +36824 (flush _test-output-buffered-file) +36825 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +36831 # check output +36832 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") +36833 # . epilogue +36834 89/<- %esp 5/r32/ebp +36835 5d/pop-to-ebp +36836 c3/return +36837 +36838 test-emit-subx-stmt-select-primitive-2: +36839 # Select the right primitive between overloads. +36840 # increment foo +36841 # => +36842 # ff 0/subop/increment %eax # sub-optimal, but should suffice +36843 # +36844 # There's a variable on the var stack as follows: +36845 # name: 'foo' +36846 # type: int +36847 # register: 'eax' +36848 # +36849 # There's two primitives, as follows: +36850 # - name: 'increment' +36851 # out: int/reg +36852 # value: 'ff 0/subop/increment' +36853 # - name: 'increment' +36854 # inout: int/mem +36855 # value: 'ff 0/subop/increment' +36856 # +36857 # . prologue +36858 55/push-ebp +36859 89/<- %ebp 4/r32/esp +36860 # setup +36861 (clear-stream _test-output-stream) +36862 (clear-stream $_test-output-buffered-file->buffer) +36863 $test-emit-subx-stmt-select-primitive-2:initialize-type: +36864 # var type/ecx: (payload type-tree) = int +36865 68/push 0/imm32/right:null +36866 68/push 0/imm32/right:null +36867 68/push 0/imm32/left:unused +36868 68/push 1/imm32/value:int +36869 68/push 1/imm32/is-atom?:true +36870 68/push 0x11/imm32/alloc-id:fake:payload +36871 89/<- %ecx 4/r32/esp +36872 $test-emit-subx-stmt-select-primitive-2:initialize-var: +36873 # var var-foo/ecx: (payload var) +36874 68/push 0/imm32/register +36875 68/push 0/imm32/register +36876 68/push 0/imm32/no-stack-offset +36877 68/push 1/imm32/block-depth +36878 51/push-ecx +36879 68/push 0x11/imm32/alloc-id:fake +36880 68/push 0/imm32/name +36881 68/push 0/imm32/name +36882 68/push 0x11/imm32/alloc-id:fake:payload +36883 89/<- %ecx 4/r32/esp +36884 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: +36885 # var-foo->name = "foo" +36886 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +36887 (copy-array Heap "foo" %eax) +36888 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: +36889 # var-foo->register = "eax" +36890 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +36891 (copy-array Heap "eax" %eax) +36892 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: +36893 # var operand/ebx: (payload stmt-var) +36894 68/push 0/imm32/is-deref:false +36895 68/push 0/imm32/next +36896 68/push 0/imm32/next +36897 51/push-ecx/var-foo +36898 68/push 0x11/imm32/alloc-id:fake +36899 68/push 0x11/imm32/alloc-id:fake:payload +36900 89/<- %ebx 4/r32/esp +36901 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: +36902 # var stmt/esi: (addr statement) +36903 68/push 0/imm32/no-outputs +36904 68/push 0/imm32/no-outputs +36905 53/push-ebx/inouts +36906 68/push 0x11/imm32/alloc-id:fake +36907 68/push 0/imm32/operation +36908 68/push 0/imm32/operation +36909 68/push 1/imm32 +36910 89/<- %esi 4/r32/esp +36911 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: +36912 # stmt->operation = "increment" +36913 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +36914 (copy-array Heap "increment" %eax) +36915 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: +36916 # var formal-var/ebx: (payload var) +36917 68/push 0/imm32/register +36918 68/push 0/imm32/register +36919 68/push 0/imm32/no-stack-offset +36920 68/push 1/imm32/block-depth +36921 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +36922 68/push 0x11/imm32/alloc-id:fake +36923 68/push 0/imm32/name +36924 68/push 0/imm32/name +36925 68/push 0x11/imm32/alloc-id:fake:payload +36926 89/<- %ebx 4/r32/esp +36927 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: +36928 # formal-var->name = "dummy" +36929 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +36930 (copy-array Heap "dummy" %eax) +36931 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: +36932 # formal-var->register = "*" +36933 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +36934 (copy-array Heap "*" %eax) # Any-register +36935 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: +36936 # var formal-outputs/ebx: (payload list stmt-var) +36937 68/push 0/imm32/next +36938 68/push 0/imm32/next +36939 53/push-ebx/formal-var 36940 68/push 0x11/imm32/alloc-id:fake -36941 68/push 0/imm32/name -36942 68/push 0/imm32/name -36943 89/<- %ebx 4/r32/esp -36944 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: -36945 # primitives->name = "increment" -36946 (copy-array Heap "increment" %ebx) # Primitive-name -36947 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: -36948 # primitives->subx-name = "ff 0/subop/increment" -36949 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -36950 (copy-array Heap "ff 0/subop/increment" %eax) -36951 # convert -36952 c7 0/subop/copy *Curr-block-depth 0/imm32 -36953 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0) -36954 (flush _test-output-buffered-file) -36955 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -36961 # check output -36962 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") -36963 # . epilogue -36964 89/<- %esp 5/r32/ebp -36965 5d/pop-to-ebp -36966 c3/return -36967 -36968 test-increment-register: -36969 # Select the right register between overloads. -36970 # foo <- increment -36971 # => -36972 # 50/increment-eax -36973 # -36974 # There's a variable on the var stack as follows: -36975 # name: 'foo' -36976 # type: int -36977 # register: 'eax' -36978 # -36979 # Primitives are the global definitions. -36980 # -36981 # . prologue -36982 55/push-ebp -36983 89/<- %ebp 4/r32/esp -36984 # setup -36985 (clear-stream _test-output-stream) -36986 (clear-stream $_test-output-buffered-file->buffer) -36987 $test-increment-register:initialize-type: -36988 # var type/ecx: (payload type-tree) = int -36989 68/push 0/imm32/right:null -36990 68/push 0/imm32/right:null -36991 68/push 0/imm32/left:unused -36992 68/push 1/imm32/value:int -36993 68/push 1/imm32/is-atom?:true -36994 68/push 0x11/imm32/alloc-id:fake:payload -36995 89/<- %ecx 4/r32/esp -36996 $test-increment-register:initialize-var: -36997 # var var-foo/ecx: (payload var) -36998 68/push 0/imm32/register -36999 68/push 0/imm32/register -37000 68/push 0/imm32/no-stack-offset -37001 68/push 1/imm32/block-depth -37002 51/push-ecx -37003 68/push 0x11/imm32/alloc-id:fake -37004 68/push 0/imm32/name -37005 68/push 0/imm32/name -37006 68/push 0x11/imm32/alloc-id:fake:payload -37007 89/<- %ecx 4/r32/esp -37008 $test-increment-register:initialize-var-name: -37009 # var-foo->name = "foo" -37010 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37011 (copy-array Heap "foo" %eax) -37012 $test-increment-register:initialize-var-register: -37013 # var-foo->register = "eax" -37014 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -37015 (copy-array Heap "eax" %eax) -37016 $test-increment-register:initialize-stmt-var: -37017 # var operand/ebx: (payload stmt-var) -37018 68/push 0/imm32/is-deref:false -37019 68/push 0/imm32/next -37020 68/push 0/imm32/next -37021 51/push-ecx/var-foo -37022 68/push 0x11/imm32/alloc-id:fake -37023 68/push 0x11/imm32/alloc-id:fake:payload -37024 89/<- %ebx 4/r32/esp -37025 $test-increment-register:initialize-stmt: -37026 # var stmt/esi: (addr statement) -37027 53/push-ebx/outputs -37028 68/push 0x11/imm32/alloc-id:fake -37029 68/push 0/imm32/no-inouts -37030 68/push 0/imm32/no-inouts -37031 68/push 0/imm32/operation -37032 68/push 0/imm32/operation -37033 68/push 1/imm32 -37034 89/<- %esi 4/r32/esp -37035 $test-increment-register:initialize-stmt-operation: -37036 # stmt->operation = "increment" -37037 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37038 (copy-array Heap "increment" %eax) -37039 # convert -37040 c7 0/subop/copy *Curr-block-depth 0/imm32 -37041 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37042 (flush _test-output-buffered-file) -37043 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37049 # check output -37050 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") -37051 # . epilogue -37052 89/<- %esp 5/r32/ebp -37053 5d/pop-to-ebp -37054 c3/return -37055 -37056 test-add-reg-to-reg: -37057 # var1/reg <- add var2/reg -37058 # => -37059 # 01/add-to %var1 var2 -37060 # -37061 # . prologue -37062 55/push-ebp -37063 89/<- %ebp 4/r32/esp -37064 # setup -37065 (clear-stream _test-output-stream) -37066 (clear-stream $_test-output-buffered-file->buffer) -37067 $test-add-reg-to-reg:initialize-type: -37068 # var type/ecx: (payload type-tree) = int -37069 68/push 0/imm32/right:null -37070 68/push 0/imm32/right:null -37071 68/push 0/imm32/left:unused -37072 68/push 1/imm32/value:int -37073 68/push 1/imm32/is-atom?:true -37074 68/push 0x11/imm32/alloc-id:fake:payload -37075 89/<- %ecx 4/r32/esp -37076 $test-add-reg-to-reg:initialize-var1: -37077 # var var1/ecx: (payload var) -37078 68/push 0/imm32/register -37079 68/push 0/imm32/register -37080 68/push 0/imm32/no-stack-offset -37081 68/push 1/imm32/block-depth -37082 51/push-ecx -37083 68/push 0x11/imm32/alloc-id:fake -37084 68/push 0/imm32/name -37085 68/push 0/imm32/name -37086 68/push 0x11/imm32/alloc-id:fake:payload -37087 89/<- %ecx 4/r32/esp -37088 $test-add-reg-to-reg:initialize-var1-name: -37089 # var1->name = "var1" -37090 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37091 (copy-array Heap "var1" %eax) -37092 $test-add-reg-to-reg:initialize-var1-register: -37093 # var1->register = "eax" -37094 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -37095 (copy-array Heap "eax" %eax) -37096 $test-add-reg-to-reg:initialize-var2: -37097 # var var2/edx: (payload var) -37098 68/push 0/imm32/register -37099 68/push 0/imm32/register -37100 68/push 0/imm32/no-stack-offset -37101 68/push 1/imm32/block-depth -37102 ff 6/subop/push *(ecx+0x10) -37103 68/push 0x11/imm32/alloc-id:fake -37104 68/push 0/imm32/name -37105 68/push 0/imm32/name -37106 68/push 0x11/imm32/alloc-id:fake:payload -37107 89/<- %edx 4/r32/esp -37108 $test-add-reg-to-reg:initialize-var2-name: -37109 # var2->name = "var2" -37110 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -37111 (copy-array Heap "var2" %eax) -37112 $test-add-reg-to-reg:initialize-var2-register: -37113 # var2->register = "ecx" -37114 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -37115 (copy-array Heap "ecx" %eax) -37116 $test-add-reg-to-reg:initialize-inouts: -37117 # var inouts/esi: (payload stmt-var) = [var2] -37118 68/push 0/imm32/is-deref:false -37119 68/push 0/imm32/next -37120 68/push 0/imm32/next -37121 52/push-edx/var2 -37122 68/push 0x11/imm32/alloc-id:fake -37123 68/push 0x11/imm32/alloc-id:fake:payload -37124 89/<- %esi 4/r32/esp -37125 $test-add-reg-to-reg:initialize-outputs: -37126 # var outputs/edi: (payload stmt-var) = [var1] -37127 68/push 0/imm32/is-deref:false -37128 68/push 0/imm32/next -37129 68/push 0/imm32/next -37130 51/push-ecx/var1 +36941 68/push 0x11/imm32/alloc-id:fake:payload +36942 89/<- %ebx 4/r32/esp +36943 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: +36944 # var primitive2/edi: (payload primitive) +36945 68/push 0/imm32/next +36946 68/push 0/imm32/next +36947 68/push 0/imm32/no-x32 +36948 68/push 0/imm32/no-xm32 +36949 68/push 0/imm32/no-disp32 +36950 68/push 0/imm32/no-imm8 +36951 68/push 0/imm32/no-imm32 +36952 68/push 0/imm32/no-r32 +36953 68/push 3/imm32/rm32-is-first-output +36954 68/push 0/imm32/subx-name +36955 68/push 0/imm32/subx-name +36956 53/push-ebx/outputs +36957 68/push 0x11/imm32/alloc-id:fake +36958 68/push 0/imm32/no-inouts +36959 68/push 0/imm32/no-inouts +36960 68/push 0/imm32/name +36961 68/push 0/imm32/name +36962 68/push 0x11/imm32/alloc-id:fake:payload +36963 89/<- %edi 4/r32/esp +36964 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: +36965 # primitives->name = "increment" +36966 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +36967 (copy-array Heap "increment" %eax) +36968 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: +36969 # primitives->subx-name = "ff 0/subop/increment" +36970 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +36971 (copy-array Heap "ff 0/subop/increment" %eax) +36972 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: +36973 # var primitives/ebx: (addr primitive) +36974 57/push-edi +36975 68/push 0x11/imm32/alloc-id:fake +36976 68/push 0/imm32/no-x32 +36977 68/push 0/imm32/no-xm32 +36978 68/push 0/imm32/no-disp32 +36979 68/push 0/imm32/no-imm8 +36980 68/push 0/imm32/no-imm32 +36981 68/push 0/imm32/no-r32 +36982 68/push 1/imm32/rm32-is-first-inout +36983 68/push 0/imm32/subx-name +36984 68/push 0/imm32/subx-name +36985 68/push 0/imm32/no-outputs +36986 68/push 0/imm32/no-outputs +36987 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +36988 68/push 0x11/imm32/alloc-id:fake +36989 68/push 0/imm32/name +36990 68/push 0/imm32/name +36991 89/<- %ebx 4/r32/esp +36992 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: +36993 # primitives->name = "increment" +36994 (copy-array Heap "increment" %ebx) # Primitive-name +36995 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: +36996 # primitives->subx-name = "ff 0/subop/increment" +36997 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +36998 (copy-array Heap "ff 0/subop/increment" %eax) +36999 # convert +37000 c7 0/subop/copy *Curr-block-depth 0/imm32 +37001 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0) +37002 (flush _test-output-buffered-file) +37003 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37009 # check output +37010 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") +37011 # . epilogue +37012 89/<- %esp 5/r32/ebp +37013 5d/pop-to-ebp +37014 c3/return +37015 +37016 test-increment-register: +37017 # Select the right register between overloads. +37018 # foo <- increment +37019 # => +37020 # 50/increment-eax +37021 # +37022 # There's a variable on the var stack as follows: +37023 # name: 'foo' +37024 # type: int +37025 # register: 'eax' +37026 # +37027 # Primitives are the global definitions. +37028 # +37029 # . prologue +37030 55/push-ebp +37031 89/<- %ebp 4/r32/esp +37032 # setup +37033 (clear-stream _test-output-stream) +37034 (clear-stream $_test-output-buffered-file->buffer) +37035 $test-increment-register:initialize-type: +37036 # var type/ecx: (payload type-tree) = int +37037 68/push 0/imm32/right:null +37038 68/push 0/imm32/right:null +37039 68/push 0/imm32/left:unused +37040 68/push 1/imm32/value:int +37041 68/push 1/imm32/is-atom?:true +37042 68/push 0x11/imm32/alloc-id:fake:payload +37043 89/<- %ecx 4/r32/esp +37044 $test-increment-register:initialize-var: +37045 # var var-foo/ecx: (payload var) +37046 68/push 0/imm32/register +37047 68/push 0/imm32/register +37048 68/push 0/imm32/no-stack-offset +37049 68/push 1/imm32/block-depth +37050 51/push-ecx +37051 68/push 0x11/imm32/alloc-id:fake +37052 68/push 0/imm32/name +37053 68/push 0/imm32/name +37054 68/push 0x11/imm32/alloc-id:fake:payload +37055 89/<- %ecx 4/r32/esp +37056 $test-increment-register:initialize-var-name: +37057 # var-foo->name = "foo" +37058 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37059 (copy-array Heap "foo" %eax) +37060 $test-increment-register:initialize-var-register: +37061 # var-foo->register = "eax" +37062 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +37063 (copy-array Heap "eax" %eax) +37064 $test-increment-register:initialize-stmt-var: +37065 # var operand/ebx: (payload stmt-var) +37066 68/push 0/imm32/is-deref:false +37067 68/push 0/imm32/next +37068 68/push 0/imm32/next +37069 51/push-ecx/var-foo +37070 68/push 0x11/imm32/alloc-id:fake +37071 68/push 0x11/imm32/alloc-id:fake:payload +37072 89/<- %ebx 4/r32/esp +37073 $test-increment-register:initialize-stmt: +37074 # var stmt/esi: (addr statement) +37075 53/push-ebx/outputs +37076 68/push 0x11/imm32/alloc-id:fake +37077 68/push 0/imm32/no-inouts +37078 68/push 0/imm32/no-inouts +37079 68/push 0/imm32/operation +37080 68/push 0/imm32/operation +37081 68/push 1/imm32 +37082 89/<- %esi 4/r32/esp +37083 $test-increment-register:initialize-stmt-operation: +37084 # stmt->operation = "increment" +37085 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37086 (copy-array Heap "increment" %eax) +37087 # convert +37088 c7 0/subop/copy *Curr-block-depth 0/imm32 +37089 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37090 (flush _test-output-buffered-file) +37091 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37097 # check output +37098 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") +37099 # . epilogue +37100 89/<- %esp 5/r32/ebp +37101 5d/pop-to-ebp +37102 c3/return +37103 +37104 test-add-reg-to-reg: +37105 # var1/reg <- add var2/reg +37106 # => +37107 # 01/add-to %var1 var2 +37108 # +37109 # . prologue +37110 55/push-ebp +37111 89/<- %ebp 4/r32/esp +37112 # setup +37113 (clear-stream _test-output-stream) +37114 (clear-stream $_test-output-buffered-file->buffer) +37115 $test-add-reg-to-reg:initialize-type: +37116 # var type/ecx: (payload type-tree) = int +37117 68/push 0/imm32/right:null +37118 68/push 0/imm32/right:null +37119 68/push 0/imm32/left:unused +37120 68/push 1/imm32/value:int +37121 68/push 1/imm32/is-atom?:true +37122 68/push 0x11/imm32/alloc-id:fake:payload +37123 89/<- %ecx 4/r32/esp +37124 $test-add-reg-to-reg:initialize-var1: +37125 # var var1/ecx: (payload var) +37126 68/push 0/imm32/register +37127 68/push 0/imm32/register +37128 68/push 0/imm32/no-stack-offset +37129 68/push 1/imm32/block-depth +37130 51/push-ecx 37131 68/push 0x11/imm32/alloc-id:fake -37132 68/push 0x11/imm32/alloc-id:fake:payload -37133 89/<- %edi 4/r32/esp -37134 $test-add-reg-to-reg:initialize-stmt: -37135 # var stmt/esi: (addr statement) -37136 68/push 0/imm32/next -37137 68/push 0/imm32/next -37138 57/push-edi/outputs -37139 68/push 0x11/imm32/alloc-id:fake -37140 56/push-esi/inouts -37141 68/push 0x11/imm32/alloc-id:fake -37142 68/push 0/imm32/operation -37143 68/push 0/imm32/operation -37144 68/push 1/imm32/tag:stmt1 -37145 89/<- %esi 4/r32/esp -37146 $test-add-reg-to-reg:initialize-stmt-operation: -37147 # stmt->operation = "add" -37148 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37149 (copy-array Heap "add" %eax) -37150 # convert -37151 c7 0/subop/copy *Curr-block-depth 0/imm32 -37152 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37153 (flush _test-output-buffered-file) -37154 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37160 # check output -37161 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") -37162 # . epilogue -37163 89/<- %esp 5/r32/ebp -37164 5d/pop-to-ebp -37165 c3/return -37166 -37167 test-add-reg-to-mem: -37168 # add-to var1 var2/reg -37169 # => -37170 # 01/add-to *(ebp+__) var2 -37171 # -37172 # . prologue -37173 55/push-ebp -37174 89/<- %ebp 4/r32/esp -37175 # setup -37176 (clear-stream _test-output-stream) -37177 (clear-stream $_test-output-buffered-file->buffer) -37178 $test-add-reg-to-mem:initialize-type: -37179 # var type/ecx: (payload type-tree) = int -37180 68/push 0/imm32/right:null -37181 68/push 0/imm32/right:null -37182 68/push 0/imm32/left:unused -37183 68/push 1/imm32/value:int -37184 68/push 1/imm32/is-atom?:true -37185 68/push 0x11/imm32/alloc-id:fake:payload -37186 89/<- %ecx 4/r32/esp -37187 $test-add-reg-to-mem:initialize-var1: -37188 # var var1/ecx: (payload var) -37189 68/push 0/imm32/register -37190 68/push 0/imm32/register -37191 68/push 8/imm32/stack-offset -37192 68/push 1/imm32/block-depth -37193 51/push-ecx -37194 68/push 0x11/imm32/alloc-id:fake -37195 68/push 0/imm32/name -37196 68/push 0/imm32/name -37197 68/push 0x11/imm32/alloc-id:fake:payload -37198 89/<- %ecx 4/r32/esp -37199 $test-add-reg-to-mem:initialize-var1-name: -37200 # var1->name = "var1" -37201 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37202 (copy-array Heap "var1" %eax) -37203 $test-add-reg-to-mem:initialize-var2: -37204 # var var2/edx: (payload var) -37205 68/push 0/imm32/register -37206 68/push 0/imm32/register -37207 68/push 0/imm32/no-stack-offset -37208 68/push 1/imm32/block-depth -37209 ff 6/subop/push *(ecx+0x10) -37210 68/push 0x11/imm32/alloc-id:fake -37211 68/push 0/imm32/name -37212 68/push 0/imm32/name -37213 68/push 0x11/imm32/alloc-id:fake:payload -37214 89/<- %edx 4/r32/esp -37215 $test-add-reg-to-mem:initialize-var2-name: -37216 # var2->name = "var2" -37217 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -37218 (copy-array Heap "var2" %eax) -37219 $test-add-reg-to-mem:initialize-var2-register: -37220 # var2->register = "ecx" -37221 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -37222 (copy-array Heap "ecx" %eax) -37223 $test-add-reg-to-mem:initialize-inouts: -37224 # var inouts/esi: (payload stmt-var) = [var2] -37225 68/push 0/imm32/is-deref:false -37226 68/push 0/imm32/next -37227 68/push 0/imm32/next -37228 52/push-edx/var2 -37229 68/push 0x11/imm32/alloc-id:fake -37230 68/push 0x11/imm32/alloc-id:fake:payload -37231 89/<- %esi 4/r32/esp -37232 # inouts = [var1, var2] -37233 68/push 0/imm32/is-deref:false -37234 56/push-esi/next -37235 68/push 0x11/imm32/alloc-id:fake -37236 51/push-ecx/var1 -37237 68/push 0x11/imm32/alloc-id:fake -37238 68/push 0x11/imm32/alloc-id:fake:payload -37239 89/<- %esi 4/r32/esp -37240 $test-add-reg-to-mem:initialize-stmt: -37241 # var stmt/esi: (addr statement) -37242 68/push 0/imm32/next -37243 68/push 0/imm32/next -37244 68/push 0/imm32/outputs -37245 68/push 0/imm32/outputs -37246 56/push-esi/inouts -37247 68/push 0x11/imm32/alloc-id:fake -37248 68/push 0/imm32/operation -37249 68/push 0/imm32/operation -37250 68/push 1/imm32/tag:stmt1 -37251 89/<- %esi 4/r32/esp -37252 $test-add-reg-to-mem:initialize-stmt-operation: -37253 # stmt->operation = "add-to" -37254 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37255 (copy-array Heap "add-to" %eax) -37256 # convert -37257 c7 0/subop/copy *Curr-block-depth 0/imm32 -37258 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37259 (flush _test-output-buffered-file) -37260 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37266 # check output -37267 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") -37268 # . epilogue -37269 89/<- %esp 5/r32/ebp -37270 5d/pop-to-ebp -37271 c3/return -37272 -37273 test-add-mem-to-reg: -37274 # var1/reg <- add var2 -37275 # => -37276 # 03/add *(ebp+__) var1 -37277 # -37278 # . prologue -37279 55/push-ebp -37280 89/<- %ebp 4/r32/esp -37281 # setup -37282 (clear-stream _test-output-stream) -37283 (clear-stream $_test-output-buffered-file->buffer) -37284 $test-add-mem-to-reg:initialize-type: -37285 # var type/ecx: (payload type-tree) = int -37286 68/push 0/imm32/right:null -37287 68/push 0/imm32/right:null -37288 68/push 0/imm32/left:unused -37289 68/push 1/imm32/value:int -37290 68/push 1/imm32/is-atom?:true -37291 68/push 0x11/imm32/alloc-id:fake:payload -37292 89/<- %ecx 4/r32/esp -37293 $test-add-mem-to-reg:initialize-var: -37294 # var var1/ecx: (payload var) -37295 68/push 0/imm32/register -37296 68/push 0/imm32/register -37297 68/push 0/imm32/no-stack-offset -37298 68/push 1/imm32/block-depth -37299 51/push-ecx -37300 68/push 0x11/imm32/alloc-id:fake -37301 68/push 0/imm32/name -37302 68/push 0/imm32/name -37303 68/push 0x11/imm32/alloc-id:fake:payload -37304 89/<- %ecx 4/r32/esp -37305 $test-add-mem-to-reg:initialize-var-name: -37306 # var1->name = "foo" -37307 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37308 (copy-array Heap "var1" %eax) -37309 $test-add-mem-to-reg:initialize-var-register: -37310 # var1->register = "eax" -37311 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -37312 (copy-array Heap "eax" %eax) -37313 $test-add-mem-to-reg:initialize-var2: -37314 # var var2/edx: (payload var) -37315 68/push 0/imm32/register -37316 68/push 0/imm32/register -37317 68/push 8/imm32/stack-offset -37318 68/push 1/imm32/block-depth -37319 ff 6/subop/push *(ecx+0x10) -37320 68/push 0x11/imm32/alloc-id:fake -37321 68/push 0/imm32/name -37322 68/push 0/imm32/name -37323 68/push 0x11/imm32/alloc-id:fake:payload -37324 89/<- %edx 4/r32/esp -37325 $test-add-mem-to-reg:initialize-var2-name: -37326 # var2->name = "var2" -37327 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -37328 (copy-array Heap "var2" %eax) -37329 $test-add-mem-to-reg:initialize-inouts: -37330 # var inouts/esi: (payload stmt-var) = [var2] -37331 68/push 0/imm32/is-deref:false -37332 68/push 0/imm32/next -37333 68/push 0/imm32/next -37334 52/push-edx/var2 -37335 68/push 0x11/imm32/alloc-id:fake -37336 68/push 0x11/imm32/alloc-id:fake:payload -37337 89/<- %esi 4/r32/esp -37338 $test-add-mem-to-reg:initialize-outputs: -37339 # var outputs/edi: (payload stmt-var) = [var1] -37340 68/push 0/imm32/is-deref:false -37341 68/push 0/imm32/next -37342 68/push 0/imm32/next -37343 51/push-ecx/var1 -37344 68/push 0x11/imm32/alloc-id:fake -37345 68/push 0x11/imm32/alloc-id:fake:payload -37346 89/<- %edi 4/r32/esp -37347 $test-add-mem-to-reg:initialize-stmt: -37348 # var stmt/esi: (addr statement) -37349 68/push 0/imm32/next -37350 68/push 0/imm32/next -37351 57/push-edi/outputs -37352 68/push 0x11/imm32/alloc-id:fake -37353 56/push-esi/inouts -37354 68/push 0x11/imm32/alloc-id:fake -37355 68/push 0/imm32/operation -37356 68/push 0/imm32/operation -37357 68/push 1/imm32/tag:stmt1 -37358 89/<- %esi 4/r32/esp -37359 $test-add-mem-to-reg:initialize-stmt-operation: -37360 # stmt->operation = "add" -37361 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37362 (copy-array Heap "add" %eax) -37363 # convert -37364 c7 0/subop/copy *Curr-block-depth 0/imm32 -37365 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37366 (flush _test-output-buffered-file) -37367 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37373 # check output -37374 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") -37375 # . epilogue -37376 89/<- %esp 5/r32/ebp -37377 5d/pop-to-ebp -37378 c3/return -37379 -37380 test-add-literal-to-eax: -37381 # var1/eax <- add 0x34 -37382 # => -37383 # 05/add-to-eax 0x34/imm32 -37384 # -37385 # . prologue -37386 55/push-ebp -37387 89/<- %ebp 4/r32/esp -37388 # setup -37389 (clear-stream _test-output-stream) -37390 (clear-stream $_test-output-buffered-file->buffer) -37391 $test-add-literal-to-eax:initialize-var-type: -37392 # var type/ecx: (payload type-tree) = int -37393 68/push 0/imm32/right:null -37394 68/push 0/imm32/right:null -37395 68/push 0/imm32/left:unused -37396 68/push 1/imm32/value:int -37397 68/push 1/imm32/is-atom?:true -37398 68/push 0x11/imm32/alloc-id:fake:payload -37399 89/<- %ecx 4/r32/esp -37400 $test-add-literal-to-eax:initialize-var: -37401 # var v/ecx: (payload var) -37402 68/push 0/imm32/register -37403 68/push 0/imm32/register -37404 68/push 0/imm32/no-stack-offset -37405 68/push 1/imm32/block-depth -37406 51/push-ecx -37407 68/push 0x11/imm32/alloc-id:fake -37408 68/push 0/imm32/name -37409 68/push 0/imm32/name -37410 68/push 0x11/imm32/alloc-id:fake:payload -37411 89/<- %ecx 4/r32/esp -37412 $test-add-literal-to-eax:initialize-var-name: -37413 # v->name = "v" -37414 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37415 (copy-array Heap "v" %eax) -37416 $test-add-literal-to-eax:initialize-var-register: -37417 # v->register = "eax" -37418 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -37419 (copy-array Heap "eax" %eax) -37420 $test-add-literal-to-eax:initialize-literal-type: -37421 # var type/edx: (payload type-tree) = literal -37422 68/push 0/imm32/right:null -37423 68/push 0/imm32/right:null -37424 68/push 0/imm32/left:unused -37425 68/push 0/imm32/value:literal -37426 68/push 1/imm32/is-atom?:true -37427 68/push 0x11/imm32/alloc-id:fake:payload -37428 89/<- %edx 4/r32/esp -37429 $test-add-literal-to-eax:initialize-literal: -37430 # var l/edx: (payload var) -37431 68/push 0/imm32/register -37432 68/push 0/imm32/register -37433 68/push 0/imm32/no-stack-offset -37434 68/push 1/imm32/block-depth -37435 52/push-edx -37436 68/push 0x11/imm32/alloc-id:fake -37437 68/push 0/imm32/name -37438 68/push 0/imm32/name -37439 68/push 0x11/imm32/alloc-id:fake:payload -37440 89/<- %edx 4/r32/esp -37441 $test-add-literal-to-eax:initialize-literal-value: -37442 # l->name = "0x34" -37443 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -37444 (copy-array Heap "0x34" %eax) -37445 $test-add-literal-to-eax:initialize-inouts: -37446 # var inouts/esi: (payload stmt-var) = [l] -37447 68/push 0/imm32/is-deref:false -37448 68/push 0/imm32/next -37449 68/push 0/imm32/next -37450 52/push-edx/l -37451 68/push 0x11/imm32/alloc-id:fake -37452 68/push 0x11/imm32/alloc-id:fake:payload -37453 89/<- %esi 4/r32/esp -37454 $test-add-literal-to-eax:initialize-outputs: -37455 # var outputs/edi: (payload stmt-var) = [v] -37456 68/push 0/imm32/is-deref:false -37457 68/push 0/imm32/next -37458 68/push 0/imm32/next -37459 51/push-ecx/v -37460 68/push 0x11/imm32/alloc-id:fake -37461 68/push 0x11/imm32/alloc-id:fake:payload -37462 89/<- %edi 4/r32/esp -37463 $test-add-literal-to-eax:initialize-stmt: -37464 # var stmt/esi: (addr statement) -37465 68/push 0/imm32/next -37466 68/push 0/imm32/next -37467 57/push-edi/outputs -37468 68/push 0x11/imm32/alloc-id:fake -37469 56/push-esi/inouts -37470 68/push 0x11/imm32/alloc-id:fake -37471 68/push 0/imm32/operation -37472 68/push 0/imm32/operation -37473 68/push 1/imm32/tag:stmt1 -37474 89/<- %esi 4/r32/esp -37475 $test-add-literal-to-eax:initialize-stmt-operation: -37476 # stmt->operation = "add" -37477 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37478 (copy-array Heap "add" %eax) -37479 # convert -37480 c7 0/subop/copy *Curr-block-depth 0/imm32 -37481 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37482 (flush _test-output-buffered-file) -37483 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37489 # check output -37490 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") -37491 # . epilogue -37492 89/<- %esp 5/r32/ebp -37493 5d/pop-to-ebp -37494 c3/return -37495 -37496 test-add-literal-to-reg: -37497 # var1/ecx <- add 0x34 -37498 # => -37499 # 81 0/subop/add %ecx 0x34/imm32 -37500 # -37501 # . prologue -37502 55/push-ebp -37503 89/<- %ebp 4/r32/esp -37504 # setup -37505 (clear-stream _test-output-stream) -37506 (clear-stream $_test-output-buffered-file->buffer) -37507 $test-add-literal-to-reg:initialize-var-type: -37508 # var type/ecx: (payload type-tree) = int -37509 68/push 0/imm32/right:null -37510 68/push 0/imm32/right:null -37511 68/push 0/imm32/left:unused -37512 68/push 1/imm32/value:int -37513 68/push 1/imm32/is-atom?:true -37514 68/push 0x11/imm32/alloc-id:fake:payload -37515 89/<- %ecx 4/r32/esp -37516 $test-add-literal-to-reg:initialize-var: -37517 # var v/ecx: (payload var) -37518 68/push 0/imm32/register -37519 68/push 0/imm32/register -37520 68/push 0/imm32/no-stack-offset -37521 68/push 1/imm32/block-depth -37522 51/push-ecx -37523 68/push 0x11/imm32/alloc-id:fake -37524 68/push 0/imm32/name -37525 68/push 0/imm32/name -37526 68/push 0x11/imm32/alloc-id:fake:payload -37527 89/<- %ecx 4/r32/esp -37528 $test-add-literal-to-reg:initialize-var-name: -37529 # v->name = "v" -37530 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37531 (copy-array Heap "v" %eax) -37532 $test-add-literal-to-reg:initialize-var-register: -37533 # v->register = "ecx" -37534 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -37535 (copy-array Heap "ecx" %eax) -37536 $test-add-literal-to-reg:initialize-literal-type: -37537 # var type/edx: (payload type-tree) = literal -37538 68/push 0/imm32/right:null -37539 68/push 0/imm32/right:null -37540 68/push 0/imm32/left:unused -37541 68/push 0/imm32/value:literal -37542 68/push 1/imm32/is-atom?:true -37543 68/push 0x11/imm32/alloc-id:fake:payload -37544 89/<- %edx 4/r32/esp -37545 $test-add-literal-to-reg:initialize-literal: -37546 # var l/edx: (payload var) -37547 68/push 0/imm32/register -37548 68/push 0/imm32/register -37549 68/push 0/imm32/no-stack-offset -37550 68/push 1/imm32/block-depth -37551 52/push-edx -37552 68/push 0x11/imm32/alloc-id:fake -37553 68/push 0/imm32/name -37554 68/push 0/imm32/name -37555 68/push 0x11/imm32/alloc-id:fake:payload -37556 89/<- %edx 4/r32/esp -37557 $test-add-literal-to-reg:initialize-literal-value: -37558 # l->name = "0x34" -37559 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -37560 (copy-array Heap "0x34" %eax) -37561 $test-add-literal-to-reg:initialize-inouts: -37562 # var inouts/esi: (payload stmt-var) = [l] -37563 68/push 0/imm32/is-deref:false -37564 68/push 0/imm32/next -37565 68/push 0/imm32/next -37566 52/push-edx/l -37567 68/push 0x11/imm32/alloc-id:fake -37568 68/push 0x11/imm32/alloc-id:fake:payload -37569 89/<- %esi 4/r32/esp -37570 $test-add-literal-to-reg:initialize-outputs: -37571 # var outputs/edi: (payload stmt-var) = [v] -37572 68/push 0/imm32/is-deref:false -37573 68/push 0/imm32/next -37574 68/push 0/imm32/next -37575 51/push-ecx/v -37576 68/push 0x11/imm32/alloc-id:fake -37577 68/push 0x11/imm32/alloc-id:fake:payload -37578 89/<- %edi 4/r32/esp -37579 $test-add-literal-to-reg:initialize-stmt: -37580 # var stmt/esi: (addr statement) -37581 68/push 0/imm32/next -37582 68/push 0/imm32/next -37583 57/push-edi/outputs -37584 68/push 0x11/imm32/alloc-id:fake -37585 56/push-esi/inouts -37586 68/push 0x11/imm32/alloc-id:fake -37587 68/push 0/imm32/operation -37588 68/push 0/imm32/operation -37589 68/push 1/imm32/tag:stmt1 -37590 89/<- %esi 4/r32/esp -37591 $test-add-literal-to-reg:initialize-stmt-operation: -37592 # stmt->operation = "add" -37593 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37594 (copy-array Heap "add" %eax) -37595 # convert -37596 c7 0/subop/copy *Curr-block-depth 0/imm32 -37597 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37598 (flush _test-output-buffered-file) -37599 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37605 # check output -37606 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") -37607 # . epilogue -37608 89/<- %esp 5/r32/ebp -37609 5d/pop-to-ebp -37610 c3/return -37611 -37612 test-add-literal-to-mem: -37613 # add-to var1, 0x34 -37614 # => -37615 # 81 0/subop/add %eax 0x34/imm32 -37616 # -37617 # . prologue -37618 55/push-ebp -37619 89/<- %ebp 4/r32/esp -37620 # setup -37621 (clear-stream _test-output-stream) -37622 (clear-stream $_test-output-buffered-file->buffer) -37623 $test-add-literal-to-mem:initialize-type: -37624 # var type/ecx: (payload type-tree) = int -37625 68/push 0/imm32/right:null -37626 68/push 0/imm32/right:null -37627 68/push 0/imm32/left:unused -37628 68/push 1/imm32/value:int -37629 68/push 1/imm32/is-atom?:true -37630 68/push 0x11/imm32/alloc-id:fake:payload -37631 89/<- %ecx 4/r32/esp -37632 $test-add-literal-to-mem:initialize-var1: -37633 # var var1/ecx: (payload var) -37634 68/push 0/imm32/register -37635 68/push 0/imm32/register -37636 68/push 8/imm32/stack-offset -37637 68/push 1/imm32/block-depth -37638 51/push-ecx -37639 68/push 0x11/imm32/alloc-id:fake -37640 68/push 0/imm32/name -37641 68/push 0/imm32/name -37642 68/push 0x11/imm32/alloc-id:fake:payload -37643 89/<- %ecx 4/r32/esp -37644 $test-add-literal-to-mem:initialize-var1-name: -37645 # var1->name = "var1" -37646 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37647 (copy-array Heap "var1" %eax) -37648 $test-add-literal-to-mem:initialize-literal-type: -37649 # var type/edx: (payload type-tree) = literal -37650 68/push 0/imm32/right:null -37651 68/push 0/imm32/right:null -37652 68/push 0/imm32/left:unused -37653 68/push 0/imm32/value:literal -37654 68/push 1/imm32/is-atom?:true -37655 68/push 0x11/imm32/alloc-id:fake:payload -37656 89/<- %edx 4/r32/esp -37657 $test-add-literal-to-mem:initialize-literal: -37658 # var l/edx: (payload var) -37659 68/push 0/imm32/register -37660 68/push 0/imm32/register -37661 68/push 0/imm32/no-stack-offset -37662 68/push 1/imm32/block-depth -37663 52/push-edx -37664 68/push 0x11/imm32/alloc-id:fake -37665 68/push 0/imm32/name -37666 68/push 0/imm32/name -37667 68/push 0x11/imm32/alloc-id:fake:payload -37668 89/<- %edx 4/r32/esp -37669 $test-add-literal-to-mem:initialize-literal-value: -37670 # l->name = "0x34" -37671 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -37672 (copy-array Heap "0x34" %eax) -37673 $test-add-literal-to-mem:initialize-inouts: -37674 # var inouts/esi: (payload stmt-var) = [l] -37675 68/push 0/imm32/is-deref:false -37676 68/push 0/imm32/next -37677 68/push 0/imm32/next -37678 52/push-edx/l -37679 68/push 0x11/imm32/alloc-id:fake -37680 68/push 0x11/imm32/alloc-id:fake:payload -37681 89/<- %esi 4/r32/esp -37682 # var inouts = (handle stmt-var) = [var1, var2] -37683 68/push 0/imm32/is-deref:false -37684 56/push-esi/next -37685 68/push 0x11/imm32/alloc-id:fake -37686 51/push-ecx/var1 +37132 68/push 0/imm32/name +37133 68/push 0/imm32/name +37134 68/push 0x11/imm32/alloc-id:fake:payload +37135 89/<- %ecx 4/r32/esp +37136 $test-add-reg-to-reg:initialize-var1-name: +37137 # var1->name = "var1" +37138 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37139 (copy-array Heap "var1" %eax) +37140 $test-add-reg-to-reg:initialize-var1-register: +37141 # var1->register = "eax" +37142 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +37143 (copy-array Heap "eax" %eax) +37144 $test-add-reg-to-reg:initialize-var2: +37145 # var var2/edx: (payload var) +37146 68/push 0/imm32/register +37147 68/push 0/imm32/register +37148 68/push 0/imm32/no-stack-offset +37149 68/push 1/imm32/block-depth +37150 ff 6/subop/push *(ecx+0x10) +37151 68/push 0x11/imm32/alloc-id:fake +37152 68/push 0/imm32/name +37153 68/push 0/imm32/name +37154 68/push 0x11/imm32/alloc-id:fake:payload +37155 89/<- %edx 4/r32/esp +37156 $test-add-reg-to-reg:initialize-var2-name: +37157 # var2->name = "var2" +37158 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +37159 (copy-array Heap "var2" %eax) +37160 $test-add-reg-to-reg:initialize-var2-register: +37161 # var2->register = "ecx" +37162 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +37163 (copy-array Heap "ecx" %eax) +37164 $test-add-reg-to-reg:initialize-inouts: +37165 # var inouts/esi: (payload stmt-var) = [var2] +37166 68/push 0/imm32/is-deref:false +37167 68/push 0/imm32/next +37168 68/push 0/imm32/next +37169 52/push-edx/var2 +37170 68/push 0x11/imm32/alloc-id:fake +37171 68/push 0x11/imm32/alloc-id:fake:payload +37172 89/<- %esi 4/r32/esp +37173 $test-add-reg-to-reg:initialize-outputs: +37174 # var outputs/edi: (payload stmt-var) = [var1] +37175 68/push 0/imm32/is-deref:false +37176 68/push 0/imm32/next +37177 68/push 0/imm32/next +37178 51/push-ecx/var1 +37179 68/push 0x11/imm32/alloc-id:fake +37180 68/push 0x11/imm32/alloc-id:fake:payload +37181 89/<- %edi 4/r32/esp +37182 $test-add-reg-to-reg:initialize-stmt: +37183 # var stmt/esi: (addr statement) +37184 68/push 0/imm32/next +37185 68/push 0/imm32/next +37186 57/push-edi/outputs +37187 68/push 0x11/imm32/alloc-id:fake +37188 56/push-esi/inouts +37189 68/push 0x11/imm32/alloc-id:fake +37190 68/push 0/imm32/operation +37191 68/push 0/imm32/operation +37192 68/push 1/imm32/tag:stmt1 +37193 89/<- %esi 4/r32/esp +37194 $test-add-reg-to-reg:initialize-stmt-operation: +37195 # stmt->operation = "add" +37196 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37197 (copy-array Heap "add" %eax) +37198 # convert +37199 c7 0/subop/copy *Curr-block-depth 0/imm32 +37200 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37201 (flush _test-output-buffered-file) +37202 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37208 # check output +37209 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") +37210 # . epilogue +37211 89/<- %esp 5/r32/ebp +37212 5d/pop-to-ebp +37213 c3/return +37214 +37215 test-add-reg-to-mem: +37216 # add-to var1 var2/reg +37217 # => +37218 # 01/add-to *(ebp+__) var2 +37219 # +37220 # . prologue +37221 55/push-ebp +37222 89/<- %ebp 4/r32/esp +37223 # setup +37224 (clear-stream _test-output-stream) +37225 (clear-stream $_test-output-buffered-file->buffer) +37226 $test-add-reg-to-mem:initialize-type: +37227 # var type/ecx: (payload type-tree) = int +37228 68/push 0/imm32/right:null +37229 68/push 0/imm32/right:null +37230 68/push 0/imm32/left:unused +37231 68/push 1/imm32/value:int +37232 68/push 1/imm32/is-atom?:true +37233 68/push 0x11/imm32/alloc-id:fake:payload +37234 89/<- %ecx 4/r32/esp +37235 $test-add-reg-to-mem:initialize-var1: +37236 # var var1/ecx: (payload var) +37237 68/push 0/imm32/register +37238 68/push 0/imm32/register +37239 68/push 8/imm32/stack-offset +37240 68/push 1/imm32/block-depth +37241 51/push-ecx +37242 68/push 0x11/imm32/alloc-id:fake +37243 68/push 0/imm32/name +37244 68/push 0/imm32/name +37245 68/push 0x11/imm32/alloc-id:fake:payload +37246 89/<- %ecx 4/r32/esp +37247 $test-add-reg-to-mem:initialize-var1-name: +37248 # var1->name = "var1" +37249 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37250 (copy-array Heap "var1" %eax) +37251 $test-add-reg-to-mem:initialize-var2: +37252 # var var2/edx: (payload var) +37253 68/push 0/imm32/register +37254 68/push 0/imm32/register +37255 68/push 0/imm32/no-stack-offset +37256 68/push 1/imm32/block-depth +37257 ff 6/subop/push *(ecx+0x10) +37258 68/push 0x11/imm32/alloc-id:fake +37259 68/push 0/imm32/name +37260 68/push 0/imm32/name +37261 68/push 0x11/imm32/alloc-id:fake:payload +37262 89/<- %edx 4/r32/esp +37263 $test-add-reg-to-mem:initialize-var2-name: +37264 # var2->name = "var2" +37265 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +37266 (copy-array Heap "var2" %eax) +37267 $test-add-reg-to-mem:initialize-var2-register: +37268 # var2->register = "ecx" +37269 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +37270 (copy-array Heap "ecx" %eax) +37271 $test-add-reg-to-mem:initialize-inouts: +37272 # var inouts/esi: (payload stmt-var) = [var2] +37273 68/push 0/imm32/is-deref:false +37274 68/push 0/imm32/next +37275 68/push 0/imm32/next +37276 52/push-edx/var2 +37277 68/push 0x11/imm32/alloc-id:fake +37278 68/push 0x11/imm32/alloc-id:fake:payload +37279 89/<- %esi 4/r32/esp +37280 # inouts = [var1, var2] +37281 68/push 0/imm32/is-deref:false +37282 56/push-esi/next +37283 68/push 0x11/imm32/alloc-id:fake +37284 51/push-ecx/var1 +37285 68/push 0x11/imm32/alloc-id:fake +37286 68/push 0x11/imm32/alloc-id:fake:payload +37287 89/<- %esi 4/r32/esp +37288 $test-add-reg-to-mem:initialize-stmt: +37289 # var stmt/esi: (addr statement) +37290 68/push 0/imm32/next +37291 68/push 0/imm32/next +37292 68/push 0/imm32/outputs +37293 68/push 0/imm32/outputs +37294 56/push-esi/inouts +37295 68/push 0x11/imm32/alloc-id:fake +37296 68/push 0/imm32/operation +37297 68/push 0/imm32/operation +37298 68/push 1/imm32/tag:stmt1 +37299 89/<- %esi 4/r32/esp +37300 $test-add-reg-to-mem:initialize-stmt-operation: +37301 # stmt->operation = "add-to" +37302 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37303 (copy-array Heap "add-to" %eax) +37304 # convert +37305 c7 0/subop/copy *Curr-block-depth 0/imm32 +37306 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37307 (flush _test-output-buffered-file) +37308 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37314 # check output +37315 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") +37316 # . epilogue +37317 89/<- %esp 5/r32/ebp +37318 5d/pop-to-ebp +37319 c3/return +37320 +37321 test-add-mem-to-reg: +37322 # var1/reg <- add var2 +37323 # => +37324 # 03/add *(ebp+__) var1 +37325 # +37326 # . prologue +37327 55/push-ebp +37328 89/<- %ebp 4/r32/esp +37329 # setup +37330 (clear-stream _test-output-stream) +37331 (clear-stream $_test-output-buffered-file->buffer) +37332 $test-add-mem-to-reg:initialize-type: +37333 # var type/ecx: (payload type-tree) = int +37334 68/push 0/imm32/right:null +37335 68/push 0/imm32/right:null +37336 68/push 0/imm32/left:unused +37337 68/push 1/imm32/value:int +37338 68/push 1/imm32/is-atom?:true +37339 68/push 0x11/imm32/alloc-id:fake:payload +37340 89/<- %ecx 4/r32/esp +37341 $test-add-mem-to-reg:initialize-var: +37342 # var var1/ecx: (payload var) +37343 68/push 0/imm32/register +37344 68/push 0/imm32/register +37345 68/push 0/imm32/no-stack-offset +37346 68/push 1/imm32/block-depth +37347 51/push-ecx +37348 68/push 0x11/imm32/alloc-id:fake +37349 68/push 0/imm32/name +37350 68/push 0/imm32/name +37351 68/push 0x11/imm32/alloc-id:fake:payload +37352 89/<- %ecx 4/r32/esp +37353 $test-add-mem-to-reg:initialize-var-name: +37354 # var1->name = "foo" +37355 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37356 (copy-array Heap "var1" %eax) +37357 $test-add-mem-to-reg:initialize-var-register: +37358 # var1->register = "eax" +37359 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +37360 (copy-array Heap "eax" %eax) +37361 $test-add-mem-to-reg:initialize-var2: +37362 # var var2/edx: (payload var) +37363 68/push 0/imm32/register +37364 68/push 0/imm32/register +37365 68/push 8/imm32/stack-offset +37366 68/push 1/imm32/block-depth +37367 ff 6/subop/push *(ecx+0x10) +37368 68/push 0x11/imm32/alloc-id:fake +37369 68/push 0/imm32/name +37370 68/push 0/imm32/name +37371 68/push 0x11/imm32/alloc-id:fake:payload +37372 89/<- %edx 4/r32/esp +37373 $test-add-mem-to-reg:initialize-var2-name: +37374 # var2->name = "var2" +37375 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +37376 (copy-array Heap "var2" %eax) +37377 $test-add-mem-to-reg:initialize-inouts: +37378 # var inouts/esi: (payload stmt-var) = [var2] +37379 68/push 0/imm32/is-deref:false +37380 68/push 0/imm32/next +37381 68/push 0/imm32/next +37382 52/push-edx/var2 +37383 68/push 0x11/imm32/alloc-id:fake +37384 68/push 0x11/imm32/alloc-id:fake:payload +37385 89/<- %esi 4/r32/esp +37386 $test-add-mem-to-reg:initialize-outputs: +37387 # var outputs/edi: (payload stmt-var) = [var1] +37388 68/push 0/imm32/is-deref:false +37389 68/push 0/imm32/next +37390 68/push 0/imm32/next +37391 51/push-ecx/var1 +37392 68/push 0x11/imm32/alloc-id:fake +37393 68/push 0x11/imm32/alloc-id:fake:payload +37394 89/<- %edi 4/r32/esp +37395 $test-add-mem-to-reg:initialize-stmt: +37396 # var stmt/esi: (addr statement) +37397 68/push 0/imm32/next +37398 68/push 0/imm32/next +37399 57/push-edi/outputs +37400 68/push 0x11/imm32/alloc-id:fake +37401 56/push-esi/inouts +37402 68/push 0x11/imm32/alloc-id:fake +37403 68/push 0/imm32/operation +37404 68/push 0/imm32/operation +37405 68/push 1/imm32/tag:stmt1 +37406 89/<- %esi 4/r32/esp +37407 $test-add-mem-to-reg:initialize-stmt-operation: +37408 # stmt->operation = "add" +37409 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37410 (copy-array Heap "add" %eax) +37411 # convert +37412 c7 0/subop/copy *Curr-block-depth 0/imm32 +37413 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37414 (flush _test-output-buffered-file) +37415 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37421 # check output +37422 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") +37423 # . epilogue +37424 89/<- %esp 5/r32/ebp +37425 5d/pop-to-ebp +37426 c3/return +37427 +37428 test-add-literal-to-eax: +37429 # var1/eax <- add 0x34 +37430 # => +37431 # 05/add-to-eax 0x34/imm32 +37432 # +37433 # . prologue +37434 55/push-ebp +37435 89/<- %ebp 4/r32/esp +37436 # setup +37437 (clear-stream _test-output-stream) +37438 (clear-stream $_test-output-buffered-file->buffer) +37439 $test-add-literal-to-eax:initialize-var-type: +37440 # var type/ecx: (payload type-tree) = int +37441 68/push 0/imm32/right:null +37442 68/push 0/imm32/right:null +37443 68/push 0/imm32/left:unused +37444 68/push 1/imm32/value:int +37445 68/push 1/imm32/is-atom?:true +37446 68/push 0x11/imm32/alloc-id:fake:payload +37447 89/<- %ecx 4/r32/esp +37448 $test-add-literal-to-eax:initialize-var: +37449 # var v/ecx: (payload var) +37450 68/push 0/imm32/register +37451 68/push 0/imm32/register +37452 68/push 0/imm32/no-stack-offset +37453 68/push 1/imm32/block-depth +37454 51/push-ecx +37455 68/push 0x11/imm32/alloc-id:fake +37456 68/push 0/imm32/name +37457 68/push 0/imm32/name +37458 68/push 0x11/imm32/alloc-id:fake:payload +37459 89/<- %ecx 4/r32/esp +37460 $test-add-literal-to-eax:initialize-var-name: +37461 # v->name = "v" +37462 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37463 (copy-array Heap "v" %eax) +37464 $test-add-literal-to-eax:initialize-var-register: +37465 # v->register = "eax" +37466 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +37467 (copy-array Heap "eax" %eax) +37468 $test-add-literal-to-eax:initialize-literal-type: +37469 # var type/edx: (payload type-tree) = literal +37470 68/push 0/imm32/right:null +37471 68/push 0/imm32/right:null +37472 68/push 0/imm32/left:unused +37473 68/push 0/imm32/value:literal +37474 68/push 1/imm32/is-atom?:true +37475 68/push 0x11/imm32/alloc-id:fake:payload +37476 89/<- %edx 4/r32/esp +37477 $test-add-literal-to-eax:initialize-literal: +37478 # var l/edx: (payload var) +37479 68/push 0/imm32/register +37480 68/push 0/imm32/register +37481 68/push 0/imm32/no-stack-offset +37482 68/push 1/imm32/block-depth +37483 52/push-edx +37484 68/push 0x11/imm32/alloc-id:fake +37485 68/push 0/imm32/name +37486 68/push 0/imm32/name +37487 68/push 0x11/imm32/alloc-id:fake:payload +37488 89/<- %edx 4/r32/esp +37489 $test-add-literal-to-eax:initialize-literal-value: +37490 # l->name = "0x34" +37491 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +37492 (copy-array Heap "0x34" %eax) +37493 $test-add-literal-to-eax:initialize-inouts: +37494 # var inouts/esi: (payload stmt-var) = [l] +37495 68/push 0/imm32/is-deref:false +37496 68/push 0/imm32/next +37497 68/push 0/imm32/next +37498 52/push-edx/l +37499 68/push 0x11/imm32/alloc-id:fake +37500 68/push 0x11/imm32/alloc-id:fake:payload +37501 89/<- %esi 4/r32/esp +37502 $test-add-literal-to-eax:initialize-outputs: +37503 # var outputs/edi: (payload stmt-var) = [v] +37504 68/push 0/imm32/is-deref:false +37505 68/push 0/imm32/next +37506 68/push 0/imm32/next +37507 51/push-ecx/v +37508 68/push 0x11/imm32/alloc-id:fake +37509 68/push 0x11/imm32/alloc-id:fake:payload +37510 89/<- %edi 4/r32/esp +37511 $test-add-literal-to-eax:initialize-stmt: +37512 # var stmt/esi: (addr statement) +37513 68/push 0/imm32/next +37514 68/push 0/imm32/next +37515 57/push-edi/outputs +37516 68/push 0x11/imm32/alloc-id:fake +37517 56/push-esi/inouts +37518 68/push 0x11/imm32/alloc-id:fake +37519 68/push 0/imm32/operation +37520 68/push 0/imm32/operation +37521 68/push 1/imm32/tag:stmt1 +37522 89/<- %esi 4/r32/esp +37523 $test-add-literal-to-eax:initialize-stmt-operation: +37524 # stmt->operation = "add" +37525 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37526 (copy-array Heap "add" %eax) +37527 # convert +37528 c7 0/subop/copy *Curr-block-depth 0/imm32 +37529 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37530 (flush _test-output-buffered-file) +37531 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37537 # check output +37538 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") +37539 # . epilogue +37540 89/<- %esp 5/r32/ebp +37541 5d/pop-to-ebp +37542 c3/return +37543 +37544 test-add-literal-to-reg: +37545 # var1/ecx <- add 0x34 +37546 # => +37547 # 81 0/subop/add %ecx 0x34/imm32 +37548 # +37549 # . prologue +37550 55/push-ebp +37551 89/<- %ebp 4/r32/esp +37552 # setup +37553 (clear-stream _test-output-stream) +37554 (clear-stream $_test-output-buffered-file->buffer) +37555 $test-add-literal-to-reg:initialize-var-type: +37556 # var type/ecx: (payload type-tree) = int +37557 68/push 0/imm32/right:null +37558 68/push 0/imm32/right:null +37559 68/push 0/imm32/left:unused +37560 68/push 1/imm32/value:int +37561 68/push 1/imm32/is-atom?:true +37562 68/push 0x11/imm32/alloc-id:fake:payload +37563 89/<- %ecx 4/r32/esp +37564 $test-add-literal-to-reg:initialize-var: +37565 # var v/ecx: (payload var) +37566 68/push 0/imm32/register +37567 68/push 0/imm32/register +37568 68/push 0/imm32/no-stack-offset +37569 68/push 1/imm32/block-depth +37570 51/push-ecx +37571 68/push 0x11/imm32/alloc-id:fake +37572 68/push 0/imm32/name +37573 68/push 0/imm32/name +37574 68/push 0x11/imm32/alloc-id:fake:payload +37575 89/<- %ecx 4/r32/esp +37576 $test-add-literal-to-reg:initialize-var-name: +37577 # v->name = "v" +37578 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37579 (copy-array Heap "v" %eax) +37580 $test-add-literal-to-reg:initialize-var-register: +37581 # v->register = "ecx" +37582 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +37583 (copy-array Heap "ecx" %eax) +37584 $test-add-literal-to-reg:initialize-literal-type: +37585 # var type/edx: (payload type-tree) = literal +37586 68/push 0/imm32/right:null +37587 68/push 0/imm32/right:null +37588 68/push 0/imm32/left:unused +37589 68/push 0/imm32/value:literal +37590 68/push 1/imm32/is-atom?:true +37591 68/push 0x11/imm32/alloc-id:fake:payload +37592 89/<- %edx 4/r32/esp +37593 $test-add-literal-to-reg:initialize-literal: +37594 # var l/edx: (payload var) +37595 68/push 0/imm32/register +37596 68/push 0/imm32/register +37597 68/push 0/imm32/no-stack-offset +37598 68/push 1/imm32/block-depth +37599 52/push-edx +37600 68/push 0x11/imm32/alloc-id:fake +37601 68/push 0/imm32/name +37602 68/push 0/imm32/name +37603 68/push 0x11/imm32/alloc-id:fake:payload +37604 89/<- %edx 4/r32/esp +37605 $test-add-literal-to-reg:initialize-literal-value: +37606 # l->name = "0x34" +37607 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +37608 (copy-array Heap "0x34" %eax) +37609 $test-add-literal-to-reg:initialize-inouts: +37610 # var inouts/esi: (payload stmt-var) = [l] +37611 68/push 0/imm32/is-deref:false +37612 68/push 0/imm32/next +37613 68/push 0/imm32/next +37614 52/push-edx/l +37615 68/push 0x11/imm32/alloc-id:fake +37616 68/push 0x11/imm32/alloc-id:fake:payload +37617 89/<- %esi 4/r32/esp +37618 $test-add-literal-to-reg:initialize-outputs: +37619 # var outputs/edi: (payload stmt-var) = [v] +37620 68/push 0/imm32/is-deref:false +37621 68/push 0/imm32/next +37622 68/push 0/imm32/next +37623 51/push-ecx/v +37624 68/push 0x11/imm32/alloc-id:fake +37625 68/push 0x11/imm32/alloc-id:fake:payload +37626 89/<- %edi 4/r32/esp +37627 $test-add-literal-to-reg:initialize-stmt: +37628 # var stmt/esi: (addr statement) +37629 68/push 0/imm32/next +37630 68/push 0/imm32/next +37631 57/push-edi/outputs +37632 68/push 0x11/imm32/alloc-id:fake +37633 56/push-esi/inouts +37634 68/push 0x11/imm32/alloc-id:fake +37635 68/push 0/imm32/operation +37636 68/push 0/imm32/operation +37637 68/push 1/imm32/tag:stmt1 +37638 89/<- %esi 4/r32/esp +37639 $test-add-literal-to-reg:initialize-stmt-operation: +37640 # stmt->operation = "add" +37641 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37642 (copy-array Heap "add" %eax) +37643 # convert +37644 c7 0/subop/copy *Curr-block-depth 0/imm32 +37645 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37646 (flush _test-output-buffered-file) +37647 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37653 # check output +37654 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") +37655 # . epilogue +37656 89/<- %esp 5/r32/ebp +37657 5d/pop-to-ebp +37658 c3/return +37659 +37660 test-add-literal-to-mem: +37661 # add-to var1, 0x34 +37662 # => +37663 # 81 0/subop/add %eax 0x34/imm32 +37664 # +37665 # . prologue +37666 55/push-ebp +37667 89/<- %ebp 4/r32/esp +37668 # setup +37669 (clear-stream _test-output-stream) +37670 (clear-stream $_test-output-buffered-file->buffer) +37671 $test-add-literal-to-mem:initialize-type: +37672 # var type/ecx: (payload type-tree) = int +37673 68/push 0/imm32/right:null +37674 68/push 0/imm32/right:null +37675 68/push 0/imm32/left:unused +37676 68/push 1/imm32/value:int +37677 68/push 1/imm32/is-atom?:true +37678 68/push 0x11/imm32/alloc-id:fake:payload +37679 89/<- %ecx 4/r32/esp +37680 $test-add-literal-to-mem:initialize-var1: +37681 # var var1/ecx: (payload var) +37682 68/push 0/imm32/register +37683 68/push 0/imm32/register +37684 68/push 8/imm32/stack-offset +37685 68/push 1/imm32/block-depth +37686 51/push-ecx 37687 68/push 0x11/imm32/alloc-id:fake -37688 68/push 0x11/imm32/alloc-id:fake:payload -37689 89/<- %esi 4/r32/esp -37690 $test-add-literal-to-mem:initialize-stmt: -37691 # var stmt/esi: (addr statement) -37692 68/push 0/imm32/next -37693 68/push 0/imm32/next -37694 68/push 0/imm32/outputs -37695 68/push 0/imm32/outputs -37696 56/push-esi/inouts -37697 68/push 0x11/imm32/alloc-id:fake -37698 68/push 0/imm32/operation -37699 68/push 0/imm32/operation -37700 68/push 1/imm32/tag:stmt1 -37701 89/<- %esi 4/r32/esp -37702 $test-add-literal-to-mem:initialize-stmt-operation: -37703 # stmt->operation = "add-to" -37704 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37705 (copy-array Heap "add-to" %eax) -37706 # convert -37707 c7 0/subop/copy *Curr-block-depth 0/imm32 -37708 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37709 (flush _test-output-buffered-file) -37710 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37716 # check output -37717 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") -37718 # . epilogue -37719 89/<- %esp 5/r32/ebp -37720 5d/pop-to-ebp -37721 c3/return -37722 -37723 test-shift-reg-by-literal: -37724 # var1/ecx <- shift-left 2 -37725 # => -37726 # c1/shift 4/subop/left %ecx 2/imm8 -37727 # -37728 # . prologue -37729 55/push-ebp -37730 89/<- %ebp 4/r32/esp -37731 # setup -37732 (clear-stream _test-output-stream) -37733 (clear-stream $_test-output-buffered-file->buffer) -37734 $test-shift-reg-by-literal:initialize-var-type: -37735 # var type/ecx: (payload type-tree) = int -37736 68/push 0/imm32/right:null -37737 68/push 0/imm32/right:null -37738 68/push 0/imm32/left:unused -37739 68/push 1/imm32/value:int -37740 68/push 1/imm32/is-atom?:true -37741 68/push 0x11/imm32/alloc-id:fake:payload -37742 89/<- %ecx 4/r32/esp -37743 $test-shift-reg-by-literal:initialize-var: -37744 # var v/ecx: (payload var) -37745 68/push 0/imm32/register -37746 68/push 0/imm32/register -37747 68/push 0/imm32/no-stack-offset -37748 68/push 1/imm32/block-depth -37749 51/push-ecx -37750 68/push 0x11/imm32/alloc-id:fake -37751 68/push 0/imm32/name -37752 68/push 0/imm32/name -37753 68/push 0x11/imm32/alloc-id:fake:payload -37754 89/<- %ecx 4/r32/esp -37755 $test-shift-reg-by-literal:initialize-var-name: -37756 # v->name = "v" -37757 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37758 (copy-array Heap "v" %eax) -37759 $test-shift-reg-by-literal:initialize-var-register: -37760 # v->register = "ecx" -37761 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -37762 (copy-array Heap "ecx" %eax) -37763 $test-shift-reg-by-literal:initialize-literal-type: -37764 # var type/edx: (payload type-tree) = literal -37765 68/push 0/imm32/right:null -37766 68/push 0/imm32/right:null -37767 68/push 0/imm32/left:unused -37768 68/push 0/imm32/value:literal -37769 68/push 1/imm32/is-atom?:true -37770 68/push 0x11/imm32/alloc-id:fake:payload -37771 89/<- %edx 4/r32/esp -37772 $test-shift-reg-by-literal:initialize-literal: -37773 # var l/edx: (payload var) -37774 68/push 0/imm32/register -37775 68/push 0/imm32/register -37776 68/push 0/imm32/no-stack-offset -37777 68/push 1/imm32/block-depth -37778 52/push-edx -37779 68/push 0x11/imm32/alloc-id:fake -37780 68/push 0/imm32/name -37781 68/push 0/imm32/name -37782 68/push 0x11/imm32/alloc-id:fake:payload -37783 89/<- %edx 4/r32/esp -37784 $test-shift-reg-by-literal:initialize-literal-value: -37785 # l->name = "2" -37786 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -37787 (copy-array Heap "2" %eax) -37788 $test-shift-reg-by-literal:initialize-inouts: -37789 # var inouts/esi: (payload stmt-var) = [l] -37790 68/push 0/imm32/is-deref:false -37791 68/push 0/imm32/next -37792 68/push 0/imm32/next -37793 52/push-edx/l -37794 68/push 0x11/imm32/alloc-id:fake -37795 68/push 0x11/imm32/alloc-id:fake:payload -37796 89/<- %esi 4/r32/esp -37797 $test-shift-reg-by-literal:initialize-outputs: -37798 # var outputs/edi: (payload stmt-var) = [v] -37799 68/push 0/imm32/is-deref:false -37800 68/push 0/imm32/next -37801 68/push 0/imm32/next -37802 51/push-ecx/v -37803 68/push 0x11/imm32/alloc-id:fake -37804 68/push 0x11/imm32/alloc-id:fake:payload -37805 89/<- %edi 4/r32/esp -37806 $test-shift-reg-by-literal:initialize-stmt: -37807 # var stmt/esi: (addr statement) -37808 68/push 0/imm32/next -37809 68/push 0/imm32/next -37810 57/push-edi/outputs -37811 68/push 0x11/imm32/alloc-id:fake -37812 56/push-esi/inouts -37813 68/push 0x11/imm32/alloc-id:fake -37814 68/push 0/imm32/operation -37815 68/push 0/imm32/operation -37816 68/push 1/imm32/tag:stmt1 -37817 89/<- %esi 4/r32/esp -37818 $test-shift-reg-by-literal:initialize-stmt-operation: -37819 # stmt->operation = "shift-left" -37820 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37821 (copy-array Heap "shift-left" %eax) -37822 # convert -37823 c7 0/subop/copy *Curr-block-depth 0/imm32 -37824 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37825 (flush _test-output-buffered-file) -37826 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37832 # check output -37833 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left %ecx 2/imm8" "F - test-shift-reg-by-literal") -37834 # . epilogue -37835 89/<- %esp 5/r32/ebp -37836 5d/pop-to-ebp -37837 c3/return -37838 -37839 test-shift-mem-by-literal: -37840 # shift-left var 3 -37841 # => -37842 # c1/shift 4/subop/left *(ebp+8) 3/imm8 -37843 # -37844 # . prologue -37845 55/push-ebp -37846 89/<- %ebp 4/r32/esp -37847 # setup -37848 (clear-stream _test-output-stream) -37849 (clear-stream $_test-output-buffered-file->buffer) -37850 $test-shift-mem-by-literal:initialize-type: -37851 # var type/ecx: (payload type-tree) = int -37852 68/push 0/imm32/right:null -37853 68/push 0/imm32/right:null -37854 68/push 0/imm32/left:unused -37855 68/push 1/imm32/value:int -37856 68/push 1/imm32/is-atom?:true -37857 68/push 0x11/imm32/alloc-id:fake:payload -37858 89/<- %ecx 4/r32/esp -37859 $test-shift-mem-by-literal:initialize-var1: -37860 # var var1/ecx: (payload var) -37861 68/push 0/imm32/register -37862 68/push 0/imm32/register -37863 68/push 8/imm32/stack-offset -37864 68/push 1/imm32/block-depth -37865 51/push-ecx -37866 68/push 0x11/imm32/alloc-id:fake -37867 68/push 0/imm32/name -37868 68/push 0/imm32/name -37869 68/push 0x11/imm32/alloc-id:fake:payload -37870 89/<- %ecx 4/r32/esp -37871 $test-shift-mem-by-literal:initialize-var1-name: -37872 # var1->name = "var1" -37873 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37874 (copy-array Heap "var1" %eax) -37875 $test-shift-mem-by-literal:initialize-literal-type: -37876 # var type/edx: (payload type-tree) = literal -37877 68/push 0/imm32/right:null -37878 68/push 0/imm32/right:null -37879 68/push 0/imm32/left:unused -37880 68/push 0/imm32/value:literal -37881 68/push 1/imm32/is-atom?:true -37882 68/push 0x11/imm32/alloc-id:fake:payload -37883 89/<- %edx 4/r32/esp -37884 $test-shift-mem-by-literal:initialize-literal: -37885 # var l/edx: (payload var) -37886 68/push 0/imm32/register -37887 68/push 0/imm32/register -37888 68/push 0/imm32/no-stack-offset -37889 68/push 1/imm32/block-depth -37890 52/push-edx -37891 68/push 0x11/imm32/alloc-id:fake -37892 68/push 0/imm32/name -37893 68/push 0/imm32/name -37894 68/push 0x11/imm32/alloc-id:fake:payload -37895 89/<- %edx 4/r32/esp -37896 $test-shift-mem-by-literal:initialize-literal-value: -37897 # l->name = "3" -37898 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -37899 (copy-array Heap "3" %eax) -37900 $test-shift-mem-by-literal:initialize-inouts: -37901 # var inouts/esi: (payload stmt-var) = [l] -37902 68/push 0/imm32/is-deref:false -37903 68/push 0/imm32/next -37904 68/push 0/imm32/next -37905 52/push-edx/l -37906 68/push 0x11/imm32/alloc-id:fake -37907 68/push 0x11/imm32/alloc-id:fake:payload -37908 89/<- %esi 4/r32/esp -37909 # var inouts = (handle stmt-var) = [var1, var2] -37910 68/push 0/imm32/is-deref:false -37911 56/push-esi/next -37912 68/push 0x11/imm32/alloc-id:fake -37913 51/push-ecx/var1 +37688 68/push 0/imm32/name +37689 68/push 0/imm32/name +37690 68/push 0x11/imm32/alloc-id:fake:payload +37691 89/<- %ecx 4/r32/esp +37692 $test-add-literal-to-mem:initialize-var1-name: +37693 # var1->name = "var1" +37694 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37695 (copy-array Heap "var1" %eax) +37696 $test-add-literal-to-mem:initialize-literal-type: +37697 # var type/edx: (payload type-tree) = literal +37698 68/push 0/imm32/right:null +37699 68/push 0/imm32/right:null +37700 68/push 0/imm32/left:unused +37701 68/push 0/imm32/value:literal +37702 68/push 1/imm32/is-atom?:true +37703 68/push 0x11/imm32/alloc-id:fake:payload +37704 89/<- %edx 4/r32/esp +37705 $test-add-literal-to-mem:initialize-literal: +37706 # var l/edx: (payload var) +37707 68/push 0/imm32/register +37708 68/push 0/imm32/register +37709 68/push 0/imm32/no-stack-offset +37710 68/push 1/imm32/block-depth +37711 52/push-edx +37712 68/push 0x11/imm32/alloc-id:fake +37713 68/push 0/imm32/name +37714 68/push 0/imm32/name +37715 68/push 0x11/imm32/alloc-id:fake:payload +37716 89/<- %edx 4/r32/esp +37717 $test-add-literal-to-mem:initialize-literal-value: +37718 # l->name = "0x34" +37719 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +37720 (copy-array Heap "0x34" %eax) +37721 $test-add-literal-to-mem:initialize-inouts: +37722 # var inouts/esi: (payload stmt-var) = [l] +37723 68/push 0/imm32/is-deref:false +37724 68/push 0/imm32/next +37725 68/push 0/imm32/next +37726 52/push-edx/l +37727 68/push 0x11/imm32/alloc-id:fake +37728 68/push 0x11/imm32/alloc-id:fake:payload +37729 89/<- %esi 4/r32/esp +37730 # var inouts = (handle stmt-var) = [var1, var2] +37731 68/push 0/imm32/is-deref:false +37732 56/push-esi/next +37733 68/push 0x11/imm32/alloc-id:fake +37734 51/push-ecx/var1 +37735 68/push 0x11/imm32/alloc-id:fake +37736 68/push 0x11/imm32/alloc-id:fake:payload +37737 89/<- %esi 4/r32/esp +37738 $test-add-literal-to-mem:initialize-stmt: +37739 # var stmt/esi: (addr statement) +37740 68/push 0/imm32/next +37741 68/push 0/imm32/next +37742 68/push 0/imm32/outputs +37743 68/push 0/imm32/outputs +37744 56/push-esi/inouts +37745 68/push 0x11/imm32/alloc-id:fake +37746 68/push 0/imm32/operation +37747 68/push 0/imm32/operation +37748 68/push 1/imm32/tag:stmt1 +37749 89/<- %esi 4/r32/esp +37750 $test-add-literal-to-mem:initialize-stmt-operation: +37751 # stmt->operation = "add-to" +37752 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37753 (copy-array Heap "add-to" %eax) +37754 # convert +37755 c7 0/subop/copy *Curr-block-depth 0/imm32 +37756 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37757 (flush _test-output-buffered-file) +37758 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37764 # check output +37765 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") +37766 # . epilogue +37767 89/<- %esp 5/r32/ebp +37768 5d/pop-to-ebp +37769 c3/return +37770 +37771 test-shift-reg-by-literal: +37772 # var1/ecx <- shift-left 2 +37773 # => +37774 # c1/shift 4/subop/left %ecx 2/imm8 +37775 # +37776 # . prologue +37777 55/push-ebp +37778 89/<- %ebp 4/r32/esp +37779 # setup +37780 (clear-stream _test-output-stream) +37781 (clear-stream $_test-output-buffered-file->buffer) +37782 $test-shift-reg-by-literal:initialize-var-type: +37783 # var type/ecx: (payload type-tree) = int +37784 68/push 0/imm32/right:null +37785 68/push 0/imm32/right:null +37786 68/push 0/imm32/left:unused +37787 68/push 1/imm32/value:int +37788 68/push 1/imm32/is-atom?:true +37789 68/push 0x11/imm32/alloc-id:fake:payload +37790 89/<- %ecx 4/r32/esp +37791 $test-shift-reg-by-literal:initialize-var: +37792 # var v/ecx: (payload var) +37793 68/push 0/imm32/register +37794 68/push 0/imm32/register +37795 68/push 0/imm32/no-stack-offset +37796 68/push 1/imm32/block-depth +37797 51/push-ecx +37798 68/push 0x11/imm32/alloc-id:fake +37799 68/push 0/imm32/name +37800 68/push 0/imm32/name +37801 68/push 0x11/imm32/alloc-id:fake:payload +37802 89/<- %ecx 4/r32/esp +37803 $test-shift-reg-by-literal:initialize-var-name: +37804 # v->name = "v" +37805 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37806 (copy-array Heap "v" %eax) +37807 $test-shift-reg-by-literal:initialize-var-register: +37808 # v->register = "ecx" +37809 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +37810 (copy-array Heap "ecx" %eax) +37811 $test-shift-reg-by-literal:initialize-literal-type: +37812 # var type/edx: (payload type-tree) = literal +37813 68/push 0/imm32/right:null +37814 68/push 0/imm32/right:null +37815 68/push 0/imm32/left:unused +37816 68/push 0/imm32/value:literal +37817 68/push 1/imm32/is-atom?:true +37818 68/push 0x11/imm32/alloc-id:fake:payload +37819 89/<- %edx 4/r32/esp +37820 $test-shift-reg-by-literal:initialize-literal: +37821 # var l/edx: (payload var) +37822 68/push 0/imm32/register +37823 68/push 0/imm32/register +37824 68/push 0/imm32/no-stack-offset +37825 68/push 1/imm32/block-depth +37826 52/push-edx +37827 68/push 0x11/imm32/alloc-id:fake +37828 68/push 0/imm32/name +37829 68/push 0/imm32/name +37830 68/push 0x11/imm32/alloc-id:fake:payload +37831 89/<- %edx 4/r32/esp +37832 $test-shift-reg-by-literal:initialize-literal-value: +37833 # l->name = "2" +37834 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +37835 (copy-array Heap "2" %eax) +37836 $test-shift-reg-by-literal:initialize-inouts: +37837 # var inouts/esi: (payload stmt-var) = [l] +37838 68/push 0/imm32/is-deref:false +37839 68/push 0/imm32/next +37840 68/push 0/imm32/next +37841 52/push-edx/l +37842 68/push 0x11/imm32/alloc-id:fake +37843 68/push 0x11/imm32/alloc-id:fake:payload +37844 89/<- %esi 4/r32/esp +37845 $test-shift-reg-by-literal:initialize-outputs: +37846 # var outputs/edi: (payload stmt-var) = [v] +37847 68/push 0/imm32/is-deref:false +37848 68/push 0/imm32/next +37849 68/push 0/imm32/next +37850 51/push-ecx/v +37851 68/push 0x11/imm32/alloc-id:fake +37852 68/push 0x11/imm32/alloc-id:fake:payload +37853 89/<- %edi 4/r32/esp +37854 $test-shift-reg-by-literal:initialize-stmt: +37855 # var stmt/esi: (addr statement) +37856 68/push 0/imm32/next +37857 68/push 0/imm32/next +37858 57/push-edi/outputs +37859 68/push 0x11/imm32/alloc-id:fake +37860 56/push-esi/inouts +37861 68/push 0x11/imm32/alloc-id:fake +37862 68/push 0/imm32/operation +37863 68/push 0/imm32/operation +37864 68/push 1/imm32/tag:stmt1 +37865 89/<- %esi 4/r32/esp +37866 $test-shift-reg-by-literal:initialize-stmt-operation: +37867 # stmt->operation = "shift-left" +37868 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37869 (copy-array Heap "shift-left" %eax) +37870 # convert +37871 c7 0/subop/copy *Curr-block-depth 0/imm32 +37872 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37873 (flush _test-output-buffered-file) +37874 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37880 # check output +37881 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left %ecx 2/imm8" "F - test-shift-reg-by-literal") +37882 # . epilogue +37883 89/<- %esp 5/r32/ebp +37884 5d/pop-to-ebp +37885 c3/return +37886 +37887 test-shift-mem-by-literal: +37888 # shift-left var 3 +37889 # => +37890 # c1/shift 4/subop/left *(ebp+8) 3/imm8 +37891 # +37892 # . prologue +37893 55/push-ebp +37894 89/<- %ebp 4/r32/esp +37895 # setup +37896 (clear-stream _test-output-stream) +37897 (clear-stream $_test-output-buffered-file->buffer) +37898 $test-shift-mem-by-literal:initialize-type: +37899 # var type/ecx: (payload type-tree) = int +37900 68/push 0/imm32/right:null +37901 68/push 0/imm32/right:null +37902 68/push 0/imm32/left:unused +37903 68/push 1/imm32/value:int +37904 68/push 1/imm32/is-atom?:true +37905 68/push 0x11/imm32/alloc-id:fake:payload +37906 89/<- %ecx 4/r32/esp +37907 $test-shift-mem-by-literal:initialize-var1: +37908 # var var1/ecx: (payload var) +37909 68/push 0/imm32/register +37910 68/push 0/imm32/register +37911 68/push 8/imm32/stack-offset +37912 68/push 1/imm32/block-depth +37913 51/push-ecx 37914 68/push 0x11/imm32/alloc-id:fake -37915 68/push 0x11/imm32/alloc-id:fake:payload -37916 89/<- %esi 4/r32/esp -37917 $test-shift-mem-by-literal:initialize-stmt: -37918 # var stmt/esi: (addr statement) -37919 68/push 0/imm32/next -37920 68/push 0/imm32/next -37921 68/push 0/imm32/outputs -37922 68/push 0/imm32/outputs -37923 56/push-esi/inouts -37924 68/push 0x11/imm32/alloc-id:fake -37925 68/push 0/imm32/operation -37926 68/push 0/imm32/operation -37927 68/push 1/imm32/tag:stmt1 -37928 89/<- %esi 4/r32/esp -37929 $test-shift-mem-by-literal:initialize-stmt-operation: -37930 # stmt->operation = "shift-left" -37931 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -37932 (copy-array Heap "shift-left" %eax) -37933 # convert -37934 c7 0/subop/copy *Curr-block-depth 0/imm32 -37935 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -37936 (flush _test-output-buffered-file) -37937 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -37943 # check output -37944 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left *(ebp+0x00000008) 3/imm8" "F - test-shift-mem-by-literal") -37945 # . epilogue -37946 89/<- %esp 5/r32/ebp -37947 5d/pop-to-ebp -37948 c3/return -37949 -37950 test-compare-reg-with-reg: -37951 # compare var1/ecx, var2/eax -37952 # => -37953 # 39/compare %ecx 0/r32/eax -37954 # -37955 # . prologue -37956 55/push-ebp -37957 89/<- %ebp 4/r32/esp -37958 # setup -37959 (clear-stream _test-output-stream) -37960 (clear-stream $_test-output-buffered-file->buffer) -37961 $test-compare-reg-with-reg:initialize-type: -37962 # var type/ecx: (payload type-tree) = int -37963 68/push 0/imm32/right:null -37964 68/push 0/imm32/right:null -37965 68/push 0/imm32/left:unused -37966 68/push 1/imm32/value:int -37967 68/push 1/imm32/is-atom?:true -37968 68/push 0x11/imm32/alloc-id:fake:payload -37969 89/<- %ecx 4/r32/esp -37970 $test-compare-reg-with-reg:initialize-var1: -37971 # var var1/ecx: (payload var) -37972 68/push 0/imm32/register -37973 68/push 0/imm32/register -37974 68/push 0/imm32/no-stack-offset -37975 68/push 1/imm32/block-depth -37976 51/push-ecx -37977 68/push 0x11/imm32/alloc-id:fake -37978 68/push 0/imm32/name -37979 68/push 0/imm32/name -37980 68/push 0x11/imm32/alloc-id:fake:payload -37981 89/<- %ecx 4/r32/esp -37982 $test-compare-reg-with-reg:initialize-var1-name: -37983 # var1->name = "var1" -37984 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -37985 (copy-array Heap "var1" %eax) -37986 $test-compare-reg-with-reg:initialize-var1-register: -37987 # var1->register = "ecx" -37988 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -37989 (copy-array Heap "ecx" %eax) -37990 $test-compare-reg-with-reg:initialize-var2: -37991 # var var2/edx: (payload var) -37992 68/push 0/imm32/register -37993 68/push 0/imm32/register -37994 68/push 0/imm32/no-stack-offset -37995 68/push 1/imm32/block-depth -37996 ff 6/subop/push *(ecx+0x10) -37997 68/push 0x11/imm32/alloc-id:fake -37998 68/push 0/imm32/name -37999 68/push 0/imm32/name -38000 68/push 0x11/imm32/alloc-id:fake:payload -38001 89/<- %edx 4/r32/esp -38002 $test-compare-reg-with-reg:initialize-var2-name: -38003 # var2->name = "var2" -38004 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -38005 (copy-array Heap "var2" %eax) -38006 $test-compare-reg-with-reg:initialize-var2-register: -38007 # var2->register = "eax" -38008 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -38009 (copy-array Heap "eax" %eax) -38010 $test-compare-reg-with-reg:initialize-inouts: -38011 # var inouts/esi: (payload stmt-var) = [var2] -38012 68/push 0/imm32/is-deref:false -38013 68/push 0/imm32/next -38014 68/push 0/imm32/next -38015 52/push-edx/var2 -38016 68/push 0x11/imm32/alloc-id:fake -38017 68/push 0x11/imm32/alloc-id:fake:payload -38018 89/<- %esi 4/r32/esp -38019 # inouts = [var1, var2] -38020 68/push 0/imm32/is-deref:false -38021 56/push-esi/next -38022 68/push 0x11/imm32/alloc-id:fake -38023 51/push-ecx/var1 -38024 68/push 0x11/imm32/alloc-id:fake -38025 68/push 0x11/imm32/alloc-id:fake:payload -38026 89/<- %esi 4/r32/esp -38027 $test-compare-reg-with-reg:initialize-stmt: -38028 # var stmt/esi: (addr statement) -38029 68/push 0/imm32/next -38030 68/push 0/imm32/next -38031 68/push 0/imm32/outputs -38032 68/push 0/imm32/outputs -38033 56/push-esi/inouts -38034 68/push 0x11/imm32/alloc-id:fake -38035 68/push 0/imm32/operation -38036 68/push 0/imm32/operation -38037 68/push 1/imm32/tag:stmt1 -38038 89/<- %esi 4/r32/esp -38039 $test-compare-reg-with-reg:initialize-stmt-operation: -38040 # stmt->operation = "compare" -38041 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -38042 (copy-array Heap "compare" %eax) -38043 # convert -38044 c7 0/subop/copy *Curr-block-depth 0/imm32 -38045 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -38046 (flush _test-output-buffered-file) -38047 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -38053 # check output -38054 (check-next-stream-line-equal _test-output-stream "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") -38055 # . epilogue -38056 89/<- %esp 5/r32/ebp -38057 5d/pop-to-ebp -38058 c3/return -38059 -38060 test-compare-mem-with-reg: -38061 # compare var1, var2/eax -38062 # => -38063 # 39/compare *(ebp+___) 0/r32/eax -38064 # -38065 # . prologue -38066 55/push-ebp -38067 89/<- %ebp 4/r32/esp -38068 # setup -38069 (clear-stream _test-output-stream) -38070 (clear-stream $_test-output-buffered-file->buffer) -38071 $test-compare-mem-with-reg:initialize-type: -38072 # var type/ecx: (payload type-tree) = int -38073 68/push 0/imm32/right:null -38074 68/push 0/imm32/right:null -38075 68/push 0/imm32/left:unused -38076 68/push 1/imm32/value:int -38077 68/push 1/imm32/is-atom?:true -38078 68/push 0x11/imm32/alloc-id:fake:payload -38079 89/<- %ecx 4/r32/esp -38080 $test-compare-mem-with-reg:initialize-var1: -38081 # var var1/ecx: (payload var) -38082 68/push 0/imm32/register -38083 68/push 0/imm32/register -38084 68/push 8/imm32/stack-offset -38085 68/push 1/imm32/block-depth -38086 51/push-ecx -38087 68/push 0x11/imm32/alloc-id:fake -38088 68/push 0/imm32/name -38089 68/push 0/imm32/name -38090 68/push 0x11/imm32/alloc-id:fake:payload -38091 89/<- %ecx 4/r32/esp -38092 $test-compare-mem-with-reg:initialize-var1-name: -38093 # var1->name = "var1" -38094 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -38095 (copy-array Heap "var1" %eax) -38096 $test-compare-mem-with-reg:initialize-var2: -38097 # var var2/edx: (payload var) -38098 68/push 0/imm32/register -38099 68/push 0/imm32/register -38100 68/push 0/imm32/no-stack-offset -38101 68/push 1/imm32/block-depth -38102 ff 6/subop/push *(ecx+0x10) -38103 68/push 0x11/imm32/alloc-id:fake -38104 68/push 0/imm32/name -38105 68/push 0/imm32/name -38106 68/push 0x11/imm32/alloc-id:fake:payload -38107 89/<- %edx 4/r32/esp -38108 $test-compare-mem-with-reg:initialize-var2-name: -38109 # var2->name = "var2" -38110 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -38111 (copy-array Heap "var2" %eax) -38112 $test-compare-mem-with-reg:initialize-var2-register: -38113 # var2->register = "eax" -38114 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -38115 (copy-array Heap "eax" %eax) -38116 $test-compare-mem-with-reg:initialize-inouts: -38117 # var inouts/esi: (payload stmt-var) = [var2] -38118 68/push 0/imm32/is-deref:false -38119 68/push 0/imm32/next -38120 68/push 0/imm32/next -38121 52/push-edx/var2 -38122 68/push 0x11/imm32/alloc-id:fake -38123 68/push 0x11/imm32/alloc-id:fake:payload -38124 89/<- %esi 4/r32/esp -38125 # inouts = [var1, var2] -38126 68/push 0/imm32/is-deref:false -38127 56/push-esi/next -38128 68/push 0x11/imm32/alloc-id:fake -38129 51/push-ecx/var1 -38130 68/push 0x11/imm32/alloc-id:fake -38131 68/push 0x11/imm32/alloc-id:fake:payload -38132 89/<- %esi 4/r32/esp -38133 $test-compare-mem-with-reg:initialize-stmt: -38134 # var stmt/esi: (addr statement) -38135 68/push 0/imm32/next -38136 68/push 0/imm32/next -38137 68/push 0/imm32/outputs -38138 68/push 0/imm32/outputs -38139 56/push-esi/inouts -38140 68/push 0x11/imm32/alloc-id:fake -38141 68/push 0/imm32/operation -38142 68/push 0/imm32/operation -38143 68/push 1/imm32/tag:stmt1 -38144 89/<- %esi 4/r32/esp -38145 $test-compare-mem-with-reg:initialize-stmt-operation: -38146 # stmt->operation = "compare" -38147 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -38148 (copy-array Heap "compare" %eax) -38149 # convert -38150 c7 0/subop/copy *Curr-block-depth 0/imm32 -38151 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -38152 (flush _test-output-buffered-file) -38153 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -38159 # check output -38160 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") -38161 # . epilogue -38162 89/<- %esp 5/r32/ebp -38163 5d/pop-to-ebp -38164 c3/return -38165 -38166 test-compare-reg-with-mem: -38167 # compare var1/eax, var2 -38168 # => -38169 # 3b/compare<- *(ebp+___) 0/r32/eax -38170 # -38171 # . prologue -38172 55/push-ebp -38173 89/<- %ebp 4/r32/esp -38174 # setup -38175 (clear-stream _test-output-stream) -38176 (clear-stream $_test-output-buffered-file->buffer) -38177 $test-compare-reg-with-mem:initialize-type: -38178 # var type/ecx: (payload type-tree) = int -38179 68/push 0/imm32/right:null -38180 68/push 0/imm32/right:null -38181 68/push 0/imm32/left:unused -38182 68/push 1/imm32/value:int -38183 68/push 1/imm32/is-atom?:true -38184 68/push 0x11/imm32/alloc-id:fake:payload -38185 89/<- %ecx 4/r32/esp -38186 $test-compare-reg-with-mem:initialize-var1: -38187 # var var1/ecx: (payload var) -38188 68/push 0/imm32/register -38189 68/push 0/imm32/register -38190 68/push 0/imm32/no-stack-offset -38191 68/push 1/imm32/block-depth -38192 51/push-ecx -38193 68/push 0x11/imm32/alloc-id:fake -38194 68/push 0/imm32/name -38195 68/push 0/imm32/name -38196 68/push 0x11/imm32/alloc-id:fake:payload -38197 89/<- %ecx 4/r32/esp -38198 $test-compare-reg-with-mem:initialize-var1-name: -38199 # var1->name = "var1" -38200 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -38201 (copy-array Heap "var1" %eax) -38202 $test-compare-reg-with-mem:initialize-var1-register: -38203 # var1->register = "eax" -38204 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -38205 (copy-array Heap "eax" %eax) -38206 $test-compare-reg-with-mem:initialize-var2: -38207 # var var2/edx: (payload var) -38208 68/push 0/imm32/register -38209 68/push 0/imm32/register -38210 68/push 8/imm32/stack-offset -38211 68/push 1/imm32/block-depth -38212 ff 6/subop/push *(ecx+0x10) -38213 68/push 0x11/imm32/alloc-id:fake -38214 68/push 0/imm32/name -38215 68/push 0/imm32/name -38216 68/push 0x11/imm32/alloc-id:fake:payload -38217 89/<- %edx 4/r32/esp -38218 $test-compare-reg-with-mem:initialize-var2-name: -38219 # var2->name = "var2" -38220 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -38221 (copy-array Heap "var2" %eax) -38222 $test-compare-reg-with-mem:initialize-inouts: -38223 # var inouts/esi: (payload stmt-var) = [var2] -38224 68/push 0/imm32/is-deref:false -38225 68/push 0/imm32/next -38226 68/push 0/imm32/next -38227 52/push-edx/var2 -38228 68/push 0x11/imm32/alloc-id:fake -38229 68/push 0x11/imm32/alloc-id:fake:payload -38230 89/<- %esi 4/r32/esp -38231 # inouts = [var1, var2] -38232 68/push 0/imm32/is-deref:false -38233 56/push-esi/next -38234 68/push 0x11/imm32/alloc-id:fake -38235 51/push-ecx/var1 -38236 68/push 0x11/imm32/alloc-id:fake -38237 68/push 0x11/imm32/alloc-id:fake:payload -38238 89/<- %esi 4/r32/esp -38239 $test-compare-reg-with-mem:initialize-stmt: -38240 # var stmt/esi: (addr statement) -38241 68/push 0/imm32/next -38242 68/push 0/imm32/next -38243 68/push 0/imm32/outputs -38244 68/push 0/imm32/outputs -38245 56/push-esi/inouts -38246 68/push 0x11/imm32/alloc-id:fake -38247 68/push 0/imm32/operation -38248 68/push 0/imm32/operation -38249 68/push 1/imm32/tag:stmt1 -38250 89/<- %esi 4/r32/esp -38251 $test-compare-reg-with-mem:initialize-stmt-operation: -38252 # stmt->operation = "compare" -38253 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -38254 (copy-array Heap "compare" %eax) -38255 # convert -38256 c7 0/subop/copy *Curr-block-depth 0/imm32 -38257 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -38258 (flush _test-output-buffered-file) -38259 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -38265 # check output -38266 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") -38267 # . epilogue -38268 89/<- %esp 5/r32/ebp -38269 5d/pop-to-ebp -38270 c3/return -38271 -38272 test-compare-mem-with-literal: -38273 # compare var1, 0x34 -38274 # => -38275 # 81 7/subop/compare *(ebp+___) 0x34/imm32 -38276 # -38277 # . prologue -38278 55/push-ebp -38279 89/<- %ebp 4/r32/esp -38280 # setup -38281 (clear-stream _test-output-stream) -38282 (clear-stream $_test-output-buffered-file->buffer) -38283 $test-compare-mem-with-literal:initialize-type: -38284 # var type/ecx: (payload type-tree) = int -38285 68/push 0/imm32/right:null -38286 68/push 0/imm32/right:null -38287 68/push 0/imm32/left:unused -38288 68/push 1/imm32/value:int -38289 68/push 1/imm32/is-atom?:true -38290 68/push 0x11/imm32/alloc-id:fake:payload -38291 89/<- %ecx 4/r32/esp -38292 $test-compare-mem-with-literal:initialize-var1: -38293 # var var1/ecx: (payload var) -38294 68/push 0/imm32/register -38295 68/push 0/imm32/register -38296 68/push 8/imm32/stack-offset -38297 68/push 1/imm32/block-depth -38298 51/push-ecx -38299 68/push 0x11/imm32/alloc-id:fake -38300 68/push 0/imm32/name -38301 68/push 0/imm32/name -38302 68/push 0x11/imm32/alloc-id:fake:payload -38303 89/<- %ecx 4/r32/esp -38304 $test-compare-mem-with-literal:initialize-var1-name: -38305 # var1->name = "var1" -38306 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -38307 (copy-array Heap "var1" %eax) -38308 $test-compare-mem-with-literal:initialize-literal-type: -38309 # var type/edx: (payload type-tree) = literal -38310 68/push 0/imm32/right:null -38311 68/push 0/imm32/right:null -38312 68/push 0/imm32/left:unused -38313 68/push 0/imm32/value:literal -38314 68/push 1/imm32/is-atom?:true -38315 68/push 0x11/imm32/alloc-id:fake:payload -38316 89/<- %edx 4/r32/esp -38317 $test-compare-mem-with-literal:initialize-literal: -38318 # var l/edx: (payload var) -38319 68/push 0/imm32/register -38320 68/push 0/imm32/register -38321 68/push 0/imm32/no-stack-offset -38322 68/push 1/imm32/block-depth -38323 52/push-edx -38324 68/push 0x11/imm32/alloc-id:fake -38325 68/push 0/imm32/name -38326 68/push 0/imm32/name -38327 68/push 0x11/imm32/alloc-id:fake:payload -38328 89/<- %edx 4/r32/esp -38329 $test-compare-mem-with-literal:initialize-literal-value: -38330 # l->name = "0x34" -38331 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -38332 (copy-array Heap "0x34" %eax) -38333 $test-compare-mem-with-literal:initialize-inouts: -38334 # var inouts/esi: (payload stmt-var) = [l] -38335 68/push 0/imm32/is-deref:false -38336 68/push 0/imm32/next -38337 68/push 0/imm32/next -38338 52/push-edx/l -38339 68/push 0x11/imm32/alloc-id:fake -38340 68/push 0x11/imm32/alloc-id:fake:payload -38341 89/<- %esi 4/r32/esp -38342 # var inouts = (handle stmt-var) = [var1, var2] -38343 68/push 0/imm32/is-deref:false -38344 56/push-esi/next -38345 68/push 0x11/imm32/alloc-id:fake -38346 51/push-ecx/var1 +37915 68/push 0/imm32/name +37916 68/push 0/imm32/name +37917 68/push 0x11/imm32/alloc-id:fake:payload +37918 89/<- %ecx 4/r32/esp +37919 $test-shift-mem-by-literal:initialize-var1-name: +37920 # var1->name = "var1" +37921 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +37922 (copy-array Heap "var1" %eax) +37923 $test-shift-mem-by-literal:initialize-literal-type: +37924 # var type/edx: (payload type-tree) = literal +37925 68/push 0/imm32/right:null +37926 68/push 0/imm32/right:null +37927 68/push 0/imm32/left:unused +37928 68/push 0/imm32/value:literal +37929 68/push 1/imm32/is-atom?:true +37930 68/push 0x11/imm32/alloc-id:fake:payload +37931 89/<- %edx 4/r32/esp +37932 $test-shift-mem-by-literal:initialize-literal: +37933 # var l/edx: (payload var) +37934 68/push 0/imm32/register +37935 68/push 0/imm32/register +37936 68/push 0/imm32/no-stack-offset +37937 68/push 1/imm32/block-depth +37938 52/push-edx +37939 68/push 0x11/imm32/alloc-id:fake +37940 68/push 0/imm32/name +37941 68/push 0/imm32/name +37942 68/push 0x11/imm32/alloc-id:fake:payload +37943 89/<- %edx 4/r32/esp +37944 $test-shift-mem-by-literal:initialize-literal-value: +37945 # l->name = "3" +37946 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +37947 (copy-array Heap "3" %eax) +37948 $test-shift-mem-by-literal:initialize-inouts: +37949 # var inouts/esi: (payload stmt-var) = [l] +37950 68/push 0/imm32/is-deref:false +37951 68/push 0/imm32/next +37952 68/push 0/imm32/next +37953 52/push-edx/l +37954 68/push 0x11/imm32/alloc-id:fake +37955 68/push 0x11/imm32/alloc-id:fake:payload +37956 89/<- %esi 4/r32/esp +37957 # var inouts = (handle stmt-var) = [var1, var2] +37958 68/push 0/imm32/is-deref:false +37959 56/push-esi/next +37960 68/push 0x11/imm32/alloc-id:fake +37961 51/push-ecx/var1 +37962 68/push 0x11/imm32/alloc-id:fake +37963 68/push 0x11/imm32/alloc-id:fake:payload +37964 89/<- %esi 4/r32/esp +37965 $test-shift-mem-by-literal:initialize-stmt: +37966 # var stmt/esi: (addr statement) +37967 68/push 0/imm32/next +37968 68/push 0/imm32/next +37969 68/push 0/imm32/outputs +37970 68/push 0/imm32/outputs +37971 56/push-esi/inouts +37972 68/push 0x11/imm32/alloc-id:fake +37973 68/push 0/imm32/operation +37974 68/push 0/imm32/operation +37975 68/push 1/imm32/tag:stmt1 +37976 89/<- %esi 4/r32/esp +37977 $test-shift-mem-by-literal:initialize-stmt-operation: +37978 # stmt->operation = "shift-left" +37979 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +37980 (copy-array Heap "shift-left" %eax) +37981 # convert +37982 c7 0/subop/copy *Curr-block-depth 0/imm32 +37983 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +37984 (flush _test-output-buffered-file) +37985 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +37991 # check output +37992 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left *(ebp+0x00000008) 3/imm8" "F - test-shift-mem-by-literal") +37993 # . epilogue +37994 89/<- %esp 5/r32/ebp +37995 5d/pop-to-ebp +37996 c3/return +37997 +37998 test-compare-reg-with-reg: +37999 # compare var1/ecx, var2/eax +38000 # => +38001 # 39/compare %ecx 0/r32/eax +38002 # +38003 # . prologue +38004 55/push-ebp +38005 89/<- %ebp 4/r32/esp +38006 # setup +38007 (clear-stream _test-output-stream) +38008 (clear-stream $_test-output-buffered-file->buffer) +38009 $test-compare-reg-with-reg:initialize-type: +38010 # var type/ecx: (payload type-tree) = int +38011 68/push 0/imm32/right:null +38012 68/push 0/imm32/right:null +38013 68/push 0/imm32/left:unused +38014 68/push 1/imm32/value:int +38015 68/push 1/imm32/is-atom?:true +38016 68/push 0x11/imm32/alloc-id:fake:payload +38017 89/<- %ecx 4/r32/esp +38018 $test-compare-reg-with-reg:initialize-var1: +38019 # var var1/ecx: (payload var) +38020 68/push 0/imm32/register +38021 68/push 0/imm32/register +38022 68/push 0/imm32/no-stack-offset +38023 68/push 1/imm32/block-depth +38024 51/push-ecx +38025 68/push 0x11/imm32/alloc-id:fake +38026 68/push 0/imm32/name +38027 68/push 0/imm32/name +38028 68/push 0x11/imm32/alloc-id:fake:payload +38029 89/<- %ecx 4/r32/esp +38030 $test-compare-reg-with-reg:initialize-var1-name: +38031 # var1->name = "var1" +38032 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +38033 (copy-array Heap "var1" %eax) +38034 $test-compare-reg-with-reg:initialize-var1-register: +38035 # var1->register = "ecx" +38036 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +38037 (copy-array Heap "ecx" %eax) +38038 $test-compare-reg-with-reg:initialize-var2: +38039 # var var2/edx: (payload var) +38040 68/push 0/imm32/register +38041 68/push 0/imm32/register +38042 68/push 0/imm32/no-stack-offset +38043 68/push 1/imm32/block-depth +38044 ff 6/subop/push *(ecx+0x10) +38045 68/push 0x11/imm32/alloc-id:fake +38046 68/push 0/imm32/name +38047 68/push 0/imm32/name +38048 68/push 0x11/imm32/alloc-id:fake:payload +38049 89/<- %edx 4/r32/esp +38050 $test-compare-reg-with-reg:initialize-var2-name: +38051 # var2->name = "var2" +38052 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +38053 (copy-array Heap "var2" %eax) +38054 $test-compare-reg-with-reg:initialize-var2-register: +38055 # var2->register = "eax" +38056 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +38057 (copy-array Heap "eax" %eax) +38058 $test-compare-reg-with-reg:initialize-inouts: +38059 # var inouts/esi: (payload stmt-var) = [var2] +38060 68/push 0/imm32/is-deref:false +38061 68/push 0/imm32/next +38062 68/push 0/imm32/next +38063 52/push-edx/var2 +38064 68/push 0x11/imm32/alloc-id:fake +38065 68/push 0x11/imm32/alloc-id:fake:payload +38066 89/<- %esi 4/r32/esp +38067 # inouts = [var1, var2] +38068 68/push 0/imm32/is-deref:false +38069 56/push-esi/next +38070 68/push 0x11/imm32/alloc-id:fake +38071 51/push-ecx/var1 +38072 68/push 0x11/imm32/alloc-id:fake +38073 68/push 0x11/imm32/alloc-id:fake:payload +38074 89/<- %esi 4/r32/esp +38075 $test-compare-reg-with-reg:initialize-stmt: +38076 # var stmt/esi: (addr statement) +38077 68/push 0/imm32/next +38078 68/push 0/imm32/next +38079 68/push 0/imm32/outputs +38080 68/push 0/imm32/outputs +38081 56/push-esi/inouts +38082 68/push 0x11/imm32/alloc-id:fake +38083 68/push 0/imm32/operation +38084 68/push 0/imm32/operation +38085 68/push 1/imm32/tag:stmt1 +38086 89/<- %esi 4/r32/esp +38087 $test-compare-reg-with-reg:initialize-stmt-operation: +38088 # stmt->operation = "compare" +38089 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +38090 (copy-array Heap "compare" %eax) +38091 # convert +38092 c7 0/subop/copy *Curr-block-depth 0/imm32 +38093 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +38094 (flush _test-output-buffered-file) +38095 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +38101 # check output +38102 (check-next-stream-line-equal _test-output-stream "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") +38103 # . epilogue +38104 89/<- %esp 5/r32/ebp +38105 5d/pop-to-ebp +38106 c3/return +38107 +38108 test-compare-mem-with-reg: +38109 # compare var1, var2/eax +38110 # => +38111 # 39/compare *(ebp+___) 0/r32/eax +38112 # +38113 # . prologue +38114 55/push-ebp +38115 89/<- %ebp 4/r32/esp +38116 # setup +38117 (clear-stream _test-output-stream) +38118 (clear-stream $_test-output-buffered-file->buffer) +38119 $test-compare-mem-with-reg:initialize-type: +38120 # var type/ecx: (payload type-tree) = int +38121 68/push 0/imm32/right:null +38122 68/push 0/imm32/right:null +38123 68/push 0/imm32/left:unused +38124 68/push 1/imm32/value:int +38125 68/push 1/imm32/is-atom?:true +38126 68/push 0x11/imm32/alloc-id:fake:payload +38127 89/<- %ecx 4/r32/esp +38128 $test-compare-mem-with-reg:initialize-var1: +38129 # var var1/ecx: (payload var) +38130 68/push 0/imm32/register +38131 68/push 0/imm32/register +38132 68/push 8/imm32/stack-offset +38133 68/push 1/imm32/block-depth +38134 51/push-ecx +38135 68/push 0x11/imm32/alloc-id:fake +38136 68/push 0/imm32/name +38137 68/push 0/imm32/name +38138 68/push 0x11/imm32/alloc-id:fake:payload +38139 89/<- %ecx 4/r32/esp +38140 $test-compare-mem-with-reg:initialize-var1-name: +38141 # var1->name = "var1" +38142 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +38143 (copy-array Heap "var1" %eax) +38144 $test-compare-mem-with-reg:initialize-var2: +38145 # var var2/edx: (payload var) +38146 68/push 0/imm32/register +38147 68/push 0/imm32/register +38148 68/push 0/imm32/no-stack-offset +38149 68/push 1/imm32/block-depth +38150 ff 6/subop/push *(ecx+0x10) +38151 68/push 0x11/imm32/alloc-id:fake +38152 68/push 0/imm32/name +38153 68/push 0/imm32/name +38154 68/push 0x11/imm32/alloc-id:fake:payload +38155 89/<- %edx 4/r32/esp +38156 $test-compare-mem-with-reg:initialize-var2-name: +38157 # var2->name = "var2" +38158 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +38159 (copy-array Heap "var2" %eax) +38160 $test-compare-mem-with-reg:initialize-var2-register: +38161 # var2->register = "eax" +38162 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +38163 (copy-array Heap "eax" %eax) +38164 $test-compare-mem-with-reg:initialize-inouts: +38165 # var inouts/esi: (payload stmt-var) = [var2] +38166 68/push 0/imm32/is-deref:false +38167 68/push 0/imm32/next +38168 68/push 0/imm32/next +38169 52/push-edx/var2 +38170 68/push 0x11/imm32/alloc-id:fake +38171 68/push 0x11/imm32/alloc-id:fake:payload +38172 89/<- %esi 4/r32/esp +38173 # inouts = [var1, var2] +38174 68/push 0/imm32/is-deref:false +38175 56/push-esi/next +38176 68/push 0x11/imm32/alloc-id:fake +38177 51/push-ecx/var1 +38178 68/push 0x11/imm32/alloc-id:fake +38179 68/push 0x11/imm32/alloc-id:fake:payload +38180 89/<- %esi 4/r32/esp +38181 $test-compare-mem-with-reg:initialize-stmt: +38182 # var stmt/esi: (addr statement) +38183 68/push 0/imm32/next +38184 68/push 0/imm32/next +38185 68/push 0/imm32/outputs +38186 68/push 0/imm32/outputs +38187 56/push-esi/inouts +38188 68/push 0x11/imm32/alloc-id:fake +38189 68/push 0/imm32/operation +38190 68/push 0/imm32/operation +38191 68/push 1/imm32/tag:stmt1 +38192 89/<- %esi 4/r32/esp +38193 $test-compare-mem-with-reg:initialize-stmt-operation: +38194 # stmt->operation = "compare" +38195 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +38196 (copy-array Heap "compare" %eax) +38197 # convert +38198 c7 0/subop/copy *Curr-block-depth 0/imm32 +38199 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +38200 (flush _test-output-buffered-file) +38201 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +38207 # check output +38208 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") +38209 # . epilogue +38210 89/<- %esp 5/r32/ebp +38211 5d/pop-to-ebp +38212 c3/return +38213 +38214 test-compare-reg-with-mem: +38215 # compare var1/eax, var2 +38216 # => +38217 # 3b/compare<- *(ebp+___) 0/r32/eax +38218 # +38219 # . prologue +38220 55/push-ebp +38221 89/<- %ebp 4/r32/esp +38222 # setup +38223 (clear-stream _test-output-stream) +38224 (clear-stream $_test-output-buffered-file->buffer) +38225 $test-compare-reg-with-mem:initialize-type: +38226 # var type/ecx: (payload type-tree) = int +38227 68/push 0/imm32/right:null +38228 68/push 0/imm32/right:null +38229 68/push 0/imm32/left:unused +38230 68/push 1/imm32/value:int +38231 68/push 1/imm32/is-atom?:true +38232 68/push 0x11/imm32/alloc-id:fake:payload +38233 89/<- %ecx 4/r32/esp +38234 $test-compare-reg-with-mem:initialize-var1: +38235 # var var1/ecx: (payload var) +38236 68/push 0/imm32/register +38237 68/push 0/imm32/register +38238 68/push 0/imm32/no-stack-offset +38239 68/push 1/imm32/block-depth +38240 51/push-ecx +38241 68/push 0x11/imm32/alloc-id:fake +38242 68/push 0/imm32/name +38243 68/push 0/imm32/name +38244 68/push 0x11/imm32/alloc-id:fake:payload +38245 89/<- %ecx 4/r32/esp +38246 $test-compare-reg-with-mem:initialize-var1-name: +38247 # var1->name = "var1" +38248 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +38249 (copy-array Heap "var1" %eax) +38250 $test-compare-reg-with-mem:initialize-var1-register: +38251 # var1->register = "eax" +38252 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +38253 (copy-array Heap "eax" %eax) +38254 $test-compare-reg-with-mem:initialize-var2: +38255 # var var2/edx: (payload var) +38256 68/push 0/imm32/register +38257 68/push 0/imm32/register +38258 68/push 8/imm32/stack-offset +38259 68/push 1/imm32/block-depth +38260 ff 6/subop/push *(ecx+0x10) +38261 68/push 0x11/imm32/alloc-id:fake +38262 68/push 0/imm32/name +38263 68/push 0/imm32/name +38264 68/push 0x11/imm32/alloc-id:fake:payload +38265 89/<- %edx 4/r32/esp +38266 $test-compare-reg-with-mem:initialize-var2-name: +38267 # var2->name = "var2" +38268 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +38269 (copy-array Heap "var2" %eax) +38270 $test-compare-reg-with-mem:initialize-inouts: +38271 # var inouts/esi: (payload stmt-var) = [var2] +38272 68/push 0/imm32/is-deref:false +38273 68/push 0/imm32/next +38274 68/push 0/imm32/next +38275 52/push-edx/var2 +38276 68/push 0x11/imm32/alloc-id:fake +38277 68/push 0x11/imm32/alloc-id:fake:payload +38278 89/<- %esi 4/r32/esp +38279 # inouts = [var1, var2] +38280 68/push 0/imm32/is-deref:false +38281 56/push-esi/next +38282 68/push 0x11/imm32/alloc-id:fake +38283 51/push-ecx/var1 +38284 68/push 0x11/imm32/alloc-id:fake +38285 68/push 0x11/imm32/alloc-id:fake:payload +38286 89/<- %esi 4/r32/esp +38287 $test-compare-reg-with-mem:initialize-stmt: +38288 # var stmt/esi: (addr statement) +38289 68/push 0/imm32/next +38290 68/push 0/imm32/next +38291 68/push 0/imm32/outputs +38292 68/push 0/imm32/outputs +38293 56/push-esi/inouts +38294 68/push 0x11/imm32/alloc-id:fake +38295 68/push 0/imm32/operation +38296 68/push 0/imm32/operation +38297 68/push 1/imm32/tag:stmt1 +38298 89/<- %esi 4/r32/esp +38299 $test-compare-reg-with-mem:initialize-stmt-operation: +38300 # stmt->operation = "compare" +38301 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +38302 (copy-array Heap "compare" %eax) +38303 # convert +38304 c7 0/subop/copy *Curr-block-depth 0/imm32 +38305 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +38306 (flush _test-output-buffered-file) +38307 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +38313 # check output +38314 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") +38315 # . epilogue +38316 89/<- %esp 5/r32/ebp +38317 5d/pop-to-ebp +38318 c3/return +38319 +38320 test-compare-mem-with-literal: +38321 # compare var1, 0x34 +38322 # => +38323 # 81 7/subop/compare *(ebp+___) 0x34/imm32 +38324 # +38325 # . prologue +38326 55/push-ebp +38327 89/<- %ebp 4/r32/esp +38328 # setup +38329 (clear-stream _test-output-stream) +38330 (clear-stream $_test-output-buffered-file->buffer) +38331 $test-compare-mem-with-literal:initialize-type: +38332 # var type/ecx: (payload type-tree) = int +38333 68/push 0/imm32/right:null +38334 68/push 0/imm32/right:null +38335 68/push 0/imm32/left:unused +38336 68/push 1/imm32/value:int +38337 68/push 1/imm32/is-atom?:true +38338 68/push 0x11/imm32/alloc-id:fake:payload +38339 89/<- %ecx 4/r32/esp +38340 $test-compare-mem-with-literal:initialize-var1: +38341 # var var1/ecx: (payload var) +38342 68/push 0/imm32/register +38343 68/push 0/imm32/register +38344 68/push 8/imm32/stack-offset +38345 68/push 1/imm32/block-depth +38346 51/push-ecx 38347 68/push 0x11/imm32/alloc-id:fake -38348 68/push 0x11/imm32/alloc-id:fake:payload -38349 89/<- %esi 4/r32/esp -38350 $test-compare-mem-with-literal:initialize-stmt: -38351 # var stmt/esi: (addr statement) -38352 68/push 0/imm32/next -38353 68/push 0/imm32/next -38354 68/push 0/imm32/outputs -38355 68/push 0/imm32/outputs -38356 56/push-esi/inouts -38357 68/push 0x11/imm32/alloc-id:fake -38358 68/push 0/imm32/operation -38359 68/push 0/imm32/operation -38360 68/push 1/imm32/tag:stmt1 -38361 89/<- %esi 4/r32/esp -38362 $test-compare-mem-with-literal:initialize-stmt-operation: -38363 # stmt->operation = "compare" -38364 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -38365 (copy-array Heap "compare" %eax) -38366 # convert -38367 c7 0/subop/copy *Curr-block-depth 0/imm32 -38368 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -38369 (flush _test-output-buffered-file) -38370 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -38376 # check output -38377 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") -38378 # . epilogue -38379 89/<- %esp 5/r32/ebp -38380 5d/pop-to-ebp -38381 c3/return -38382 -38383 test-compare-eax-with-literal: -38384 # compare var1/eax 0x34 -38385 # => -38386 # 3d/compare-eax-with 0x34/imm32 -38387 # -38388 # . prologue -38389 55/push-ebp -38390 89/<- %ebp 4/r32/esp -38391 # setup -38392 (clear-stream _test-output-stream) -38393 (clear-stream $_test-output-buffered-file->buffer) -38394 $test-compare-eax-with-literal:initialize-type: -38395 # var type/ecx: (payload type-tree) = int -38396 68/push 0/imm32/right:null -38397 68/push 0/imm32/right:null -38398 68/push 0/imm32/left:unused -38399 68/push 1/imm32/value:int -38400 68/push 1/imm32/is-atom?:true -38401 68/push 0x11/imm32/alloc-id:fake:payload -38402 89/<- %ecx 4/r32/esp -38403 $test-compare-eax-with-literal:initialize-var1: -38404 # var var1/ecx: (payload var) -38405 68/push 0/imm32/register -38406 68/push 0/imm32/register -38407 68/push 0/imm32/no-stack-offset -38408 68/push 1/imm32/block-depth -38409 51/push-ecx -38410 68/push 0x11/imm32/alloc-id:fake -38411 68/push 0/imm32/name -38412 68/push 0/imm32/name -38413 68/push 0x11/imm32/alloc-id:fake:payload -38414 89/<- %ecx 4/r32/esp -38415 $test-compare-eax-with-literal:initialize-var1-name: -38416 # var1->name = "var1" -38417 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -38418 (copy-array Heap "var1" %eax) -38419 $test-compare-eax-with-literal:initialize-var1-register: -38420 # v->register = "eax" -38421 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -38422 (copy-array Heap "eax" %eax) -38423 $test-compare-eax-with-literal:initialize-literal-type: -38424 # var type/edx: (payload type-tree) = literal -38425 68/push 0/imm32/right:null -38426 68/push 0/imm32/right:null -38427 68/push 0/imm32/left:unused -38428 68/push 0/imm32/value:literal -38429 68/push 1/imm32/is-atom?:true -38430 68/push 0x11/imm32/alloc-id:fake:payload -38431 89/<- %edx 4/r32/esp -38432 $test-compare-eax-with-literal:initialize-literal: -38433 # var l/edx: (payload var) -38434 68/push 0/imm32/register -38435 68/push 0/imm32/register -38436 68/push 0/imm32/no-stack-offset -38437 68/push 1/imm32/block-depth -38438 52/push-edx -38439 68/push 0x11/imm32/alloc-id:fake -38440 68/push 0/imm32/name -38441 68/push 0/imm32/name -38442 68/push 0x11/imm32/alloc-id:fake:payload -38443 89/<- %edx 4/r32/esp -38444 $test-compare-eax-with-literal:initialize-literal-value: -38445 # l->name = "0x34" -38446 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -38447 (copy-array Heap "0x34" %eax) -38448 $test-compare-eax-with-literal:initialize-inouts: -38449 # var inouts/esi: (payload stmt-var) = [l] -38450 68/push 0/imm32/is-deref:false -38451 68/push 0/imm32/next -38452 68/push 0/imm32/next -38453 52/push-edx/l -38454 68/push 0x11/imm32/alloc-id:fake -38455 68/push 0x11/imm32/alloc-id:fake:payload -38456 89/<- %esi 4/r32/esp -38457 # var inouts = (handle stmt-var) = [var1, var2] -38458 68/push 0/imm32/is-deref:false -38459 56/push-esi/next -38460 68/push 0x11/imm32/alloc-id:fake -38461 51/push-ecx/var1 -38462 68/push 0x11/imm32/alloc-id:fake -38463 68/push 0x11/imm32/alloc-id:fake:payload -38464 89/<- %esi 4/r32/esp -38465 $test-compare-eax-with-literal:initialize-stmt: -38466 # var stmt/esi: (addr statement) -38467 68/push 0/imm32/next -38468 68/push 0/imm32/next -38469 68/push 0/imm32/outputs -38470 68/push 0/imm32/outputs -38471 56/push-esi/inouts -38472 68/push 0x11/imm32/alloc-id:fake -38473 68/push 0/imm32/operation -38474 68/push 0/imm32/operation -38475 68/push 1/imm32/tag:stmt1 -38476 89/<- %esi 4/r32/esp -38477 $test-compare-eax-with-literal:initialize-stmt-operation: -38478 # stmt->operation = "compare" -38479 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -38480 (copy-array Heap "compare" %eax) -38481 # convert -38482 c7 0/subop/copy *Curr-block-depth 0/imm32 -38483 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -38484 (flush _test-output-buffered-file) -38485 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -38491 # check output -38492 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") -38493 # . epilogue -38494 89/<- %esp 5/r32/ebp -38495 5d/pop-to-ebp -38496 c3/return -38497 -38498 test-compare-reg-with-literal: -38499 # compare var1/ecx 0x34 -38500 # => -38501 # 81 7/subop/compare %ecx 0x34/imm32 -38502 # -38503 # . prologue -38504 55/push-ebp -38505 89/<- %ebp 4/r32/esp -38506 # setup -38507 (clear-stream _test-output-stream) -38508 (clear-stream $_test-output-buffered-file->buffer) -38509 $test-compare-reg-with-literal:initialize-type: -38510 # var type/ecx: (payload type-tree) = int -38511 68/push 0/imm32/right:null -38512 68/push 0/imm32/right:null -38513 68/push 0/imm32/left:unused -38514 68/push 1/imm32/value:int -38515 68/push 1/imm32/is-atom?:true -38516 68/push 0x11/imm32/alloc-id:fake:payload -38517 89/<- %ecx 4/r32/esp -38518 $test-compare-reg-with-literal:initialize-var1: -38519 # var var1/ecx: (payload var) -38520 68/push 0/imm32/register -38521 68/push 0/imm32/register -38522 68/push 0/imm32/no-stack-offset -38523 68/push 1/imm32/block-depth -38524 51/push-ecx -38525 68/push 0x11/imm32/alloc-id:fake -38526 68/push 0/imm32/name -38527 68/push 0/imm32/name -38528 68/push 0x11/imm32/alloc-id:fake:payload -38529 89/<- %ecx 4/r32/esp -38530 $test-compare-reg-with-literal:initialize-var1-name: -38531 # var1->name = "var1" -38532 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -38533 (copy-array Heap "var1" %eax) -38534 $test-compare-reg-with-literal:initialize-var1-register: -38535 # v->register = "ecx" -38536 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -38537 (copy-array Heap "ecx" %eax) -38538 $test-compare-reg-with-literal:initialize-literal-type: -38539 # var type/edx: (payload type-tree) = literal -38540 68/push 0/imm32/right:null -38541 68/push 0/imm32/right:null -38542 68/push 0/imm32/left:unused -38543 68/push 0/imm32/value:literal -38544 68/push 1/imm32/is-atom?:true -38545 68/push 0x11/imm32/alloc-id:fake:payload -38546 89/<- %edx 4/r32/esp -38547 $test-compare-reg-with-literal:initialize-literal: -38548 # var l/edx: (payload var) -38549 68/push 0/imm32/register -38550 68/push 0/imm32/register -38551 68/push 0/imm32/no-stack-offset -38552 68/push 1/imm32/block-depth -38553 52/push-edx -38554 68/push 0x11/imm32/alloc-id:fake -38555 68/push 0/imm32/name -38556 68/push 0/imm32/name -38557 68/push 0x11/imm32/alloc-id:fake:payload -38558 89/<- %edx 4/r32/esp -38559 $test-compare-reg-with-literal:initialize-literal-value: -38560 # l->name = "0x34" -38561 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -38562 (copy-array Heap "0x34" %eax) -38563 $test-compare-reg-with-literal:initialize-inouts: -38564 # var inouts/esi: (payload stmt-var) = [l] -38565 68/push 0/imm32/is-deref:false -38566 68/push 0/imm32/next -38567 68/push 0/imm32/next -38568 52/push-edx/l -38569 68/push 0x11/imm32/alloc-id:fake -38570 68/push 0x11/imm32/alloc-id:fake:payload -38571 89/<- %esi 4/r32/esp -38572 # var inouts = (handle stmt-var) = [var1, var2] -38573 68/push 0/imm32/is-deref:false -38574 56/push-esi/next -38575 68/push 0x11/imm32/alloc-id:fake -38576 51/push-ecx/var1 -38577 68/push 0x11/imm32/alloc-id:fake -38578 68/push 0x11/imm32/alloc-id:fake:payload -38579 89/<- %esi 4/r32/esp -38580 $test-compare-reg-with-literal:initialize-stmt: -38581 # var stmt/esi: (addr statement) -38582 68/push 0/imm32/next -38583 68/push 0/imm32/next -38584 68/push 0/imm32/outputs -38585 68/push 0/imm32/outputs -38586 56/push-esi/inouts -38587 68/push 0x11/imm32/alloc-id:fake -38588 68/push 0/imm32/operation -38589 68/push 0/imm32/operation -38590 68/push 1/imm32/tag:stmt1 -38591 89/<- %esi 4/r32/esp -38592 $test-compare-reg-with-literal:initialize-stmt-operation: -38593 # stmt->operation = "compare" -38594 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -38595 (copy-array Heap "compare" %eax) -38596 # convert -38597 c7 0/subop/copy *Curr-block-depth 0/imm32 -38598 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) -38599 (flush _test-output-buffered-file) -38600 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -38606 # check output -38607 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") -38608 # . epilogue -38609 89/<- %esp 5/r32/ebp -38610 5d/pop-to-ebp -38611 c3/return -38612 -38613 test-emit-subx-stmt-function-call: -38614 # Call a function on a variable on the stack. -38615 # f foo -38616 # => -38617 # (f *(ebp-8)) -38618 # (Changing the function name supports overloading in general, but here it -38619 # just serves to help disambiguate things.) -38620 # -38621 # There's a variable on the var stack as follows: -38622 # name: 'foo' -38623 # type: int -38624 # stack-offset: -8 -38625 # -38626 # There's nothing in primitives. -38627 # -38628 # We don't perform any checking here on the type of 'f'. -38629 # -38630 # . prologue -38631 55/push-ebp -38632 89/<- %ebp 4/r32/esp -38633 # setup -38634 (clear-stream _test-output-stream) -38635 (clear-stream $_test-output-buffered-file->buffer) -38636 $test-emit-subx-function-call:initialize-type: -38637 # var type/ecx: (payload type-tree) = int -38638 68/push 0/imm32/right:null -38639 68/push 0/imm32/right:null -38640 68/push 0/imm32/left:unused -38641 68/push 1/imm32/value:int -38642 68/push 1/imm32/is-atom?:true -38643 68/push 0x11/imm32/alloc-id:fake:payload -38644 89/<- %ecx 4/r32/esp -38645 $test-emit-subx-function-call:initialize-var: -38646 # var var-foo/ecx: (payload var) = var(type) -38647 68/push 0/imm32/no-register -38648 68/push 0/imm32/no-register -38649 68/push -8/imm32/stack-offset -38650 68/push 1/imm32/block-depth -38651 51/push-ecx/type -38652 68/push 0x11/imm32/alloc-id:fake -38653 68/push 0/imm32/name -38654 68/push 0/imm32/name -38655 68/push 0x11/imm32/alloc-id:fake:payload -38656 89/<- %ecx 4/r32/esp -38657 $test-emit-subx-function-call:initialize-var-name: -38658 # var-foo->name = "foo" -38659 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -38660 (copy-array Heap "foo" %eax) -38661 $test-emit-subx-function-call:initialize-stmt-var: -38662 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -38663 68/push 0/imm32/is-deref:false -38664 68/push 0/imm32/next -38665 68/push 0/imm32/next -38666 51/push-ecx/var-foo -38667 68/push 0x11/imm32/alloc-id:fake -38668 68/push 0x11/imm32/alloc-id:fake:payload -38669 89/<- %ebx 4/r32/esp -38670 $test-emit-subx-function-call:initialize-stmt: -38671 # var stmt/esi: (addr statement) -38672 68/push 0/imm32/no-outputs -38673 68/push 0/imm32/no-outputs -38674 53/push-ebx/inouts -38675 68/push 0x11/imm32/alloc-id:fake -38676 68/push 0/imm32/operation -38677 68/push 0/imm32/operation -38678 68/push 1/imm32/tag -38679 89/<- %esi 4/r32/esp -38680 $test-emit-subx-function-call:initialize-stmt-operation: -38681 # stmt->operation = "f" -38682 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -38683 (copy-array Heap "f" %eax) -38684 # convert -38685 c7 0/subop/copy *Curr-block-depth 0/imm32 -38686 (emit-subx-stmt _test-output-buffered-file %esi 0 0 Stderr 0) -38687 (flush _test-output-buffered-file) -38688 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -38694 # check output -38695 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") -38696 # . epilogue -38697 89/<- %esp 5/r32/ebp -38698 5d/pop-to-ebp -38699 c3/return -38700 -38701 test-emit-subx-stmt-function-call-with-literal-arg: -38702 # Call a function on a literal. -38703 # f 0x34 -38704 # => -38705 # (f2 0x34) -38706 # -38707 # . prologue -38708 55/push-ebp -38709 89/<- %ebp 4/r32/esp -38710 # setup -38711 (clear-stream _test-output-stream) -38712 (clear-stream $_test-output-buffered-file->buffer) -38713 $test-emit-subx-function-call-with-literal-arg:initialize-type: -38714 # var type/ecx: (payload type-tree) = int -38715 68/push 0/imm32/right:null -38716 68/push 0/imm32/right:null -38717 68/push 0/imm32/left:unused -38718 68/push 0/imm32/value:literal -38719 68/push 1/imm32/is-atom?:true -38720 68/push 0x11/imm32/alloc-id:fake:payload -38721 89/<- %ecx 4/r32/esp -38722 $test-emit-subx-function-call-with-literal-arg:initialize-var: -38723 # var var-foo/ecx: (payload var) = var(lit) -38724 68/push 0/imm32/no-register -38725 68/push 0/imm32/no-register -38726 68/push 0/imm32/no-stack-offset -38727 68/push 1/imm32/block-depth -38728 51/push-ecx/type -38729 68/push 0x11/imm32/alloc-id:fake -38730 68/push 0/imm32/name -38731 68/push 0/imm32/name -38732 68/push 0x11/imm32/alloc-id:fake:payload -38733 89/<- %ecx 4/r32/esp -38734 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: -38735 # var-foo->name = "0x34" -38736 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -38737 (copy-array Heap "0x34" %eax) -38738 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: -38739 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -38740 68/push 0/imm32/is-deref:false -38741 68/push 0/imm32/next -38742 68/push 0/imm32/next -38743 51/push-ecx/var-foo -38744 68/push 0x11/imm32/alloc-id:fake -38745 68/push 0x11/imm32/alloc-id:fake:payload -38746 89/<- %ebx 4/r32/esp -38747 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: -38748 # var stmt/esi: (addr statement) -38749 68/push 0/imm32/no-outputs -38750 68/push 0/imm32/no-outputs -38751 53/push-ebx/inouts -38752 68/push 0x11/imm32/alloc-id:fake -38753 68/push 0/imm32/operation -38754 68/push 0/imm32/operation -38755 68/push 1/imm32/tag -38756 89/<- %esi 4/r32/esp -38757 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: -38758 # stmt->operation = "f" -38759 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -38760 (copy-array Heap "f" %eax) -38761 # convert -38762 c7 0/subop/copy *Curr-block-depth 0/imm32 -38763 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx 0 Stderr 0) -38764 (flush _test-output-buffered-file) -38765 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -38771 # check output -38772 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") -38773 # . epilogue -38774 89/<- %esp 5/r32/ebp -38775 5d/pop-to-ebp -38776 c3/return -38777 -38778 emit-indent: # out: (addr buffered-file), n: int -38779 # . prologue -38780 55/push-ebp -38781 89/<- %ebp 4/r32/esp -38782 # . save registers -38783 50/push-eax -38784 # var i/eax: int = n -38785 8b/-> *(ebp+0xc) 0/r32/eax -38786 { -38787 # if (i <= 0) break -38788 3d/compare-eax-with 0/imm32 -38789 7e/jump-if-<= break/disp8 -38790 (write-buffered *(ebp+8) " ") -38791 48/decrement-eax -38792 eb/jump loop/disp8 -38793 } -38794 $emit-indent:end: -38795 # . restore registers -38796 58/pop-to-eax -38797 # . epilogue -38798 89/<- %esp 5/r32/ebp -38799 5d/pop-to-ebp -38800 c3/return -38801 -38802 emit-subx-prologue: # out: (addr buffered-file) -38803 # . prologue -38804 55/push-ebp -38805 89/<- %ebp 4/r32/esp -38806 # -38807 (write-buffered *(ebp+8) " # . prologue\n") -38808 (write-buffered *(ebp+8) " 55/push-ebp\n") -38809 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") -38810 $emit-subx-prologue:end: -38811 # . epilogue -38812 89/<- %esp 5/r32/ebp -38813 5d/pop-to-ebp -38814 c3/return -38815 -38816 emit-subx-epilogue: # out: (addr buffered-file) -38817 # . prologue -38818 55/push-ebp -38819 89/<- %ebp 4/r32/esp -38820 # -38821 (write-buffered *(ebp+8) " # . epilogue\n") -38822 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") -38823 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") -38824 (write-buffered *(ebp+8) " c3/return\n") -38825 $emit-subx-epilogue:end: -38826 # . epilogue -38827 89/<- %esp 5/r32/ebp -38828 5d/pop-to-ebp -38829 c3/return +38348 68/push 0/imm32/name +38349 68/push 0/imm32/name +38350 68/push 0x11/imm32/alloc-id:fake:payload +38351 89/<- %ecx 4/r32/esp +38352 $test-compare-mem-with-literal:initialize-var1-name: +38353 # var1->name = "var1" +38354 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +38355 (copy-array Heap "var1" %eax) +38356 $test-compare-mem-with-literal:initialize-literal-type: +38357 # var type/edx: (payload type-tree) = literal +38358 68/push 0/imm32/right:null +38359 68/push 0/imm32/right:null +38360 68/push 0/imm32/left:unused +38361 68/push 0/imm32/value:literal +38362 68/push 1/imm32/is-atom?:true +38363 68/push 0x11/imm32/alloc-id:fake:payload +38364 89/<- %edx 4/r32/esp +38365 $test-compare-mem-with-literal:initialize-literal: +38366 # var l/edx: (payload var) +38367 68/push 0/imm32/register +38368 68/push 0/imm32/register +38369 68/push 0/imm32/no-stack-offset +38370 68/push 1/imm32/block-depth +38371 52/push-edx +38372 68/push 0x11/imm32/alloc-id:fake +38373 68/push 0/imm32/name +38374 68/push 0/imm32/name +38375 68/push 0x11/imm32/alloc-id:fake:payload +38376 89/<- %edx 4/r32/esp +38377 $test-compare-mem-with-literal:initialize-literal-value: +38378 # l->name = "0x34" +38379 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +38380 (copy-array Heap "0x34" %eax) +38381 $test-compare-mem-with-literal:initialize-inouts: +38382 # var inouts/esi: (payload stmt-var) = [l] +38383 68/push 0/imm32/is-deref:false +38384 68/push 0/imm32/next +38385 68/push 0/imm32/next +38386 52/push-edx/l +38387 68/push 0x11/imm32/alloc-id:fake +38388 68/push 0x11/imm32/alloc-id:fake:payload +38389 89/<- %esi 4/r32/esp +38390 # var inouts = (handle stmt-var) = [var1, var2] +38391 68/push 0/imm32/is-deref:false +38392 56/push-esi/next +38393 68/push 0x11/imm32/alloc-id:fake +38394 51/push-ecx/var1 +38395 68/push 0x11/imm32/alloc-id:fake +38396 68/push 0x11/imm32/alloc-id:fake:payload +38397 89/<- %esi 4/r32/esp +38398 $test-compare-mem-with-literal:initialize-stmt: +38399 # var stmt/esi: (addr statement) +38400 68/push 0/imm32/next +38401 68/push 0/imm32/next +38402 68/push 0/imm32/outputs +38403 68/push 0/imm32/outputs +38404 56/push-esi/inouts +38405 68/push 0x11/imm32/alloc-id:fake +38406 68/push 0/imm32/operation +38407 68/push 0/imm32/operation +38408 68/push 1/imm32/tag:stmt1 +38409 89/<- %esi 4/r32/esp +38410 $test-compare-mem-with-literal:initialize-stmt-operation: +38411 # stmt->operation = "compare" +38412 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +38413 (copy-array Heap "compare" %eax) +38414 # convert +38415 c7 0/subop/copy *Curr-block-depth 0/imm32 +38416 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +38417 (flush _test-output-buffered-file) +38418 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +38424 # check output +38425 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") +38426 # . epilogue +38427 89/<- %esp 5/r32/ebp +38428 5d/pop-to-ebp +38429 c3/return +38430 +38431 test-compare-eax-with-literal: +38432 # compare var1/eax 0x34 +38433 # => +38434 # 3d/compare-eax-with 0x34/imm32 +38435 # +38436 # . prologue +38437 55/push-ebp +38438 89/<- %ebp 4/r32/esp +38439 # setup +38440 (clear-stream _test-output-stream) +38441 (clear-stream $_test-output-buffered-file->buffer) +38442 $test-compare-eax-with-literal:initialize-type: +38443 # var type/ecx: (payload type-tree) = int +38444 68/push 0/imm32/right:null +38445 68/push 0/imm32/right:null +38446 68/push 0/imm32/left:unused +38447 68/push 1/imm32/value:int +38448 68/push 1/imm32/is-atom?:true +38449 68/push 0x11/imm32/alloc-id:fake:payload +38450 89/<- %ecx 4/r32/esp +38451 $test-compare-eax-with-literal:initialize-var1: +38452 # var var1/ecx: (payload var) +38453 68/push 0/imm32/register +38454 68/push 0/imm32/register +38455 68/push 0/imm32/no-stack-offset +38456 68/push 1/imm32/block-depth +38457 51/push-ecx +38458 68/push 0x11/imm32/alloc-id:fake +38459 68/push 0/imm32/name +38460 68/push 0/imm32/name +38461 68/push 0x11/imm32/alloc-id:fake:payload +38462 89/<- %ecx 4/r32/esp +38463 $test-compare-eax-with-literal:initialize-var1-name: +38464 # var1->name = "var1" +38465 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +38466 (copy-array Heap "var1" %eax) +38467 $test-compare-eax-with-literal:initialize-var1-register: +38468 # v->register = "eax" +38469 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +38470 (copy-array Heap "eax" %eax) +38471 $test-compare-eax-with-literal:initialize-literal-type: +38472 # var type/edx: (payload type-tree) = literal +38473 68/push 0/imm32/right:null +38474 68/push 0/imm32/right:null +38475 68/push 0/imm32/left:unused +38476 68/push 0/imm32/value:literal +38477 68/push 1/imm32/is-atom?:true +38478 68/push 0x11/imm32/alloc-id:fake:payload +38479 89/<- %edx 4/r32/esp +38480 $test-compare-eax-with-literal:initialize-literal: +38481 # var l/edx: (payload var) +38482 68/push 0/imm32/register +38483 68/push 0/imm32/register +38484 68/push 0/imm32/no-stack-offset +38485 68/push 1/imm32/block-depth +38486 52/push-edx +38487 68/push 0x11/imm32/alloc-id:fake +38488 68/push 0/imm32/name +38489 68/push 0/imm32/name +38490 68/push 0x11/imm32/alloc-id:fake:payload +38491 89/<- %edx 4/r32/esp +38492 $test-compare-eax-with-literal:initialize-literal-value: +38493 # l->name = "0x34" +38494 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +38495 (copy-array Heap "0x34" %eax) +38496 $test-compare-eax-with-literal:initialize-inouts: +38497 # var inouts/esi: (payload stmt-var) = [l] +38498 68/push 0/imm32/is-deref:false +38499 68/push 0/imm32/next +38500 68/push 0/imm32/next +38501 52/push-edx/l +38502 68/push 0x11/imm32/alloc-id:fake +38503 68/push 0x11/imm32/alloc-id:fake:payload +38504 89/<- %esi 4/r32/esp +38505 # var inouts = (handle stmt-var) = [var1, var2] +38506 68/push 0/imm32/is-deref:false +38507 56/push-esi/next +38508 68/push 0x11/imm32/alloc-id:fake +38509 51/push-ecx/var1 +38510 68/push 0x11/imm32/alloc-id:fake +38511 68/push 0x11/imm32/alloc-id:fake:payload +38512 89/<- %esi 4/r32/esp +38513 $test-compare-eax-with-literal:initialize-stmt: +38514 # var stmt/esi: (addr statement) +38515 68/push 0/imm32/next +38516 68/push 0/imm32/next +38517 68/push 0/imm32/outputs +38518 68/push 0/imm32/outputs +38519 56/push-esi/inouts +38520 68/push 0x11/imm32/alloc-id:fake +38521 68/push 0/imm32/operation +38522 68/push 0/imm32/operation +38523 68/push 1/imm32/tag:stmt1 +38524 89/<- %esi 4/r32/esp +38525 $test-compare-eax-with-literal:initialize-stmt-operation: +38526 # stmt->operation = "compare" +38527 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +38528 (copy-array Heap "compare" %eax) +38529 # convert +38530 c7 0/subop/copy *Curr-block-depth 0/imm32 +38531 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +38532 (flush _test-output-buffered-file) +38533 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +38539 # check output +38540 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") +38541 # . epilogue +38542 89/<- %esp 5/r32/ebp +38543 5d/pop-to-ebp +38544 c3/return +38545 +38546 test-compare-reg-with-literal: +38547 # compare var1/ecx 0x34 +38548 # => +38549 # 81 7/subop/compare %ecx 0x34/imm32 +38550 # +38551 # . prologue +38552 55/push-ebp +38553 89/<- %ebp 4/r32/esp +38554 # setup +38555 (clear-stream _test-output-stream) +38556 (clear-stream $_test-output-buffered-file->buffer) +38557 $test-compare-reg-with-literal:initialize-type: +38558 # var type/ecx: (payload type-tree) = int +38559 68/push 0/imm32/right:null +38560 68/push 0/imm32/right:null +38561 68/push 0/imm32/left:unused +38562 68/push 1/imm32/value:int +38563 68/push 1/imm32/is-atom?:true +38564 68/push 0x11/imm32/alloc-id:fake:payload +38565 89/<- %ecx 4/r32/esp +38566 $test-compare-reg-with-literal:initialize-var1: +38567 # var var1/ecx: (payload var) +38568 68/push 0/imm32/register +38569 68/push 0/imm32/register +38570 68/push 0/imm32/no-stack-offset +38571 68/push 1/imm32/block-depth +38572 51/push-ecx +38573 68/push 0x11/imm32/alloc-id:fake +38574 68/push 0/imm32/name +38575 68/push 0/imm32/name +38576 68/push 0x11/imm32/alloc-id:fake:payload +38577 89/<- %ecx 4/r32/esp +38578 $test-compare-reg-with-literal:initialize-var1-name: +38579 # var1->name = "var1" +38580 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +38581 (copy-array Heap "var1" %eax) +38582 $test-compare-reg-with-literal:initialize-var1-register: +38583 # v->register = "ecx" +38584 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +38585 (copy-array Heap "ecx" %eax) +38586 $test-compare-reg-with-literal:initialize-literal-type: +38587 # var type/edx: (payload type-tree) = literal +38588 68/push 0/imm32/right:null +38589 68/push 0/imm32/right:null +38590 68/push 0/imm32/left:unused +38591 68/push 0/imm32/value:literal +38592 68/push 1/imm32/is-atom?:true +38593 68/push 0x11/imm32/alloc-id:fake:payload +38594 89/<- %edx 4/r32/esp +38595 $test-compare-reg-with-literal:initialize-literal: +38596 # var l/edx: (payload var) +38597 68/push 0/imm32/register +38598 68/push 0/imm32/register +38599 68/push 0/imm32/no-stack-offset +38600 68/push 1/imm32/block-depth +38601 52/push-edx +38602 68/push 0x11/imm32/alloc-id:fake +38603 68/push 0/imm32/name +38604 68/push 0/imm32/name +38605 68/push 0x11/imm32/alloc-id:fake:payload +38606 89/<- %edx 4/r32/esp +38607 $test-compare-reg-with-literal:initialize-literal-value: +38608 # l->name = "0x34" +38609 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +38610 (copy-array Heap "0x34" %eax) +38611 $test-compare-reg-with-literal:initialize-inouts: +38612 # var inouts/esi: (payload stmt-var) = [l] +38613 68/push 0/imm32/is-deref:false +38614 68/push 0/imm32/next +38615 68/push 0/imm32/next +38616 52/push-edx/l +38617 68/push 0x11/imm32/alloc-id:fake +38618 68/push 0x11/imm32/alloc-id:fake:payload +38619 89/<- %esi 4/r32/esp +38620 # var inouts = (handle stmt-var) = [var1, var2] +38621 68/push 0/imm32/is-deref:false +38622 56/push-esi/next +38623 68/push 0x11/imm32/alloc-id:fake +38624 51/push-ecx/var1 +38625 68/push 0x11/imm32/alloc-id:fake +38626 68/push 0x11/imm32/alloc-id:fake:payload +38627 89/<- %esi 4/r32/esp +38628 $test-compare-reg-with-literal:initialize-stmt: +38629 # var stmt/esi: (addr statement) +38630 68/push 0/imm32/next +38631 68/push 0/imm32/next +38632 68/push 0/imm32/outputs +38633 68/push 0/imm32/outputs +38634 56/push-esi/inouts +38635 68/push 0x11/imm32/alloc-id:fake +38636 68/push 0/imm32/operation +38637 68/push 0/imm32/operation +38638 68/push 1/imm32/tag:stmt1 +38639 89/<- %esi 4/r32/esp +38640 $test-compare-reg-with-literal:initialize-stmt-operation: +38641 # stmt->operation = "compare" +38642 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +38643 (copy-array Heap "compare" %eax) +38644 # convert +38645 c7 0/subop/copy *Curr-block-depth 0/imm32 +38646 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0) +38647 (flush _test-output-buffered-file) +38648 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +38654 # check output +38655 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") +38656 # . epilogue +38657 89/<- %esp 5/r32/ebp +38658 5d/pop-to-ebp +38659 c3/return +38660 +38661 test-emit-subx-stmt-function-call: +38662 # Call a function on a variable on the stack. +38663 # f foo +38664 # => +38665 # (f *(ebp-8)) +38666 # (Changing the function name supports overloading in general, but here it +38667 # just serves to help disambiguate things.) +38668 # +38669 # There's a variable on the var stack as follows: +38670 # name: 'foo' +38671 # type: int +38672 # stack-offset: -8 +38673 # +38674 # There's nothing in primitives. +38675 # +38676 # We don't perform any checking here on the type of 'f'. +38677 # +38678 # . prologue +38679 55/push-ebp +38680 89/<- %ebp 4/r32/esp +38681 # setup +38682 (clear-stream _test-output-stream) +38683 (clear-stream $_test-output-buffered-file->buffer) +38684 $test-emit-subx-function-call:initialize-type: +38685 # var type/ecx: (payload type-tree) = int +38686 68/push 0/imm32/right:null +38687 68/push 0/imm32/right:null +38688 68/push 0/imm32/left:unused +38689 68/push 1/imm32/value:int +38690 68/push 1/imm32/is-atom?:true +38691 68/push 0x11/imm32/alloc-id:fake:payload +38692 89/<- %ecx 4/r32/esp +38693 $test-emit-subx-function-call:initialize-var: +38694 # var var-foo/ecx: (payload var) = var(type) +38695 68/push 0/imm32/no-register +38696 68/push 0/imm32/no-register +38697 68/push -8/imm32/stack-offset +38698 68/push 1/imm32/block-depth +38699 51/push-ecx/type +38700 68/push 0x11/imm32/alloc-id:fake +38701 68/push 0/imm32/name +38702 68/push 0/imm32/name +38703 68/push 0x11/imm32/alloc-id:fake:payload +38704 89/<- %ecx 4/r32/esp +38705 $test-emit-subx-function-call:initialize-var-name: +38706 # var-foo->name = "foo" +38707 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +38708 (copy-array Heap "foo" %eax) +38709 $test-emit-subx-function-call:initialize-stmt-var: +38710 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +38711 68/push 0/imm32/is-deref:false +38712 68/push 0/imm32/next +38713 68/push 0/imm32/next +38714 51/push-ecx/var-foo +38715 68/push 0x11/imm32/alloc-id:fake +38716 68/push 0x11/imm32/alloc-id:fake:payload +38717 89/<- %ebx 4/r32/esp +38718 $test-emit-subx-function-call:initialize-stmt: +38719 # var stmt/esi: (addr statement) +38720 68/push 0/imm32/no-outputs +38721 68/push 0/imm32/no-outputs +38722 53/push-ebx/inouts +38723 68/push 0x11/imm32/alloc-id:fake +38724 68/push 0/imm32/operation +38725 68/push 0/imm32/operation +38726 68/push 1/imm32/tag +38727 89/<- %esi 4/r32/esp +38728 $test-emit-subx-function-call:initialize-stmt-operation: +38729 # stmt->operation = "f" +38730 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +38731 (copy-array Heap "f" %eax) +38732 # convert +38733 c7 0/subop/copy *Curr-block-depth 0/imm32 +38734 (emit-subx-stmt _test-output-buffered-file %esi 0 0 Stderr 0) +38735 (flush _test-output-buffered-file) +38736 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +38742 # check output +38743 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") +38744 # . epilogue +38745 89/<- %esp 5/r32/ebp +38746 5d/pop-to-ebp +38747 c3/return +38748 +38749 test-emit-subx-stmt-function-call-with-literal-arg: +38750 # Call a function on a literal. +38751 # f 0x34 +38752 # => +38753 # (f2 0x34) +38754 # +38755 # . prologue +38756 55/push-ebp +38757 89/<- %ebp 4/r32/esp +38758 # setup +38759 (clear-stream _test-output-stream) +38760 (clear-stream $_test-output-buffered-file->buffer) +38761 $test-emit-subx-function-call-with-literal-arg:initialize-type: +38762 # var type/ecx: (payload type-tree) = int +38763 68/push 0/imm32/right:null +38764 68/push 0/imm32/right:null +38765 68/push 0/imm32/left:unused +38766 68/push 0/imm32/value:literal +38767 68/push 1/imm32/is-atom?:true +38768 68/push 0x11/imm32/alloc-id:fake:payload +38769 89/<- %ecx 4/r32/esp +38770 $test-emit-subx-function-call-with-literal-arg:initialize-var: +38771 # var var-foo/ecx: (payload var) = var(lit) +38772 68/push 0/imm32/no-register +38773 68/push 0/imm32/no-register +38774 68/push 0/imm32/no-stack-offset +38775 68/push 1/imm32/block-depth +38776 51/push-ecx/type +38777 68/push 0x11/imm32/alloc-id:fake +38778 68/push 0/imm32/name +38779 68/push 0/imm32/name +38780 68/push 0x11/imm32/alloc-id:fake:payload +38781 89/<- %ecx 4/r32/esp +38782 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: +38783 # var-foo->name = "0x34" +38784 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +38785 (copy-array Heap "0x34" %eax) +38786 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: +38787 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +38788 68/push 0/imm32/is-deref:false +38789 68/push 0/imm32/next +38790 68/push 0/imm32/next +38791 51/push-ecx/var-foo +38792 68/push 0x11/imm32/alloc-id:fake +38793 68/push 0x11/imm32/alloc-id:fake:payload +38794 89/<- %ebx 4/r32/esp +38795 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: +38796 # var stmt/esi: (addr statement) +38797 68/push 0/imm32/no-outputs +38798 68/push 0/imm32/no-outputs +38799 53/push-ebx/inouts +38800 68/push 0x11/imm32/alloc-id:fake +38801 68/push 0/imm32/operation +38802 68/push 0/imm32/operation +38803 68/push 1/imm32/tag +38804 89/<- %esi 4/r32/esp +38805 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: +38806 # stmt->operation = "f" +38807 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +38808 (copy-array Heap "f" %eax) +38809 # convert +38810 c7 0/subop/copy *Curr-block-depth 0/imm32 +38811 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx 0 Stderr 0) +38812 (flush _test-output-buffered-file) +38813 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +38819 # check output +38820 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") +38821 # . epilogue +38822 89/<- %esp 5/r32/ebp +38823 5d/pop-to-ebp +38824 c3/return +38825 +38826 emit-indent: # out: (addr buffered-file), n: int +38827 # . prologue +38828 55/push-ebp +38829 89/<- %ebp 4/r32/esp +38830 # . save registers +38831 50/push-eax +38832 # var i/eax: int = n +38833 8b/-> *(ebp+0xc) 0/r32/eax +38834 { +38835 # if (i <= 0) break +38836 3d/compare-eax-with 0/imm32 +38837 7e/jump-if-<= break/disp8 +38838 (write-buffered *(ebp+8) " ") +38839 48/decrement-eax +38840 eb/jump loop/disp8 +38841 } +38842 $emit-indent:end: +38843 # . restore registers +38844 58/pop-to-eax +38845 # . epilogue +38846 89/<- %esp 5/r32/ebp +38847 5d/pop-to-ebp +38848 c3/return +38849 +38850 emit-subx-prologue: # out: (addr buffered-file) +38851 # . prologue +38852 55/push-ebp +38853 89/<- %ebp 4/r32/esp +38854 # +38855 (write-buffered *(ebp+8) " # . prologue\n") +38856 (write-buffered *(ebp+8) " 55/push-ebp\n") +38857 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") +38858 $emit-subx-prologue:end: +38859 # . epilogue +38860 89/<- %esp 5/r32/ebp +38861 5d/pop-to-ebp +38862 c3/return +38863 +38864 emit-subx-epilogue: # out: (addr buffered-file) +38865 # . prologue +38866 55/push-ebp +38867 89/<- %ebp 4/r32/esp +38868 # +38869 (write-buffered *(ebp+8) " # . epilogue\n") +38870 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") +38871 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") +38872 (write-buffered *(ebp+8) " c3/return\n") +38873 $emit-subx-epilogue:end: +38874 # . epilogue +38875 89/<- %esp 5/r32/ebp +38876 5d/pop-to-ebp +38877 c3/return diff --git a/html/mandelbrot-fixed.mu.html b/html/mandelbrot-fixed.mu.html index 3e4b205e..14e423d1 100644 --- a/html/mandelbrot-fixed.mu.html +++ b/html/mandelbrot-fixed.mu.html @@ -14,14 +14,20 @@ pre { white-space: pre-wrap; font-family: monospace; color: #000000; background- body { font-size:12pt; font-family: monospace; color: #000000; background-color: #a8a8a8; } a { color:inherit; } * { font-size:12pt; font-size: 1em; } -.PreProc { color: #c000c0; } -.Special { color: #ff6060; } .LineNr { } -.Constant { color: #008787; } .Delimiter { color: #c000c0; } +.muRegEdx { color: #878700; } +.muRegEbx { color: #8787af; } +.muRegEsi { color: #87d787; } +.muRegEdi { color: #87ffd7; } +.Constant { color: #008787; } +.Special { color: #ff6060; } +.PreProc { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muTest { color: #5f8700; } .muComment { color: #005faf; } +.muRegEax { color: #875f00; } +.muRegEcx { color: #af875f; } --> @@ -79,11 +85,11 @@ if ('onhashchange' in window) { 20 { 21 mandelbrot screen scene-cx-f, scene-cy-f, scene-width-f 22 # move at an angle slowly towards the edge - 23 var adj-f/eax: int <- multiply-fixed scene-width-f, 0x12/0.07 + 23 var adj-f/eax: int <- multiply-fixed scene-width-f, 0x12/0.07 24 subtract-from scene-cx-f, adj-f 25 add-to scene-cy-f, adj-f 26 # slowly shrink the scene width to zoom in - 27 var tmp-f/eax: int <- multiply-fixed scene-width-f, 0x80/0.5 + 27 var tmp-f/eax: int <- multiply-fixed scene-width-f, 0x80/0.5 28 copy-to scene-width-f, tmp-f 29 loop 30 } @@ -92,8 +98,8 @@ if ('onhashchange' in window) { 33 # Since they still look like int types, we'll append a '-f' suffix to variable 34 # names to designate fixed-point numbers. 35 - 36 fn int-to-fixed in: int -> _/eax: int { - 37 var result-f/eax: int <- copy in + 36 fn int-to-fixed in: int -> _/eax: int { + 37 var result-f/eax: int <- copy in 38 result-f <- shift-left 8/fixed-precision 39 { 40 break-if-not-overflow @@ -102,8 +108,8 @@ if ('onhashchange' in window) { 43 return result-f 44 } 45 - 46 fn fixed-to-int in-f: int -> _/eax: int { - 47 var result/eax: int <- copy in-f + 46 fn fixed-to-int in-f: int -> _/eax: int { + 47 var result/eax: int <- copy in-f 48 result <- shift-right-signed 8/fixed-precision 49 return result 50 } @@ -111,53 +117,53 @@ if ('onhashchange' in window) { 52 # The process of throwing bits away always adjusts a number towards -infinity. 53 fn test-fixed-conversion { 54 # 0 - 55 var f/eax: int <- int-to-fixed 0 - 56 var result/eax: int <- fixed-to-int f + 55 var f/eax: int <- int-to-fixed 0 + 56 var result/eax: int <- fixed-to-int f 57 check-ints-equal result, 0, "F - test-fixed-conversion - 0" 58 # 1 - 59 var f/eax: int <- int-to-fixed 1 - 60 var result/eax: int <- fixed-to-int f + 59 var f/eax: int <- int-to-fixed 1 + 60 var result/eax: int <- fixed-to-int f 61 check-ints-equal result, 1, "F - test-fixed-conversion - 1" 62 # -1 - 63 var f/eax: int <- int-to-fixed -1 - 64 var result/eax: int <- fixed-to-int f + 63 var f/eax: int <- int-to-fixed -1 + 64 var result/eax: int <- fixed-to-int f 65 check-ints-equal result, -1, "F - test-fixed-conversion - -1" 66 # 0.5 = 1/2 - 67 var f/eax: int <- int-to-fixed 1 + 67 var f/eax: int <- int-to-fixed 1 68 f <- shift-right-signed 1 - 69 var result/eax: int <- fixed-to-int f + 69 var result/eax: int <- fixed-to-int f 70 check-ints-equal result, 0, "F - test-fixed-conversion - 0.5" 71 # -0.5 = -1/2 - 72 var f/eax: int <- int-to-fixed -1 + 72 var f/eax: int <- int-to-fixed -1 73 f <- shift-right-signed 1 - 74 var result/eax: int <- fixed-to-int f + 74 var result/eax: int <- fixed-to-int f 75 check-ints-equal result, -1, "F - test-fixed-conversion - -0.5" 76 # 1.5 = 3/2 - 77 var f/eax: int <- int-to-fixed 3 + 77 var f/eax: int <- int-to-fixed 3 78 f <- shift-right-signed 1 - 79 var result/eax: int <- fixed-to-int f + 79 var result/eax: int <- fixed-to-int f 80 check-ints-equal result, 1, "F - test-fixed-conversion - 1.5" 81 # -1.5 = -3/2 - 82 var f/eax: int <- int-to-fixed -3 + 82 var f/eax: int <- int-to-fixed -3 83 f <- shift-right-signed 1 - 84 var result/eax: int <- fixed-to-int f + 84 var result/eax: int <- fixed-to-int f 85 check-ints-equal result, -2, "F - test-fixed-conversion - -1.5" 86 # 1.25 = 5/4 - 87 var f/eax: int <- int-to-fixed 5 + 87 var f/eax: int <- int-to-fixed 5 88 f <- shift-right-signed 2 - 89 var result/eax: int <- fixed-to-int f + 89 var result/eax: int <- fixed-to-int f 90 check-ints-equal result, 1, "F - test-fixed-conversion - 1.25" 91 # -1.25 = -5/4 - 92 var f/eax: int <- int-to-fixed -5 + 92 var f/eax: int <- int-to-fixed -5 93 f <- shift-right-signed 2 - 94 var result/eax: int <- fixed-to-int f + 94 var result/eax: int <- fixed-to-int f 95 check-ints-equal result, -2, "F - test-fixed-conversion - -1.25" 96 } 97 98 # special routines for multiplying and dividing fixed-point numbers 99 -100 fn multiply-fixed a-f: int, b-f: int -> _/eax: int { -101 var result/eax: int <- copy a-f +100 fn multiply-fixed a-f: int, b-f: int -> _/eax: int { +101 var result/eax: int <- copy a-f 102 result <- multiply b-f 103 { 104 break-if-not-overflow @@ -167,14 +173,14 @@ if ('onhashchange' in window) { 108 return result 109 } 110 -111 fn divide-fixed a-f: int, b-f: int -> _/eax: int { -112 var result-f/eax: int <- copy a-f +111 fn divide-fixed a-f: int, b-f: int -> _/eax: int { +112 var result-f/eax: int <- copy a-f 113 result-f <- shift-left 8/fixed-precision 114 { 115 break-if-not-overflow 116 abort "divide-fixed: overflow" 117 } -118 var dummy-remainder/edx: int <- copy 0 +118 var dummy-remainder/edx: int <- copy 0 119 result-f, dummy-remainder <- integer-divide result-f, b-f 120 return result-f 121 } @@ -184,32 +190,32 @@ if ('onhashchange' in window) { 125 # adding and subtracting two fixed-point numbers can use existing instructions. 126 127 fn mandelbrot screen: (addr screen), scene-cx-f: int, scene-cy-f: int, scene-width-f: int { -128 var a/eax: int <- copy 0 -129 var b/ecx: int <- copy 0 -130 a, b <- screen-size screen -131 var width/esi: int <- copy a +128 var a/eax: int <- copy 0 +129 var b/ecx: int <- copy 0 +130 a, b <- screen-size screen +131 var width/esi: int <- copy a 132 width <- shift-left 3/log2-font-width -133 var height/edi: int <- copy b +133 var height/edi: int <- copy b 134 height <- shift-left 4/log2-font-height -135 var y/ecx: int <- copy 0 +135 var y/ecx: int <- copy 0 136 { 137 compare y, height 138 break-if->= -139 var imaginary-f/ebx: int <- viewport-to-imaginary-f y, width, height, scene-cy-f, scene-width-f -140 var x/eax: int <- copy 0 +139 var imaginary-f/ebx: int <- viewport-to-imaginary-f y, width, height, scene-cy-f, scene-width-f +140 var x/eax: int <- copy 0 141 { 142 compare x, width 143 break-if->= -144 var real-f/edx: int <- viewport-to-real-f x, width, scene-cx-f, scene-width-f -145 var iterations/esi: int <- mandelbrot-iterations-for-point real-f, imaginary-f, 0x400/max +144 var real-f/edx: int <- viewport-to-real-f x, width, scene-cx-f, scene-width-f +145 var iterations/esi: int <- mandelbrot-iterations-for-point real-f, imaginary-f, 0x400/max 146 iterations <- shift-right 3 -147 var color/edx: int <- copy 0 +147 var color/edx: int <- copy 0 148 { -149 var dummy/eax: int <- copy 0 +149 var dummy/eax: int <- copy 0 150 dummy, color <- integer-divide iterations, 0x18/24/size-of-cycle-0 151 color <- add 0x20/cycle-0 152 } -153 pixel screen, x, y, color +153 pixel screen, x, y, color 154 x <- increment 155 loop 156 } @@ -218,18 +224,18 @@ if ('onhashchange' in window) { 159 } 160 } 161 -162 fn mandelbrot-iterations-for-point real-f: int, imaginary-f: int, max: int -> _/esi: int { -163 var x-f/esi: int <- copy 0 -164 var y-f/edi: int <- copy 0 -165 var iterations/ecx: int <- copy 0 +162 fn mandelbrot-iterations-for-point real-f: int, imaginary-f: int, max: int -> _/esi: int { +163 var x-f/esi: int <- copy 0 +164 var y-f/edi: int <- copy 0 +165 var iterations/ecx: int <- copy 0 166 { -167 var done?/eax: boolean <- mandelbrot-done? x-f, y-f +167 var done?/eax: boolean <- mandelbrot-done? x-f, y-f 168 compare done?, 0/false 169 break-if-!= 170 compare iterations, max 171 break-if->= -172 var x2-f/edx: int <- mandelbrot-x x-f, y-f, real-f -173 var y2-f/ebx: int <- mandelbrot-y x-f, y-f, imaginary-f +172 var x2-f/edx: int <- mandelbrot-x x-f, y-f, real-f +173 var y2-f/ebx: int <- mandelbrot-y x-f, y-f, imaginary-f 174 x-f <- copy x2-f 175 y-f <- copy y2-f 176 iterations <- increment @@ -238,10 +244,10 @@ if ('onhashchange' in window) { 179 return iterations 180 } 181 -182 fn mandelbrot-done? x-f: int, y-f: int -> _/eax: boolean { +182 fn mandelbrot-done? x-f: int, y-f: int -> _/eax: boolean { 183 # x*x + y*y > 4 -184 var tmp-f/eax: int <- multiply-fixed x-f, x-f -185 var result-f/ecx: int <- copy tmp-f +184 var tmp-f/eax: int <- multiply-fixed x-f, x-f +185 var result-f/ecx: int <- copy tmp-f 186 tmp-f <- multiply-fixed y-f, y-f 187 result-f <- add tmp-f 188 compare result-f, 0x400/4 @@ -252,19 +258,19 @@ if ('onhashchange' in window) { 193 return 1/true 194 } 195 -196 fn mandelbrot-x x-f: int, y-f: int, real-f: int -> _/edx: int { +196 fn mandelbrot-x x-f: int, y-f: int, real-f: int -> _/edx: int { 197 # x*x - y*y + real -198 var tmp-f/eax: int <- multiply-fixed x-f, x-f -199 var result-f/ecx: int <- copy tmp-f +198 var tmp-f/eax: int <- multiply-fixed x-f, x-f +199 var result-f/ecx: int <- copy tmp-f 200 tmp-f <- multiply-fixed y-f, y-f 201 result-f <- subtract tmp-f 202 result-f <- add real-f 203 return result-f 204 } 205 -206 fn mandelbrot-y x-f: int, y-f: int, imaginary-f: int -> _/ebx: int { +206 fn mandelbrot-y x-f: int, y-f: int, imaginary-f: int -> _/ebx: int { 207 # 2*x*y + imaginary -208 var result-f/eax: int <- copy x-f +208 var result-f/eax: int <- copy x-f 209 result-f <- shift-left 1/log2 210 result-f <- multiply-fixed result-f, y-f 211 result-f <- add imaginary-f @@ -275,42 +281,42 @@ if ('onhashchange' in window) { 216 # ranges from -2 to +2. Viewport height just follows the viewport's aspect 217 # ratio. 218 -219 fn viewport-to-real-f x: int, width: int, scene-cx-f: int, scene-width-f: int -> _/edx: int { +219 fn viewport-to-real-f x: int, width: int, scene-cx-f: int, scene-width-f: int -> _/edx: int { 220 # 0 in the viewport goes to scene-cx - scene-width/2 221 # width in the viewport goes to scene-cx + scene-width/2 222 # Therefore: 223 # x in the viewport goes to (scene-cx - scene-width/2) + x*scene-width/width 224 # At most two numbers being multiplied before a divide, so no risk of overflow. -225 var result-f/eax: int <- int-to-fixed x +225 var result-f/eax: int <- int-to-fixed x 226 result-f <- multiply-fixed result-f, scene-width-f -227 var width-f/ecx: int <- copy width +227 var width-f/ecx: int <- copy width 228 width-f <- shift-left 8/fixed-precision 229 result-f <- divide-fixed result-f, width-f 230 result-f <- add scene-cx-f -231 var half-scene-width-f/ecx: int <- copy scene-width-f +231 var half-scene-width-f/ecx: int <- copy scene-width-f 232 half-scene-width-f <- shift-right 1 233 result-f <- subtract half-scene-width-f 234 return result-f 235 } 236 -237 fn viewport-to-imaginary-f y: int, width: int, height: int, scene-cy-f: int, scene-width-f: int -> _/ebx: int { +237 fn viewport-to-imaginary-f y: int, width: int, height: int, scene-cy-f: int, scene-width-f: int -> _/ebx: int { 238 # 0 in the viewport goes to scene-cy - scene-width/2*height/width 239 # height in the viewport goes to scene-cy + scene-width/2*height/width 240 # Therefore: 241 # y in the viewport goes to (scene-cy - scene-width/2*height/width) + y*scene-width/width 242 # scene-cy - scene-width/width * (height/2 + y) 243 # At most two numbers being multiplied before a divide, so no risk of overflow. -244 var result-f/eax: int <- int-to-fixed y +244 var result-f/eax: int <- int-to-fixed y 245 result-f <- multiply-fixed result-f, scene-width-f -246 var width-f/ecx: int <- copy width +246 var width-f/ecx: int <- copy width 247 width-f <- shift-left 8/fixed-precision 248 result-f <- divide-fixed result-f, width-f 249 result-f <- add scene-cy-f -250 var second-term-f/edx: int <- copy 0 +250 var second-term-f/edx: int <- copy 0 251 { -252 var _second-term-f/eax: int <- copy scene-width-f +252 var _second-term-f/eax: int <- copy scene-width-f 253 _second-term-f <- shift-right 1 -254 var height-f/ebx: int <- copy height +254 var height-f/ebx: int <- copy height 255 height-f <- shift-left 8/fixed-precision 256 _second-term-f <- multiply-fixed _second-term-f, height-f 257 _second-term-f <- divide-fixed _second-term-f, width-f diff --git a/html/mandelbrot-silhouette.mu.html b/html/mandelbrot-silhouette.mu.html new file mode 100644 index 00000000..e3a8e5a1 --- /dev/null +++ b/html/mandelbrot-silhouette.mu.html @@ -0,0 +1,217 @@ + + + + +Mu - mandelbrot-silhouette.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/mandelbrot-silhouette.mu +
+  1 # Mandelbrot set
+  2 #
+  3 # Install:
+  4 #   $ git clone https://github.com/akkartik/mu
+  5 #   $ cd mu
+  6 # Build on Linux:
+  7 #   $ ./translate mandelbrot.mu
+  8 # Build on other platforms (slow):
+  9 #   $ ./translate_emulated mandelbrot.mu
+ 10 # Run:
+ 11 #   $ qemu-system-i386 code.img
+ 12 
+ 13 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
+ 14   mandelbrot screen
+ 15 }
+ 16 
+ 17 fn mandelbrot screen: (addr screen) {
+ 18   var a/eax: int <- copy 0
+ 19   var b/ecx: int <- copy 0
+ 20   a, b <- screen-size screen
+ 21   var width/esi: int <- copy a
+ 22   width <- shift-left 3/log2-font-width
+ 23   var height/edi: int <- copy b
+ 24   height <- shift-left 4/log2-font-height
+ 25   var y/ecx: int <- copy 0
+ 26   {
+ 27     compare y, height
+ 28     break-if->=
+ 29     var imaginary/xmm1: float <- viewport-to-imaginary y, width, height
+ 30     var x/edx: int <- copy 0
+ 31     {
+ 32       compare x, width
+ 33       break-if->=
+ 34       var real/xmm0: float <- viewport-to-real x, width
+ 35       var iterations/eax: int <- mandelbrot-iterations-for-point real, imaginary, 0x400/max
+ 36       compare iterations, 0x400/max
+ 37       {
+ 38         break-if->=
+ 39         pixel screen, x, y, 0xf/white
+ 40       }
+ 41       compare iterations, 0x400/max
+ 42       {
+ 43         break-if-<
+ 44         pixel screen, x, y, 0/black
+ 45       }
+ 46       x <- increment
+ 47       loop
+ 48     }
+ 49     y <- increment
+ 50     loop
+ 51   }
+ 52 }
+ 53 
+ 54 fn mandelbrot-iterations-for-point real: float, imaginary: float, max: int -> _/eax: int {
+ 55   var zero: float
+ 56   var x/xmm0: float <- copy zero
+ 57   var y/xmm1: float <- copy zero
+ 58   var iterations/ecx: int <- copy 0
+ 59   {
+ 60     var done?/eax: boolean <- mandelbrot-done? x, y
+ 61     compare done?, 0/false
+ 62     break-if-!=
+ 63     compare iterations, max
+ 64     break-if->=
+ 65     var newx/xmm2: float <- mandelbrot-x x, y, real
+ 66     var newy/xmm3: float <- mandelbrot-y x, y, imaginary
+ 67     x <- copy newx
+ 68     y <- copy newy
+ 69     iterations <- increment
+ 70     loop
+ 71   }
+ 72   return iterations
+ 73 }
+ 74 
+ 75 fn mandelbrot-done? x: float, y: float -> _/eax: boolean {
+ 76   # x*x + y*y > 4
+ 77   var x2/xmm0: float <- copy x
+ 78   x2 <- multiply x
+ 79   var y2/xmm1: float <- copy y
+ 80   y2 <- multiply y
+ 81   var sum/xmm0: float <- copy x2
+ 82   sum <- add y2
+ 83   var four/eax: int <- copy 4
+ 84   var four-f/xmm1: float <- convert four
+ 85   compare sum, four-f
+ 86   {
+ 87     break-if-float>
+ 88     return 0/false
+ 89   }
+ 90   return 1/true
+ 91 }
+ 92 
+ 93 fn mandelbrot-x x: float, y: float, real: float -> _/xmm2: float {
+ 94   # x*x - y*y + real
+ 95   var x2/xmm0: float <- copy x
+ 96   x2 <- multiply x
+ 97   var y2/xmm1: float <- copy y
+ 98   y2 <- multiply y
+ 99   var result/xmm0: float <- copy x2
+100   result <- subtract y2
+101   result <- add real
+102   return result
+103 }
+104 
+105 fn mandelbrot-y x: float, y: float, imaginary: float -> _/xmm3: float {
+106   # 2*x*y + imaginary
+107   var two/eax: int <- copy 2
+108   var result/xmm0: float <- convert two
+109   result <- multiply x
+110   result <- multiply y
+111   result <- add imaginary
+112   return result
+113 }
+114 
+115 # Scale (x, y) pixel coordinates to a complex plane where the viewport width
+116 # ranges from -2 to +2. Viewport height just follows the viewport's aspect
+117 # ratio.
+118 
+119 fn viewport-to-real x: int, width: int -> _/xmm0: float {
+120   # (x - width/2)*4/width
+121   var result/xmm0: float <- convert x
+122   var width-f/xmm1: float <- convert width
+123   var two/eax: int <- copy 2
+124   var two-f/xmm2: float <- convert two
+125   var half-width-f/xmm2: float <- reciprocal two-f
+126   half-width-f <- multiply width-f
+127   result <- subtract half-width-f
+128   var four/eax: int <- copy 4
+129   var four-f/xmm2: float <- convert four
+130   result <- multiply four-f
+131   result <- divide width-f
+132   return result
+133 }
+134 
+135 fn viewport-to-imaginary y: int, width: int, height: int -> _/xmm1: float {
+136   # (y - height/2)*4/width
+137   var result/xmm0: float <- convert y
+138   var height-f/xmm1: float <- convert height
+139   var half-height-f/xmm1: float <- copy height-f
+140   var two/eax: int <- copy 2
+141   var two-f/xmm2: float <- convert two
+142   half-height-f <- divide two-f
+143   result <- subtract half-height-f
+144   var four/eax: int <- copy 4
+145   var four-f/xmm1: float <- convert four
+146   result <- multiply four-f
+147   var width-f/xmm1: float <- convert width
+148   result <- divide width-f
+149   return result
+150 }
+
+ + + diff --git a/html/mandelbrot.mu.html b/html/mandelbrot.mu.html index d4264d38..5094891e 100644 --- a/html/mandelbrot.mu.html +++ b/html/mandelbrot.mu.html @@ -15,9 +15,15 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } +.muRegEdi { color: #87ffd7; } +.muRegEbx { color: #8787af; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -76,11 +82,11 @@ if ('onhashchange' in window) { 18 # Initially the viewport shows a section of the scene 4 units wide. 19 # scene-width-scale = 0.5 20 var scene-width-scale: float - 21 var dest/eax: (addr float) <- address scene-width-scale + 21 var dest/eax: (addr float) <- address scene-width-scale 22 fill-in-rational dest, 1, 2 23 # scene-width = 4 24 var four: float - 25 var dest/eax: (addr float) <- address four + 25 var dest/eax: (addr float) <- address four 26 fill-in-rational dest, 4, 1 27 var scene-width/xmm3: float <- copy four 28 { @@ -97,29 +103,29 @@ if ('onhashchange' in window) { 39 } 40 41 fn mandelbrot screen: (addr screen), scene-cx: float, scene-cy: float, scene-width: float { - 42 var a/eax: int <- copy 0 - 43 var b/ecx: int <- copy 0 - 44 a, b <- screen-size screen - 45 var width/esi: int <- copy a + 42 var a/eax: int <- copy 0 + 43 var b/ecx: int <- copy 0 + 44 a, b <- screen-size screen + 45 var width/esi: int <- copy a 46 width <- shift-left 3/log2-font-width - 47 var height/edi: int <- copy b + 47 var height/edi: int <- copy b 48 height <- shift-left 4/log2-font-height - 49 var y/ecx: int <- copy 0 + 49 var y/ecx: int <- copy 0 50 { 51 compare y, height 52 break-if->= 53 var imaginary/xmm1: float <- viewport-to-imaginary y, width, height, scene-cy, scene-width - 54 var x/ebx: int <- copy 0 + 54 var x/ebx: int <- copy 0 55 { 56 compare x, width 57 break-if->= 58 var real/xmm0: float <- viewport-to-real x, width, scene-cx, scene-width - 59 var iterations/eax: int <- mandelbrot-iterations-for-point real, imaginary, 0x400/max + 59 var iterations/eax: int <- mandelbrot-iterations-for-point real, imaginary, 0x400/max 60 iterations <- shift-right 3 - 61 var color/edx: int <- copy 0 + 61 var color/edx: int <- copy 0 62 iterations, color <- integer-divide iterations, 0x18/24/size-of-cycle-0 63 color <- add 0x20/cycle-0 - 64 pixel screen, x, y, color + 64 pixel screen, x, y, color 65 x <- increment 66 loop 67 } @@ -128,13 +134,13 @@ if ('onhashchange' in window) { 70 } 71 } 72 - 73 fn mandelbrot-iterations-for-point real: float, imaginary: float, max: int -> _/eax: int { + 73 fn mandelbrot-iterations-for-point real: float, imaginary: float, max: int -> _/eax: int { 74 var zero: float 75 var x/xmm0: float <- copy zero 76 var y/xmm1: float <- copy zero - 77 var iterations/ecx: int <- copy 0 + 77 var iterations/ecx: int <- copy 0 78 { - 79 var done?/eax: boolean <- mandelbrot-done? x, y + 79 var done?/eax: boolean <- mandelbrot-done? x, y 80 compare done?, 0/false 81 break-if-!= 82 compare iterations, max @@ -149,7 +155,7 @@ if ('onhashchange' in window) { 91 return iterations 92 } 93 - 94 fn mandelbrot-done? x: float, y: float -> _/eax: boolean { + 94 fn mandelbrot-done? x: float, y: float -> _/eax: boolean { 95 # x*x + y*y > 4 96 var x2/xmm0: float <- copy x 97 x2 <- multiply x @@ -157,7 +163,7 @@ if ('onhashchange' in window) { 99 y2 <- multiply y 100 var sum/xmm0: float <- copy x2 101 sum <- add y2 -102 var four/eax: int <- copy 4 +102 var four/eax: int <- copy 4 103 var four-f/xmm1: float <- convert four 104 compare sum, four-f 105 { @@ -181,7 +187,7 @@ if ('onhashchange' in window) { 123 124 fn mandelbrot-y x: float, y: float, imaginary: float -> _/xmm3: float { 125 # 2*x*y + imaginary -126 var two/eax: int <- copy 2 +126 var two/eax: int <- copy 2 127 var result/xmm0: float <- convert two 128 result <- multiply x 129 result <- multiply y @@ -204,7 +210,7 @@ if ('onhashchange' in window) { 146 var width-f/xmm1: float <- convert width 147 result <- divide width-f 148 result <- add scene-cx -149 var two/eax: int <- copy 2 +149 var two/eax: int <- copy 2 150 var two-f/xmm2: float <- convert two 151 var half-scene-width/xmm1: float <- copy scene-width 152 half-scene-width <- divide two-f @@ -224,7 +230,7 @@ if ('onhashchange' in window) { 166 var width-f/xmm1: float <- convert width 167 result <- divide width-f 168 result <- add scene-cy -169 var two/eax: int <- copy 2 +169 var two/eax: int <- copy 2 170 var two-f/xmm2: float <- convert two 171 var second-term/xmm1: float <- copy scene-width 172 second-term <- divide two-f diff --git a/html/mu-init.subx.html b/html/mu-init.subx.html index 946275de..4c8eeeb3 100644 --- a/html/mu-init.subx.html +++ b/html/mu-init.subx.html @@ -77,16 +77,17 @@ if ('onhashchange' in window) { 21 { 22 3d/compare-eax-and 0/imm32 23 75/jump-if-!= break/disp8 -24 (clear-real-screen) -25 c7 0/subop/copy *Real-screen-cursor-x 0/imm32 -26 c7 0/subop/copy *Real-screen-cursor-y 0/imm32 -27 (main 0 0 Primary-bus-secondary-drive) -28 } -29 -30 # hang indefinitely -31 { -32 eb/jump loop/disp8 -33 } +24 c7 0/subop/copy *Running-tests? 0/imm32/false +25 (clear-real-screen) +26 c7 0/subop/copy *Real-screen-cursor-x 0/imm32 +27 c7 0/subop/copy *Real-screen-cursor-y 0/imm32 +28 (main 0 0 Primary-bus-secondary-drive) +29 } +30 +31 # hang indefinitely +32 { +33 eb/jump loop/disp8 +34 } diff --git a/html/rpn.mu.html b/html/rpn.mu.html index 5b521abc..37f4fc21 100644 --- a/html/rpn.mu.html +++ b/html/rpn.mu.html @@ -15,9 +15,14 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } +.muRegEdi { color: #87ffd7; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -75,25 +80,25 @@ if ('onhashchange' in window) { 17 18 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { 19 var in-storage: (stream byte 0x80) - 20 var in/esi: (addr stream byte) <- address in-storage - 21 var y/ecx: int <- copy 0 - 22 var space/edx: grapheme <- copy 0x20 + 20 var in/esi: (addr stream byte) <- address in-storage + 21 var y/ecx: int <- copy 0 + 22 var space/edx: grapheme <- copy 0x20 23 # read-eval-print loop 24 { 25 # print prompt - 26 var x/eax: int <- draw-text-rightward screen, "> ", 0/x, 0x80/xmax, y, 3/fg/cyan, 0/bg + 26 var x/eax: int <- draw-text-rightward screen, "> ", 0/x, 0x80/xmax, y, 3/fg/cyan, 0/bg 27 # read line from keyboard 28 clear-stream in 29 { - 30 draw-cursor screen, space - 31 var key/eax: byte <- read-key keyboard + 30 draw-cursor screen, space + 31 var key/eax: byte <- read-key keyboard 32 compare key, 0xa/newline 33 break-if-= 34 compare key, 0 35 loop-if-= - 36 var key2/eax: int <- copy key + 36 var key2/eax: int <- copy key 37 append-byte in, key2 - 38 var g/eax: grapheme <- copy key2 + 38 var g/eax: grapheme <- copy key2 39 draw-grapheme-at-cursor screen, g, 0xf/fg, 0/bg 40 move-cursor-right 0 41 loop @@ -101,7 +106,7 @@ if ('onhashchange' in window) { 43 # clear cursor 44 draw-grapheme-at-cursor screen, space, 3/fg/never-used, 0/bg 45 # parse and eval - 46 var out/eax: int <- simplify in + 46 var out/eax: int <- simplify in 47 # print 48 y <- increment 49 out, y <- draw-int32-decimal-wrapping-right-then-down screen, out, 0/xmin, y, 0x80/xmax, 0x30/ymax, 0/x, y, 7/fg, 0/bg @@ -117,94 +122,94 @@ if ('onhashchange' in window) { 59 top: int 60 } 61 - 62 fn simplify in: (addr stream byte) -> _/eax: int { + 62 fn simplify in: (addr stream byte) -> _/eax: int { 63 var word-storage: slice - 64 var word/ecx: (addr slice) <- address word-storage + 64 var word/ecx: (addr slice) <- address word-storage 65 var stack-storage: int-stack - 66 var stack/esi: (addr int-stack) <- address stack-storage + 66 var stack/esi: (addr int-stack) <- address stack-storage 67 initialize-int-stack stack, 0x10 68 $simplify:word-loop: { 69 next-word in, word - 70 var done?/eax: boolean <- slice-empty? word + 70 var done?/eax: boolean <- slice-empty? word 71 compare done?, 0 72 break-if-!= 73 # if word is an operator, perform it 74 { - 75 var is-add?/eax: boolean <- slice-equal? word, "+" + 75 var is-add?/eax: boolean <- slice-equal? word, "+" 76 compare is-add?, 0 77 break-if-= - 78 var _b/eax: int <- pop-int-stack stack - 79 var b/edx: int <- copy _b - 80 var a/eax: int <- pop-int-stack stack + 78 var _b/eax: int <- pop-int-stack stack + 79 var b/edx: int <- copy _b + 80 var a/eax: int <- pop-int-stack stack 81 a <- add b 82 push-int-stack stack, a 83 loop $simplify:word-loop 84 } 85 { - 86 var is-sub?/eax: boolean <- slice-equal? word, "-" + 86 var is-sub?/eax: boolean <- slice-equal? word, "-" 87 compare is-sub?, 0 88 break-if-= - 89 var _b/eax: int <- pop-int-stack stack - 90 var b/edx: int <- copy _b - 91 var a/eax: int <- pop-int-stack stack + 89 var _b/eax: int <- pop-int-stack stack + 90 var b/edx: int <- copy _b + 91 var a/eax: int <- pop-int-stack stack 92 a <- subtract b 93 push-int-stack stack, a 94 loop $simplify:word-loop 95 } 96 { - 97 var is-mul?/eax: boolean <- slice-equal? word, "*" + 97 var is-mul?/eax: boolean <- slice-equal? word, "*" 98 compare is-mul?, 0 99 break-if-= -100 var _b/eax: int <- pop-int-stack stack -101 var b/edx: int <- copy _b -102 var a/eax: int <- pop-int-stack stack +100 var _b/eax: int <- pop-int-stack stack +101 var b/edx: int <- copy _b +102 var a/eax: int <- pop-int-stack stack 103 a <- multiply b 104 push-int-stack stack, a 105 loop $simplify:word-loop 106 } 107 # otherwise it's an int -108 var n/eax: int <- parse-decimal-int-from-slice word +108 var n/eax: int <- parse-decimal-int-from-slice word 109 push-int-stack stack, n 110 loop 111 } -112 var result/eax: int <- pop-int-stack stack +112 var result/eax: int <- pop-int-stack stack 113 return result 114 } 115 116 fn initialize-int-stack _self: (addr int-stack), n: int { -117 var self/esi: (addr int-stack) <- copy _self -118 var d/edi: (addr handle array int) <- get self, data +117 var self/esi: (addr int-stack) <- copy _self +118 var d/edi: (addr handle array int) <- get self, data 119 populate d, n -120 var top/eax: (addr int) <- get self, top +120 var top/eax: (addr int) <- get self, top 121 copy-to *top, 0 122 } 123 124 fn push-int-stack _self: (addr int-stack), _val: int { -125 var self/esi: (addr int-stack) <- copy _self -126 var top-addr/ecx: (addr int) <- get self, top -127 var data-ah/edx: (addr handle array int) <- get self, data -128 var data/eax: (addr array int) <- lookup *data-ah -129 var top/edx: int <- copy *top-addr -130 var dest-addr/edx: (addr int) <- index data, top -131 var val/eax: int <- copy _val +125 var self/esi: (addr int-stack) <- copy _self +126 var top-addr/ecx: (addr int) <- get self, top +127 var data-ah/edx: (addr handle array int) <- get self, data +128 var data/eax: (addr array int) <- lookup *data-ah +129 var top/edx: int <- copy *top-addr +130 var dest-addr/edx: (addr int) <- index data, top +131 var val/eax: int <- copy _val 132 copy-to *dest-addr, val 133 add-to *top-addr, 1 134 } 135 -136 fn pop-int-stack _self: (addr int-stack) -> _/eax: int { -137 var self/esi: (addr int-stack) <- copy _self -138 var top-addr/ecx: (addr int) <- get self, top +136 fn pop-int-stack _self: (addr int-stack) -> _/eax: int { +137 var self/esi: (addr int-stack) <- copy _self +138 var top-addr/ecx: (addr int) <- get self, top 139 { 140 compare *top-addr, 0 141 break-if-> 142 return 0 143 } 144 subtract-from *top-addr, 1 -145 var data-ah/edx: (addr handle array int) <- get self, data -146 var data/eax: (addr array int) <- lookup *data-ah -147 var top/edx: int <- copy *top-addr -148 var result-addr/eax: (addr int) <- index data, top -149 var val/eax: int <- copy *result-addr +145 var data-ah/edx: (addr handle array int) <- get self, data +146 var data/eax: (addr array int) <- lookup *data-ah +147 var top/edx: int <- copy *top-addr +148 var result-addr/eax: (addr int) <- index data, top +149 var val/eax: int <- copy *result-addr 150 return val 151 } diff --git a/html/shell/cell.mu.html b/html/shell/cell.mu.html index ec5bbc40..ffc4ba02 100644 --- a/html/shell/cell.mu.html +++ b/html/shell/cell.mu.html @@ -17,10 +17,10 @@ a { color:inherit; } .PreProc { color: #c000c0; } .Special { color: #ff6060; } .LineNr { } -.muRegEsi { color: #87d787; } .Constant { color: #008787; } -.muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } +.muRegEsi { color: #87d787; } +.muRegEax { color: #875f00; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } @@ -219,10 +219,10 @@ if ('onhashchange' in window) { 158 var dest-ah/eax: (addr handle screen) <- get out-addr, screen-data 159 allocate dest-ah 160 var dest-addr/eax: (addr screen) <- lookup *dest-ah -161 initialize-screen dest-addr, width, height, pixel-graphics? +161 initialize-screen dest-addr, width, height, pixel-graphics? 162 } 163 -164 fn clear-screen-cell _self-ah: (addr handle cell) { +164 fn clear-screen-var _self-ah: (addr handle cell) { 165 var self-ah/eax: (addr handle cell) <- copy _self-ah 166 var self/eax: (addr cell) <- lookup *self-ah 167 compare self, 0 @@ -232,7 +232,7 @@ if ('onhashchange' in window) { 171 } 172 var screen-ah/eax: (addr handle screen) <- get self, screen-data 173 var screen/eax: (addr screen) <- lookup *screen-ah -174 clear-screen screen +174 clear-screen screen 175 } 176 177 fn allocate-keyboard _out: (addr handle cell) { @@ -253,7 +253,7 @@ if ('onhashchange' in window) { 192 initialize-gap-buffer dest-addr, capacity 193 } 194 -195 fn rewind-keyboard-cell _self-ah: (addr handle cell) { +195 fn rewind-keyboard-var _self-ah: (addr handle cell) { 196 var self-ah/eax: (addr handle cell) <- copy _self-ah 197 var self/eax: (addr cell) <- lookup *self-ah 198 compare self, 0 @@ -263,7 +263,7 @@ if ('onhashchange' in window) { 202 } 203 var keyboard-ah/eax: (addr handle gap-buffer) <- get self, keyboard-data 204 var keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah -205 rewind-gap-buffer keyboard +205 rewind-gap-buffer keyboard 206 } diff --git a/html/shell/environment.mu.html b/html/shell/environment.mu.html index 7fd41c4d..5c0c1ff7 100644 --- a/html/shell/environment.mu.html +++ b/html/shell/environment.mu.html @@ -16,18 +16,19 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } .Delimiter { color: #c000c0; } -.muFunction { color: #af5f00; text-decoration: underline; } +.CommentedCode { color: #8a8a8a; } +.muRegEdx { color: #878700; } .muRegEbx { color: #8787af; } .muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } .Constant { color: #008787; } .Special { color: #ff6060; } .PreProc { color: #c000c0; } -.CommentedCode { color: #8a8a8a; } +.muFunction { color: #af5f00; text-decoration: underline; } +.muTest { color: #5f8700; } .muComment { color: #005faf; } .muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } --> @@ -63,429 +64,1035 @@ if ('onhashchange' in window) { https://github.com/akkartik/mu/blob/main/shell/environment.mu
-  1 type environment {
-  2   globals: global-table
-  3   sandbox: sandbox
-  4   partial-function-name: (handle gap-buffer)
-  5   cursor-in-globals?: boolean
-  6   cursor-in-function-modal?: boolean
-  7 }
-  8 
-  9 fn initialize-environment _self: (addr environment) {
- 10   var self/esi: (addr environment) <- copy _self
- 11   var globals/eax: (addr global-table) <- get self, globals
- 12   initialize-globals globals
- 13   var sandbox/eax: (addr sandbox) <- get self, sandbox
- 14   initialize-sandbox sandbox, 1/with-screen
- 15   var partial-function-name-ah/eax: (addr handle gap-buffer) <- get self, partial-function-name
- 16   allocate partial-function-name-ah
- 17   var partial-function-name/eax: (addr gap-buffer) <- lookup *partial-function-name-ah
- 18   initialize-gap-buffer partial-function-name, 0x40/function-name-capacity
- 19 }
- 20 
- 21 fn render-environment screen: (addr screen), _self: (addr environment) {
- 22   # globals layout: 1 char padding, 41 code, 1 padding, 41 code, 1 padding =  85
- 23   # sandbox layout: 1 padding, 41 code, 1 padding                          =  43
- 24   #                                                                  total = 128 chars
- 25   var self/esi: (addr environment) <- copy _self
- 26   var cursor-in-globals-a/eax: (addr boolean) <- get self, cursor-in-globals?
- 27   var cursor-in-globals?/eax: boolean <- copy *cursor-in-globals-a
- 28   var globals/ecx: (addr global-table) <- get self, globals
- 29   render-globals screen, globals, cursor-in-globals?
- 30   var sandbox/edx: (addr sandbox) <- get self, sandbox
- 31   var cursor-in-sandbox?/ebx: boolean <- copy 1/true
- 32   cursor-in-sandbox? <- subtract cursor-in-globals?
- 33   render-sandbox screen, sandbox, 0x55/sandbox-left-margin, 0/sandbox-top-margin, 0x80/screen-width, 0x2f/screen-height-without-menu, cursor-in-sandbox?
- 34   # modal if necessary
- 35   {
- 36     var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal?
- 37     compare *cursor-in-function-modal-a, 0/false
- 38     break-if-=
- 39     render-function-modal screen, self
- 40     render-function-modal-menu screen, self
- 41     return
- 42   }
- 43   # render menu
- 44   {
- 45     var cursor-in-globals?/eax: (addr boolean) <- get self, cursor-in-globals?
- 46     compare *cursor-in-globals?, 0/false
- 47     break-if-=
- 48     render-globals-menu screen, globals
- 49     return
- 50   }
- 51   render-sandbox-menu screen, sandbox
- 52 }
- 53 
- 54 fn edit-environment _self: (addr environment), key: grapheme, data-disk: (addr disk) {
- 55   var self/esi: (addr environment) <- copy _self
- 56   var globals/edi: (addr global-table) <- get self, globals
- 57   var sandbox/ecx: (addr sandbox) <- get self, sandbox
- 58   # ctrl-r
- 59   # Assumption: 'real-screen' and 'real-keyboard' are 0
- 60   {
- 61     compare key, 0x12/ctrl-r
- 62     break-if-!=
- 63     var tmp/eax: (addr handle cell) <- copy 0
- 64     var nil: (handle cell)
- 65     tmp <- address nil
- 66     allocate-pair tmp
- 67     # (main real-screen real-keyboard)
- 68     var real-keyboard: (handle cell)
- 69     tmp <- address real-keyboard
- 70     allocate-keyboard tmp
- 71     # args = cons(real-keyboard, nil)
- 72     var args: (handle cell)
- 73     tmp <- address args
- 74     new-pair tmp, real-keyboard, nil
- 75     #
- 76     var real-screen: (handle cell)
- 77     tmp <- address real-screen
- 78     allocate-screen tmp
- 79     #  args = cons(real-screen, args)
- 80     tmp <- address args
- 81     new-pair tmp, real-screen, *tmp
- 82     #
- 83     var main: (handle cell)
- 84     tmp <- address main
- 85     new-symbol tmp, "main"
- 86     # args = cons(main, args)
- 87     tmp <- address args
- 88     new-pair tmp, main, *tmp
- 89     # clear real screen
- 90     clear-screen 0/screen
- 91     set-cursor-position 0/screen, 0, 0
- 92     # run
- 93     var out: (handle cell)
- 94     var out-ah/ecx: (addr handle cell) <- address out
- 95     var trace-storage: trace
- 96     var trace/ebx: (addr trace) <- address trace-storage
- 97     initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
- 98     evaluate tmp, out-ah, nil, globals, trace, 0/no-fake-screen, 0/no-fake-keyboard, 0/call-number
- 99     # wait for a keypress
-100     {
-101       var tmp/eax: byte <- read-key 0/keyboard
-102       compare tmp, 0
-103       loop-if-=
-104     }
-105     #
-106     return
-107   }
-108   # ctrl-s: send multiple places
-109   {
-110     compare key, 0x13/ctrl-s
-111     break-if-!=
-112     {
-113       # cursor in function modal? do nothing
-114       var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal?
-115       compare *cursor-in-function-modal-a, 0/false
-116       break-if-!=
-117       {
-118         # cursor in globals? update current definition
-119         var cursor-in-globals-a/edx: (addr boolean) <- get self, cursor-in-globals?
-120         compare *cursor-in-globals-a, 0/false
-121         break-if-=
-122         edit-globals globals, key
-123       }
-124       # update sandbox whether the cursor is in globals or sandbox
-125       edit-sandbox sandbox, key, globals, data-disk, 1/tweak-real-screen
-126     }
-127     return
-128   }
-129   # ctrl-g: go to a function (or the repl)
-130   {
-131     compare key, 7/ctrl-g
-132     break-if-!=
-133     var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal?
-134     compare *cursor-in-function-modal-a, 0/false
-135     break-if-!=
-136     # look for a word to prepopulate the modal
-137     var current-word-storage: (stream byte 0x40)
-138     var current-word/edi: (addr stream byte) <- address current-word-storage
-139     word-at-cursor self, current-word
-140     var partial-function-name-ah/eax: (addr handle gap-buffer) <- get self, partial-function-name
-141     var partial-function-name/eax: (addr gap-buffer) <- lookup *partial-function-name-ah
-142     clear-gap-buffer partial-function-name
-143     load-gap-buffer-from-stream partial-function-name, current-word
-144     # enable the modal
-145     var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal?
-146     copy-to *cursor-in-function-modal-a, 1/true
-147     return
-148   }
-149   # dispatch to function modal if necessary
-150   {
-151     var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal?
-152     compare *cursor-in-function-modal-a, 0/false
-153     break-if-=
-154     # nested events for modal dialog
-155     # ignore spaces
-156     {
-157       compare key, 0x20/space
-158       break-if-!=
-159       return
-160     }
-161     # esc = exit modal dialog
-162     {
-163       compare key, 0x1b/escape
-164       break-if-!=
-165       var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal?
-166       copy-to *cursor-in-function-modal-a, 0/false
-167       return
-168     }
-169     # enter = switch to function name and exit modal dialog
-170     {
-171       compare key, 0xa/newline
-172       break-if-!=
-173       var cursor-in-globals-a/edx: (addr boolean) <- get self, cursor-in-globals?
-174       copy-to *cursor-in-globals-a, 1/true
-175       var partial-function-name-ah/eax: (addr handle gap-buffer) <- get self, partial-function-name
-176       var partial-function-name/eax: (addr gap-buffer) <- lookup *partial-function-name-ah
-177       {
-178         {
-179           var empty?/eax: boolean <- gap-buffer-empty? partial-function-name
-180           compare empty?, 0/false
-181         }
-182         break-if-!=
-183         set-global-cursor-index globals, partial-function-name
-184       }
-185       var cursor-in-globals-a/ecx: (addr boolean) <- get self, cursor-in-globals?
-186       copy-to *cursor-in-globals-a, 1/true
-187       {
-188         var empty?/eax: boolean <- gap-buffer-empty? partial-function-name
-189         compare empty?, 0/false
-190         break-if-=
-191         copy-to *cursor-in-globals-a, 0/false
-192       }
-193       clear-gap-buffer partial-function-name
-194       var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal?
-195       copy-to *cursor-in-function-modal-a, 0/false
-196       return
-197     }
-198     # otherwise process like a regular gap-buffer
-199     var partial-function-name-ah/eax: (addr handle gap-buffer) <- get self, partial-function-name
-200     var partial-function-name/eax: (addr gap-buffer) <- lookup *partial-function-name-ah
-201     edit-gap-buffer partial-function-name, key
-202     return
-203   }
-204   # dispatch the key to either sandbox or globals
-205   {
-206     var cursor-in-globals-a/eax: (addr boolean) <- get self, cursor-in-globals?
-207     compare *cursor-in-globals-a, 0/false
-208     break-if-=
-209     edit-globals globals, key
-210     return
-211   }
-212   edit-sandbox sandbox, key, globals, data-disk, 1/tweak-real-screen
-213 }
-214 
-215 fn word-at-cursor _self: (addr environment), out: (addr stream byte) {
-216   var self/esi: (addr environment) <- copy _self
-217   var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal?
-218   compare *cursor-in-function-modal-a, 0/false
-219   {
-220     break-if-=
-221     # cursor in function modal
-222     return
-223   }
-224   var cursor-in-globals-a/edx: (addr boolean) <- get self, cursor-in-globals?
-225   compare *cursor-in-globals-a, 0/false
-226   {
-227     break-if-=
-228     # cursor in some function editor
-229     var globals/eax: (addr global-table) <- get self, globals
-230     var cursor-index-addr/ecx: (addr int) <- get globals, cursor-index
-231     var cursor-index/ecx: int <- copy *cursor-index-addr
-232     var globals-data-ah/eax: (addr handle array global) <- get globals, data
-233     var globals-data/eax: (addr array global) <- lookup *globals-data-ah
-234     var cursor-offset/ecx: (offset global) <- compute-offset globals-data, cursor-index
-235     var curr-global/eax: (addr global) <- index globals-data, cursor-offset
-236     var curr-global-data-ah/eax: (addr handle gap-buffer) <- get curr-global, input
-237     var curr-global-data/eax: (addr gap-buffer) <- lookup *curr-global-data-ah
-238     word-at-gap curr-global-data, out
-239     return
-240   }
-241   # cursor in sandbox
-242   var sandbox/ecx: (addr sandbox) <- get self, sandbox
-243   var sandbox-data-ah/eax: (addr handle gap-buffer) <- get sandbox, data
-244   var sandbox-data/eax: (addr gap-buffer) <- lookup *sandbox-data-ah
-245   word-at-gap sandbox-data, out
-246 }
-247 
-248 fn render-function-modal screen: (addr screen), _self: (addr environment) {
-249   var self/esi: (addr environment) <- copy _self
-250   var width/eax: int <- copy 0
-251   var height/ecx: int <- copy 0
-252   width, height <- screen-size screen
-253   # xmin = max(0, width/2 - 0x20)
-254   var xmin: int
-255   var tmp/edx: int <- copy width
-256   tmp <- shift-right 1
-257   tmp <- subtract 0x20/half-function-name-capacity
-258   {
-259     compare tmp, 0
-260     break-if->=
-261     tmp <- copy 0
-262   }
-263   copy-to xmin, tmp
-264   # xmax = min(width, width/2 + 0x20)
-265   var xmax: int
-266   tmp <- copy width
-267   tmp <- shift-right 1
-268   tmp <- add 0x20/half-function-name-capacity
-269   {
-270     compare tmp, width
-271     break-if-<=
-272     tmp <- copy width
-273   }
-274   copy-to xmax, tmp
-275   # ymin = height/2 - 2
-276   var ymin: int
-277   tmp <- copy height
-278   tmp <- shift-right 1
-279   tmp <- subtract 2
-280   copy-to ymin, tmp
-281   # ymax = height/2 + 1
-282   var ymax: int
-283   tmp <- add 3
-284   copy-to ymax, tmp
-285   #
-286   clear-rect screen, xmin, ymin, xmax, ymax, 0xf/bg=modal
-287   add-to xmin, 4
-288   set-cursor-position screen, xmin, ymin
-289   draw-text-rightward-from-cursor screen, "go to function (or leave blank to go to REPL)", xmax, 8/fg=dark-grey, 0xf/bg=modal
-290   var partial-function-name-ah/eax: (addr handle gap-buffer) <- get self, partial-function-name
-291   var _partial-function-name/eax: (addr gap-buffer) <- lookup *partial-function-name-ah
-292   var partial-function-name/edx: (addr gap-buffer) <- copy _partial-function-name
-293   subtract-from xmin, 4
-294   add-to ymin 2
-295   var dummy/eax: int <- copy 0
-296   var dummy2/ecx: int <- copy 0
-297   dummy, dummy2 <- render-gap-buffer-wrapping-right-then-down screen, partial-function-name, xmin, ymin, xmax, ymax, 1/always-render-cursor, 0/fg=black, 0xf/bg=modal
-298 }
-299 
-300 fn render-function-modal-menu screen: (addr screen), _self: (addr environment) {
-301   var self/esi: (addr environment) <- copy _self
-302   var _width/eax: int <- copy 0
-303   var height/ecx: int <- copy 0
-304   _width, height <- screen-size screen
-305   var width/edx: int <- copy _width
-306   var y/ecx: int <- copy height
-307   y <- decrement
-308   var height/ebx: int <- copy y
-309   height <- increment
-310   clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg
-311   set-cursor-position screen, 0/x, y
-312   draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight
-313   draw-text-rightward-from-cursor screen, " run main  ", width, 7/fg, 0xc5/bg=blue-bg
-314   draw-text-rightward-from-cursor screen, " enter ", width, 0/fg, 0x5c/bg=menu-highlight
-315   draw-text-rightward-from-cursor screen, " submit  ", width, 7/fg, 0xc5/bg=blue-bg
-316   draw-text-rightward-from-cursor screen, " esc ", width, 0/fg, 0x5c/bg=menu-highlight
-317   draw-text-rightward-from-cursor screen, " cancel  ", width, 7/fg, 0xc5/bg=blue-bg
-318   draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight
-319   draw-text-rightward-from-cursor screen, " <<  ", width, 7/fg, 0xc5/bg=blue-bg
-320   draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight
-321   draw-text-rightward-from-cursor screen, " <word  ", width, 7/fg, 0xc5/bg=blue-bg
-322   draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight
-323   draw-text-rightward-from-cursor screen, " word>  ", width, 7/fg, 0xc5/bg=blue-bg
-324   draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight
-325   draw-text-rightward-from-cursor screen, " >>  ", width, 7/fg, 0xc5/bg=blue-bg
-326 }
-327 
-328 # Gotcha: some saved state may not load.
-329 fn load-state _self: (addr environment), data-disk: (addr disk) {
-330   var self/esi: (addr environment) <- copy _self
-331   # data-disk -> stream
-332   var s-storage: (stream byte 0x1000)  # space for 8/sectors
-333   var s/ebx: (addr stream byte) <- address s-storage
-334   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "loading sectors from data disk", 3/fg, 0/bg
-335   move-cursor-to-left-margin-of-next-line 0/screen
-336   load-sectors data-disk, 0/lba, 8/sectors, s
-337 #?   draw-stream-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, s, 7/fg, 0xc5/bg=blue-bg
-338   # stream -> gap-buffer (HACK: we temporarily cannibalize the sandbox's gap-buffer)
-339   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "parsing", 3/fg, 0/bg
-340   move-cursor-to-left-margin-of-next-line 0/screen
-341   var sandbox/eax: (addr sandbox) <- get self, sandbox
-342   var data-ah/eax: (addr handle gap-buffer) <- get sandbox, data
-343   var data/eax: (addr gap-buffer) <- lookup *data-ah
-344   load-gap-buffer-from-stream data, s
-345   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "  into gap buffer", 3/fg, 0/bg
-346   move-cursor-to-left-margin-of-next-line 0/screen
-347   clear-stream s
-348   # read: gap-buffer -> cell
-349   var initial-root-storage: (handle cell)
-350   var initial-root/ecx: (addr handle cell) <- address initial-root-storage
-351   var trace-storage: trace
-352   var trace/edi: (addr trace) <- address trace-storage
-353   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
-354   read-cell data, initial-root, trace
-355   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "  into s-expressions", 3/fg, 0/bg
-356   move-cursor-to-left-margin-of-next-line 0/screen
-357   clear-gap-buffer data
-358   #
-359   {
-360     var initial-root-addr/eax: (addr cell) <- lookup *initial-root
-361     compare initial-root-addr, 0
-362     break-if-!=
-363     return
-364   }
-365   # load globals from assoc(initial-root, 'globals)
-366   var globals-literal-storage: (handle cell)
-367   var globals-literal-ah/eax: (addr handle cell) <- address globals-literal-storage
-368   new-symbol globals-literal-ah, "globals"
-369   var globals-literal/eax: (addr cell) <- lookup *globals-literal-ah
-370   var globals-cell-storage: (handle cell)
-371   var globals-cell-ah/edx: (addr handle cell) <- address globals-cell-storage
-372   clear-trace trace
-373   lookup-symbol globals-literal, globals-cell-ah, *initial-root, 0/no-globals, trace, 0/no-screen, 0/no-keyboard
-374   var globals-cell/eax: (addr cell) <- lookup *globals-cell-ah
-375   {
-376     compare globals-cell, 0
-377     break-if-=
-378     var globals/eax: (addr global-table) <- get self, globals
-379     load-globals globals-cell-ah, globals
-380   }
-381   # sandbox = assoc(initial-root, 'sandbox)
-382   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "loading sandbox", 3/fg, 0/bg
-383   var sandbox-literal-storage: (handle cell)
-384   var sandbox-literal-ah/eax: (addr handle cell) <- address sandbox-literal-storage
-385   new-symbol sandbox-literal-ah, "sandbox"
-386   var sandbox-literal/eax: (addr cell) <- lookup *sandbox-literal-ah
-387   var sandbox-cell-storage: (handle cell)
-388   var sandbox-cell-ah/edx: (addr handle cell) <- address sandbox-cell-storage
-389   clear-trace trace
-390   lookup-symbol sandbox-literal, sandbox-cell-ah, *initial-root, 0/no-globals, trace, 0/no-screen, 0/no-keyboard
-391   var sandbox-cell/eax: (addr cell) <- lookup *sandbox-cell-ah
-392   {
-393     compare sandbox-cell, 0
-394     break-if-=
-395     # print: cell -> stream
-396     clear-trace trace
-397     print-cell sandbox-cell-ah, s, trace
-398     # stream -> gap-buffer
-399     var sandbox/eax: (addr sandbox) <- get self, sandbox
-400     var data-ah/eax: (addr handle gap-buffer) <- get sandbox, data
-401     var data/eax: (addr gap-buffer) <- lookup *data-ah
-402     load-gap-buffer-from-stream data, s
-403   }
-404 }
-405 
-406 # Save state as an alist of alists:
-407 #   ((globals . ((a . (fn ...))
-408 #                ...))
-409 #    (sandbox . ...))
-410 fn store-state data-disk: (addr disk), sandbox: (addr sandbox), globals: (addr global-table) {
-411   compare data-disk, 0/no-disk
-412   {
-413     break-if-!=
-414     return
-415   }
-416   var stream-storage: (stream byte 0x1000)  # space enough for 8/sectors
-417   var stream/edi: (addr stream byte) <- address stream-storage
-418   write stream, "(\n"
-419   write-globals stream, globals
-420   write-sandbox stream, sandbox
-421   write stream, ")\n"
-422   store-sectors data-disk, 0/lba, 8/sectors, stream
-423 }
+   1 # The top-level data structure for the Mu shell.
+   2 #
+   3 # vim:textwidth&
+   4 # It would be nice for tests to use a narrower screen than the standard 0x80 of
+   5 # 1024 pixels with 8px-wide graphemes. But it complicates rendering logic to
+   6 # make width configurable, so we just use longer lines than usual.
+   7 
+   8 type environment {
+   9   globals: global-table
+  10   sandbox: sandbox
+  11   # some state for a modal dialog for navigating between globals
+  12   partial-global-name: (handle gap-buffer)
+  13   go-modal-error: (handle array byte)
+  14   #
+  15   cursor-in-globals?: boolean
+  16   cursor-in-go-modal?: boolean
+  17 }
+  18 
+  19 # Here's a sample usage session and what it will look like on the screen.
+  20 fn test-environment {
+  21   var env-storage: environment
+  22   var env/esi: (addr environment) <- address env-storage
+  23   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+  24   # setup: screen
+  25   var screen-on-stack: screen
+  26   var screen/edi: (addr screen) <- address screen-on-stack
+  27   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+  28   # type some code into sandbox
+  29   type-in env, screen, "(+ 3 4)"  # we don't have any global definitions here, so no macros
+  30   # run code in sandbox
+  31   edit-environment env, 0x13/ctrl-s, 0/no-disk
+  32   render-environment screen, env
+  33   #                                                         | global definitions                                                                 | sandbox
+  34   # top row blank for now
+  35   check-screen-row                     screen,         0/y, "                                                                                                                                ", "F - test-environment/0"
+  36   check-screen-row                     screen,         1/y, "                                                                                      screen:                                   ", "F - test-environment/1"
+  37   check-background-color-in-screen-row screen, 0/bg,   2/y, "                                                                                        ........                                ", "F - test-environment/2"
+  38   check-background-color-in-screen-row screen, 0/bg,   3/y, "                                                                                        ........                                ", "F - test-environment/3"
+  39   check-background-color-in-screen-row screen, 0/bg,   4/y, "                                                                                        ........                                ", "F - test-environment/4"
+  40   check-screen-row                     screen,         5/y, "                                                                                                                                ", "F - test-environment/5"
+  41   check-screen-row                     screen,         6/y, "                                                                                      keyboard:                                 ", "F - test-environment/6"
+  42   check-background-color-in-screen-row screen, 0/bg,   6/y, "                                                                                                ................                ", "F - test-environment/6-2"
+  43   check-screen-row                     screen,         7/y, "                                                                                                                                ", "F - test-environment/7"
+  44   check-screen-row                     screen,         8/y, "                                                                                      (+ 3 4)                                   ", "F - test-environment/8"
+  45   check-screen-row                     screen,         9/y, "                                                                                      ...                       trace depth: 4  ", "F - test-environment/9"
+  46   check-screen-row                     screen,       0xa/y, "                                                                                      => 7                                      ", "F - test-environment/10"
+  47   check-screen-row                     screen,       0xb/y, "                                                                                                                                ", "F - test-environment/11"
+  48   check-screen-row                     screen,       0xc/y, "                                                                                                                                ", "F - test-environment/12"
+  49   check-screen-row                     screen,       0xd/y, "                                                                                                                                ", "F - test-environment/13"
+  50   check-screen-row                     screen,       0xe/y, "                                                                                                                                ", "F - test-environment/14"
+  51   # bottom row is for a wordstar-style menu
+  52   check-screen-row                     screen,       0xf/y, " ^r  run main   ^s  run sandbox   ^g  go to   ^m  to trace   ^a  <<   ^b  <word   ^f  word>   ^e  >>                            ", "F - test-environment/15"
+  53 }
+  54 
+  55 fn test-definition-in-environment {
+  56   var env-storage: environment
+  57   var env/esi: (addr environment) <- address env-storage
+  58   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+  59   # setup: screen
+  60   var screen-on-stack: screen
+  61   var screen/edi: (addr screen) <- address screen-on-stack
+  62   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+  63   # define a global on the right (sandbox) side
+  64   type-in env, screen, "(define f 42)"
+  65   edit-environment env, 0x13/ctrl-s, 0/no-disk
+  66   render-environment screen, env
+  67   #                                                         | global definitions                                                                 | sandbox
+  68   check-screen-row                     screen,         0/y, "                                                                                                                                ", "F - test-definition-in-environment/0"
+  69   # global definition is now on the left side
+  70   check-screen-row                     screen,         1/y, "                                           (define f 42)                              screen:                                   ", "F - test-definition-in-environment/1"
+  71   check-background-color-in-screen-row screen, 0/bg,   2/y, "                                                                                        ........                                ", "F - test-environment/2"
+  72   check-background-color-in-screen-row screen, 0/bg,   3/y, "                                                                                        ........                                ", "F - test-environment/3"
+  73   check-background-color-in-screen-row screen, 0/bg,   4/y, "                                                                                        ........                                ", "F - test-environment/4"
+  74   check-screen-row                     screen,         5/y, "                                                                                                                                ", "F - test-definition-in-environment/4"
+  75   check-screen-row                     screen,         6/y, "                                                                                      keyboard:                                 ", "F - test-definition-in-environment/5"
+  76   check-background-color-in-screen-row screen, 0/bg,   6/y, "                                                                                                ................                ", "F - test-definition-in-environment/5-2"
+  77   check-screen-row                     screen,         7/y, "                                                                                                                                ", "F - test-definition-in-environment/6"
+  78   check-screen-row                     screen,         8/y, "                                                                                                                                ", "F - test-definition-in-environment/7"
+  79   # you can still see the trace on the right for what you just added to the left
+  80   check-screen-row                     screen,         9/y, "                                                                                      ...                       trace depth: 4  ", "F - test-definition-in-environment/8"
+  81 }
+  82 
+  83 # helper for testing
+  84 fn type-in self: (addr environment), screen: (addr screen), keys: (addr array byte) {
+  85   # clear the buffer
+  86   edit-environment self, 0x15/ctrl-u, 0/no-disk
+  87   render-environment screen, self
+  88   # type in all the keys
+  89   var input-stream-storage: (stream byte 0x40/capacity)
+  90   var input-stream/ecx: (addr stream byte) <- address input-stream-storage
+  91   write input-stream, keys
+  92   {
+  93     var done?/eax: boolean <- stream-empty? input-stream
+  94     compare done?, 0/false
+  95     break-if-!=
+  96     var key/eax: grapheme <- read-grapheme input-stream
+  97     edit-environment self, key, 0/no-disk
+  98     render-environment screen, self
+  99     loop
+ 100   }
+ 101 }
+ 102 
+ 103 fn initialize-environment _self: (addr environment), fake-screen-width: int, fake-screen-height: int {
+ 104   var self/esi: (addr environment) <- copy _self
+ 105   var globals/eax: (addr global-table) <- get self, globals
+ 106   initialize-globals globals
+ 107   var sandbox/eax: (addr sandbox) <- get self, sandbox
+ 108   initialize-sandbox sandbox, fake-screen-width, fake-screen-height
+ 109   var partial-global-name-ah/eax: (addr handle gap-buffer) <- get self, partial-global-name
+ 110   allocate partial-global-name-ah
+ 111   var partial-global-name/eax: (addr gap-buffer) <- lookup *partial-global-name-ah
+ 112   initialize-gap-buffer partial-global-name, 0x40/global-name-capacity
+ 113 }
+ 114 
+ 115 fn render-environment screen: (addr screen), _self: (addr environment) {
+ 116   # globals layout: 1 char padding, 41 code, 1 padding, 41 code, 1 padding =  85
+ 117   # sandbox layout: 1 padding, 41 code, 1 padding                          =  43
+ 118   #                                                                  total = 128 chars
+ 119   var self/esi: (addr environment) <- copy _self
+ 120   var cursor-in-globals-a/eax: (addr boolean) <- get self, cursor-in-globals?
+ 121   var cursor-in-globals?/eax: boolean <- copy *cursor-in-globals-a
+ 122   var globals/ecx: (addr global-table) <- get self, globals
+ 123   render-globals screen, globals, cursor-in-globals?
+ 124   var sandbox/edx: (addr sandbox) <- get self, sandbox
+ 125   var cursor-in-sandbox?/ebx: boolean <- copy 1/true
+ 126   cursor-in-sandbox? <- subtract cursor-in-globals?
+ 127   render-sandbox screen, sandbox, 0x55/sandbox-left-margin, 0/sandbox-top-margin, 0x80/screen-width, 0x2f/screen-height-without-menu, cursor-in-sandbox?
+ 128   # modal if necessary
+ 129   {
+ 130     var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 131     compare *cursor-in-go-modal-a, 0/false
+ 132     break-if-=
+ 133     render-go-modal screen, self
+ 134     render-go-modal-menu screen, self
+ 135     return
+ 136   }
+ 137   # render menu
+ 138   {
+ 139     var cursor-in-globals?/eax: (addr boolean) <- get self, cursor-in-globals?
+ 140     compare *cursor-in-globals?, 0/false
+ 141     break-if-=
+ 142     render-globals-menu screen, globals
+ 143     return
+ 144   }
+ 145   render-sandbox-menu screen, sandbox
+ 146 }
+ 147 
+ 148 fn edit-environment _self: (addr environment), key: grapheme, data-disk: (addr disk) {
+ 149   var self/esi: (addr environment) <- copy _self
+ 150   var globals/edi: (addr global-table) <- get self, globals
+ 151   var sandbox/ecx: (addr sandbox) <- get self, sandbox
+ 152   # ctrl-r
+ 153   # Assumption: 'real-screen' and 'real-keyboard' are 0
+ 154   {
+ 155     compare key, 0x12/ctrl-r
+ 156     break-if-!=
+ 157     var tmp/eax: (addr handle cell) <- copy 0
+ 158     var nil: (handle cell)
+ 159     tmp <- address nil
+ 160     allocate-pair tmp
+ 161     # (main real-screen real-keyboard)
+ 162     var real-keyboard: (handle cell)
+ 163     tmp <- address real-keyboard
+ 164     allocate-keyboard tmp
+ 165     # args = cons(real-keyboard, nil)
+ 166     var args: (handle cell)
+ 167     tmp <- address args
+ 168     new-pair tmp, real-keyboard, nil
+ 169     #
+ 170     var real-screen: (handle cell)
+ 171     tmp <- address real-screen
+ 172     allocate-screen tmp
+ 173     #  args = cons(real-screen, args)
+ 174     tmp <- address args
+ 175     new-pair tmp, real-screen, *tmp
+ 176     #
+ 177     var main: (handle cell)
+ 178     tmp <- address main
+ 179     new-symbol tmp, "main"
+ 180     # args = cons(main, args)
+ 181     tmp <- address args
+ 182     new-pair tmp, main, *tmp
+ 183     # clear real screen
+ 184     clear-screen 0/screen
+ 185     set-cursor-position 0/screen, 0, 0
+ 186     # run
+ 187     var out: (handle cell)
+ 188     var out-ah/ecx: (addr handle cell) <- address out
+ 189     var trace-storage: trace
+ 190     var trace/ebx: (addr trace) <- address trace-storage
+ 191     initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 192     evaluate tmp, out-ah, nil, globals, trace, 0/no-fake-screen, 0/no-fake-keyboard, 0/definitions-created, 0/call-number
+ 193     # wait for a keypress
+ 194     {
+ 195       var tmp/eax: byte <- read-key 0/keyboard
+ 196       compare tmp, 0
+ 197       loop-if-=
+ 198     }
+ 199     #
+ 200     return
+ 201   }
+ 202   # ctrl-s: send multiple places
+ 203   {
+ 204     compare key, 0x13/ctrl-s
+ 205     break-if-!=
+ 206     {
+ 207       # cursor in go modal? do nothing
+ 208       var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 209       compare *cursor-in-go-modal-a, 0/false
+ 210       break-if-!=
+ 211       {
+ 212         # cursor in globals? update current definition
+ 213         var cursor-in-globals-a/edx: (addr boolean) <- get self, cursor-in-globals?
+ 214         compare *cursor-in-globals-a, 0/false
+ 215         break-if-=
+ 216         edit-globals globals, key
+ 217       }
+ 218       # update sandbox whether the cursor is in globals or sandbox
+ 219       edit-sandbox sandbox, key, globals, data-disk
+ 220     }
+ 221     return
+ 222   }
+ 223   # dispatch to go modal if necessary
+ 224   {
+ 225     var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 226     compare *cursor-in-go-modal-a, 0/false
+ 227     break-if-=
+ 228     # nested events for modal dialog
+ 229     # ignore spaces
+ 230     {
+ 231       compare key, 0x20/space
+ 232       break-if-!=
+ 233       return
+ 234     }
+ 235     # esc = exit modal dialog
+ 236     {
+ 237       compare key, 0x1b/escape
+ 238       break-if-!=
+ 239       var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 240       copy-to *cursor-in-go-modal-a, 0/false
+ 241       var go-modal-error-ah/eax: (addr handle array byte) <- get self, go-modal-error
+ 242       clear-object go-modal-error-ah
+ 243       return
+ 244     }
+ 245     # enter = switch to global name and exit modal dialog
+ 246     {
+ 247       compare key, 0xa/newline
+ 248       break-if-!=
+ 249       # if no global name typed in, switch to sandbox
+ 250       var partial-global-name-ah/eax: (addr handle gap-buffer) <- get self, partial-global-name
+ 251       var partial-global-name/eax: (addr gap-buffer) <- lookup *partial-global-name-ah
+ 252       {
+ 253         var empty?/eax: boolean <- gap-buffer-empty? partial-global-name
+ 254         compare empty?, 0/false
+ 255         break-if-=
+ 256         var cursor-in-globals-a/eax: (addr boolean) <- get self, cursor-in-globals?
+ 257         copy-to *cursor-in-globals-a, 0/false
+ 258         # reset error state
+ 259         var go-modal-error-ah/eax: (addr handle array byte) <- get self, go-modal-error
+ 260         clear-object go-modal-error-ah
+ 261         # done with go modal
+ 262         var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 263         copy-to *cursor-in-go-modal-a, 0/false
+ 264         return
+ 265       }
+ 266       # turn global name into a stream
+ 267       var name-storage: (stream byte 0x40)
+ 268       var name/ecx: (addr stream byte) <- address name-storage
+ 269       emit-gap-buffer partial-global-name, name
+ 270       # compute global index
+ 271       var index/ecx: int <- find-symbol-in-globals globals, name
+ 272       # if global not found, set error and return
+ 273       {
+ 274         compare index, 0
+ 275         break-if->=
+ 276         var go-modal-error-ah/eax: (addr handle array byte) <- get self, go-modal-error
+ 277         copy-array-object "no such global", go-modal-error-ah
+ 278         return
+ 279       }
+ 280       # otherwise clear modal state
+ 281       clear-gap-buffer partial-global-name
+ 282       var go-modal-error-ah/eax: (addr handle array byte) <- get self, go-modal-error
+ 283       clear-object go-modal-error-ah
+ 284       var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 285       copy-to *cursor-in-go-modal-a, 0/false
+ 286       # switch focus to global at index
+ 287       var globals-cursor-index/eax: (addr int) <- get globals, cursor-index
+ 288       copy-to *globals-cursor-index, index
+ 289       var cursor-in-globals-a/ecx: (addr boolean) <- get self, cursor-in-globals?
+ 290       copy-to *cursor-in-globals-a, 1/true
+ 291       return
+ 292     }
+ 293     # ctrl-m = create given global name and exit modal dialog
+ 294     {
+ 295       compare key, 0xd/ctrl-m
+ 296       break-if-!=
+ 297       # if no global name typed in, set error and return
+ 298       var partial-global-name-ah/eax: (addr handle gap-buffer) <- get self, partial-global-name
+ 299       var partial-global-name/eax: (addr gap-buffer) <- lookup *partial-global-name-ah
+ 300       {
+ 301         var empty?/eax: boolean <- gap-buffer-empty? partial-global-name
+ 302         compare empty?, 0/false
+ 303         break-if-=
+ 304         var go-modal-error-ah/eax: (addr handle array byte) <- get self, go-modal-error
+ 305         copy-array-object "create what?", go-modal-error-ah
+ 306         return
+ 307       }
+ 308       # turn global name into a stream
+ 309       var name-storage: (stream byte 0x40)
+ 310       var name/edx: (addr stream byte) <- address name-storage
+ 311       emit-gap-buffer partial-global-name, name
+ 312       # compute global index
+ 313       var index/ecx: int <- find-symbol-in-globals globals, name
+ 314       # if global found, set error and return
+ 315       {
+ 316         compare index, 0
+ 317         break-if-<
+ 318         var go-modal-error-ah/eax: (addr handle array byte) <- get self, go-modal-error
+ 319         copy-array-object "already exists", go-modal-error-ah
+ 320         return
+ 321       }
+ 322       # otherwise clear modal state
+ 323       clear-gap-buffer partial-global-name
+ 324       var go-modal-error-ah/eax: (addr handle array byte) <- get self, go-modal-error
+ 325       clear-object go-modal-error-ah
+ 326       var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 327       copy-to *cursor-in-go-modal-a, 0/false
+ 328       # create new global
+ 329       create-empty-global globals, name, 0x2000/default-gap-buffer-size=8KB
+ 330       var globals-final-index/eax: (addr int) <- get globals, final-index
+ 331       var new-index/ecx: int <- copy *globals-final-index
+ 332       var globals-cursor-index/eax: (addr int) <- get globals, cursor-index
+ 333       copy-to *globals-cursor-index, new-index
+ 334       var cursor-in-globals-a/ecx: (addr boolean) <- get self, cursor-in-globals?
+ 335       copy-to *cursor-in-globals-a, 1/true
+ 336       return
+ 337     }
+ 338     # otherwise process like a regular gap-buffer
+ 339     var partial-global-name-ah/eax: (addr handle gap-buffer) <- get self, partial-global-name
+ 340     var partial-global-name/eax: (addr gap-buffer) <- lookup *partial-global-name-ah
+ 341     edit-gap-buffer partial-global-name, key
+ 342     return
+ 343   }
+ 344   # ctrl-g: go to a global (or the repl)
+ 345   {
+ 346     compare key, 7/ctrl-g
+ 347     break-if-!=
+ 348     # look for a word to prepopulate the modal
+ 349     var current-word-storage: (stream byte 0x40)
+ 350     var current-word/edi: (addr stream byte) <- address current-word-storage
+ 351     word-at-cursor self, current-word
+ 352     var partial-global-name-ah/eax: (addr handle gap-buffer) <- get self, partial-global-name
+ 353     var partial-global-name/eax: (addr gap-buffer) <- lookup *partial-global-name-ah
+ 354     clear-gap-buffer partial-global-name
+ 355     load-gap-buffer-from-stream partial-global-name, current-word
+ 356     # enable the modal
+ 357     var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 358     copy-to *cursor-in-go-modal-a, 1/true
+ 359     return
+ 360   }
+ 361   # dispatch the key to either sandbox or globals
+ 362   {
+ 363     var cursor-in-globals-a/eax: (addr boolean) <- get self, cursor-in-globals?
+ 364     compare *cursor-in-globals-a, 0/false
+ 365     break-if-=
+ 366     edit-globals globals, key
+ 367     return
+ 368   }
+ 369   edit-sandbox sandbox, key, globals, data-disk
+ 370 }
+ 371 
+ 372 fn read-and-evaluate-and-save-gap-buffer-to-globals _in-ah: (addr handle gap-buffer), result-ah: (addr handle cell), globals: (addr global-table), definitions-created: (addr stream int), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell) {
+ 373   var in-ah/eax: (addr handle gap-buffer) <- copy _in-ah
+ 374   var in/eax: (addr gap-buffer) <- lookup *in-ah
+ 375   var read-result-h: (handle cell)
+ 376   var read-result-ah/esi: (addr handle cell) <- address read-result-h
+ 377   read-cell in, read-result-ah, trace
+ 378   var error?/eax: boolean <- has-errors? trace
+ 379   {
+ 380     compare error?, 0/false
+ 381     break-if-=
+ 382     return
+ 383   }
+ 384   macroexpand read-result-ah, globals, trace
+ 385   var error?/eax: boolean <- has-errors? trace
+ 386   {
+ 387     compare error?, 0/false
+ 388     break-if-=
+ 389     return
+ 390   }
+ 391   var nil-h: (handle cell)
+ 392   var nil-ah/eax: (addr handle cell) <- address nil-h
+ 393   allocate-pair nil-ah
+ 394 #?   set-cursor-position 0/screen, 0 0
+ 395 #?   turn-on-debug-print
+ 396   var call-number-storage: int
+ 397   var call-number/edi: (addr int) <- address call-number-storage
+ 398   debug-print "^", 4/fg, 0/bg
+ 399   evaluate read-result-ah, result-ah, *nil-ah, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number
+ 400   debug-print "$", 4/fg, 0/bg
+ 401   var error?/eax: boolean <- has-errors? trace
+ 402   {
+ 403     compare error?, 0/false
+ 404     break-if-=
+ 405     return
+ 406   }
+ 407   # refresh various rendering caches
+ 408   mark-lines-dirty trace
+ 409   # If any definitions were created or modified in the process, link this gap
+ 410   # buffer to them.
+ 411   # TODO: detect and create UI for conflicts.
+ 412   stash-gap-buffer-to-globals globals, definitions-created, _in-ah
+ 413 }
+ 414 
+ 415 fn test-go-modal {
+ 416   var env-storage: environment
+ 417   var env/esi: (addr environment) <- address env-storage
+ 418   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+ 419   # setup: screen
+ 420   var screen-on-stack: screen
+ 421   var screen/edi: (addr screen) <- address screen-on-stack
+ 422   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+ 423   # hit ctrl-g
+ 424   edit-environment env, 7/ctrl-g, 0/no-disk
+ 425   render-environment screen, env
+ 426   #
+ 427   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-go-modal/0"
+ 428   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-go-modal/1"
+ 429   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-go-modal/2"
+ 430   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-go-modal/3"
+ 431   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-go-modal/4"
+ 432   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-go-modal/5"
+ 433   check-screen-row                     screen,                 6/y, "                                    go to global (or leave blank to go to REPL)                                                 ", "F - test-go-modal/6-text"
+ 434   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                ................................................................                                ", "F - test-go-modal/6"
+ 435   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                ................................................................                                ", "F - test-go-modal/7"
+ 436   # cursor is in the modal
+ 437   check-background-color-in-screen-row screen,   0/bg=cursor,  8/y, "                                |                                                                                               ", "F - test-go-modal/8-cursor"
+ 438   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                 ...............................................................                                ", "F - test-go-modal/8"
+ 439   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-go-modal/9"
+ 440   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-go-modal/10"
+ 441   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-go-modal/11"
+ 442   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-go-modal/12"
+ 443   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-go-modal/13"
+ 444   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-go-modal/14"
+ 445   # menu at bottom is correct in context
+ 446   check-screen-row                     screen,               0xf/y, " ^r  run main   enter  go   ^m  create   esc  cancel   ^a  <<   ^b  <word   ^f  word>   ^e  >>                                  ", "F - test-go-modal/15-text"
+ 447   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-go-modal/15"
+ 448 }
+ 449 
+ 450 fn test-leave-go-modal {
+ 451   var env-storage: environment
+ 452   var env/esi: (addr environment) <- address env-storage
+ 453   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+ 454   # setup: screen
+ 455   var screen-on-stack: screen
+ 456   var screen/edi: (addr screen) <- address screen-on-stack
+ 457   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+ 458   # hit ctrl-g
+ 459   edit-environment env, 7/ctrl-g, 0/no-disk
+ 460   render-environment screen, env
+ 461   # cancel
+ 462   edit-environment env, 0x1b/escape, 0/no-disk
+ 463   render-environment screen, env
+ 464   # no modal
+ 465   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-leave-go-modal/0"
+ 466   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-leave-go-modal/1"
+ 467   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-leave-go-modal/2"
+ 468   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-leave-go-modal/3"
+ 469   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-leave-go-modal/4"
+ 470   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-leave-go-modal/5"
+ 471   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                                                                                                                ", "F - test-leave-go-modal/6"
+ 472   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                                                                                                                ", "F - test-leave-go-modal/7"
+ 473   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                                                                                                                ", "F - test-leave-go-modal/8"
+ 474   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-leave-go-modal/9"
+ 475   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-leave-go-modal/10"
+ 476   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-leave-go-modal/11"
+ 477   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-leave-go-modal/12"
+ 478   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-leave-go-modal/13"
+ 479   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-leave-go-modal/14"
+ 480   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-leave-go-modal/15"
+ 481 }
+ 482 
+ 483 fn test-jump-to-global {
+ 484   var env-storage: environment
+ 485   var env/esi: (addr environment) <- address env-storage
+ 486   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+ 487   # setup: screen
+ 488   var screen-on-stack: screen
+ 489   var screen/edi: (addr screen) <- address screen-on-stack
+ 490   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+ 491   # define a global
+ 492   type-in env, screen, "(define f 42)"
+ 493   edit-environment env, 0x13/ctrl-s, 0/no-disk
+ 494   render-environment screen, env
+ 495   # hit ctrl-g
+ 496   edit-environment env, 7/ctrl-g, 0/no-disk
+ 497   render-environment screen, env
+ 498   # type global name
+ 499   type-in env, screen, "f"
+ 500   # submit
+ 501   edit-environment env, 0xa/newline, 0/no-disk
+ 502   render-environment screen, env
+ 503   #                                                                 | global definitions                                                                 | sandbox
+ 504   # cursor now in global definition
+ 505   check-screen-row                     screen,                 1/y, "                                           (define f 42)                              screen:                                   ", "F - test-jump-to-global/1"
+ 506   check-background-color-in-screen-row screen,   7/bg=cursor,  1/y, "                                                        |                                                                       ", "F - test-jump-to-global/1-cursor"
+ 507   # no modal
+ 508   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-jump-to-global/bg0"
+ 509   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-jump-to-global/bg1"
+ 510   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-jump-to-global/bg2"
+ 511   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-jump-to-global/bg3"
+ 512   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-jump-to-global/bg4"
+ 513   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-jump-to-global/bg5"
+ 514   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                                                                                                                ", "F - test-jump-to-global/bg6"
+ 515   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                                                                                                                ", "F - test-jump-to-global/bg7"
+ 516   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                                                                                                                ", "F - test-jump-to-global/bg8"
+ 517   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-jump-to-global/bg9"
+ 518   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-jump-to-global/bg10"
+ 519   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-jump-to-global/bg11"
+ 520   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-jump-to-global/bg12"
+ 521   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-jump-to-global/bg13"
+ 522   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-jump-to-global/bg14"
+ 523   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-jump-to-global/bg15"
+ 524 }
+ 525 
+ 526 fn test-go-modal-prepopulates-word-at-cursor {
+ 527   var env-storage: environment
+ 528   var env/esi: (addr environment) <- address env-storage
+ 529   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+ 530   # setup: screen
+ 531   var screen-on-stack: screen
+ 532   var screen/edi: (addr screen) <- address screen-on-stack
+ 533   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+ 534   # type a word at the cursor
+ 535   type-in env, screen, "fn1"
+ 536   # hit ctrl-g
+ 537   edit-environment env, 7/ctrl-g, 0/no-disk
+ 538   render-environment screen, env
+ 539   # modal prepopulates word at cursor
+ 540   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/0"
+ 541   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/1"
+ 542   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/2"
+ 543   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/3"
+ 544   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/4"
+ 545   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/5"
+ 546   check-screen-row                     screen,                 6/y, "                                    go to global (or leave blank to go to REPL)                                                 ", "F - test-go-modal-prepopulates-word-at-cursor/6-text"
+ 547   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                ................................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/6"
+ 548   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                ................................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/7"
+ 549   # word at cursor
+ 550   check-screen-row                     screen,                 8/y, "                                fn1                                                                                             ", "F - test-go-modal-prepopulates-word-at-cursor/8-text"
+ 551   # new cursor position
+ 552   check-background-color-in-screen-row screen,   0/bg=cursor,  8/y, "                                   |                                                                                            ", "F - test-go-modal-prepopulates-word-at-cursor/8-cursor"
+ 553   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                ... ............................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/8"
+ 554   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/9"
+ 555   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/10"
+ 556   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/11"
+ 557   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/12"
+ 558   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/13"
+ 559   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/14"
+ 560   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/15"
+ 561   # cancel
+ 562   edit-environment env, 0x1b/escape, 0/no-disk
+ 563   render-environment screen, env
+ 564   # type one more space
+ 565   edit-environment env, 0x20/space, 0/no-disk
+ 566   render-environment screen, env
+ 567   # hit ctrl-g again
+ 568   edit-environment env, 7/ctrl-g, 0/no-disk
+ 569   render-environment screen, env
+ 570   # no word prepopulated since cursor is not on the word
+ 571   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-0"
+ 572   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-1"
+ 573   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-2"
+ 574   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-3"
+ 575   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-4"
+ 576   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-5"
+ 577   check-screen-row                     screen,                 6/y, "                                    go to global (or leave blank to go to REPL)                                                 ", "F - test-go-modal-prepopulates-word-at-cursor/test2-6-text"
+ 578   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                ................................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-6"
+ 579   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                ................................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-7"
+ 580   # no word at cursor
+ 581   check-screen-row                     screen,                 8/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-8-text"
+ 582   # new cursor position
+ 583   check-background-color-in-screen-row screen,   0/bg=cursor,  8/y, "                                |                                                                                               ", "F - test-go-modal-prepopulates-word-at-cursor/test2-8-cursor"
+ 584   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                 ...............................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-8"
+ 585   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-9"
+ 586   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-10"
+ 587   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-11"
+ 588   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-12"
+ 589   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-13"
+ 590   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-14"
+ 591   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test2-15"
+ 592   # cancel
+ 593   edit-environment env, 0x1b/escape, 0/no-disk
+ 594   render-environment screen, env
+ 595   # move cursor to the left until it's on the word again
+ 596   edit-environment env, 0x80/left-arrow, 0/no-disk
+ 597   render-environment screen, env
+ 598   edit-environment env, 0x80/left-arrow, 0/no-disk
+ 599   render-environment screen, env
+ 600   # hit ctrl-g again
+ 601   edit-environment env, 7/ctrl-g, 0/no-disk
+ 602   render-environment screen, env
+ 603   # word prepopulated like before
+ 604   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-0"
+ 605   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-1"
+ 606   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-2"
+ 607   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-3"
+ 608   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-4"
+ 609   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-5"
+ 610   check-screen-row                     screen,                 6/y, "                                    go to global (or leave blank to go to REPL)                                                 ", "F - test-go-modal-prepopulates-word-at-cursor/test3-6-text"
+ 611   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                ................................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-6"
+ 612   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                ................................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-7"
+ 613   # word at cursor
+ 614   check-screen-row                     screen,                 8/y, "                                fn1                                                                                             ", "F - test-go-modal-prepopulates-word-at-cursor/test3-8-text"
+ 615   # new cursor position
+ 616   check-background-color-in-screen-row screen,   0/bg=cursor,  8/y, "                                   |                                                                                            ", "F - test-go-modal-prepopulates-word-at-cursor/test3-8-cursor"
+ 617   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                ... ............................................................                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-8"
+ 618   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-9"
+ 619   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-10"
+ 620   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-11"
+ 621   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-12"
+ 622   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-13"
+ 623   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-14"
+ 624   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-go-modal-prepopulates-word-at-cursor/test3-15"
+ 625 }
+ 626 
+ 627 fn test-jump-to-nonexistent-global {
+ 628   var env-storage: environment
+ 629   var env/esi: (addr environment) <- address env-storage
+ 630   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+ 631   # setup: screen
+ 632   var screen-on-stack: screen
+ 633   var screen/edi: (addr screen) <- address screen-on-stack
+ 634   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+ 635   # type in any (nonexistent) global name
+ 636   type-in env, screen, "f"
+ 637   # hit ctrl-g
+ 638   edit-environment env, 7/ctrl-g, 0/no-disk
+ 639   render-environment screen, env
+ 640   # submit
+ 641   edit-environment env, 0xa/newline, 0/no-disk
+ 642   render-environment screen, env
+ 643   # modal now shows an error
+ 644   #                                                                 | global definitions                                                                 | sandbox
+ 645   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/0"
+ 646   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/1"
+ 647   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/2"
+ 648   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/3"
+ 649   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/4"
+ 650   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/5"
+ 651   check-screen-row                     screen,                 6/y, "                                    go to global (or leave blank to go to REPL)                                                 ", "F - test-jump-to-nonexistent-global/6-text"
+ 652   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                ................................................................                                ", "F - test-jump-to-nonexistent-global/6"
+ 653   check-screen-row-in-color            screen, 4/fg=error,     7/y, "                                no such global                                                                                  ", "F - test-jump-to-nonexistent-global/7-text"
+ 654   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                ................................................................                                ", "F - test-jump-to-nonexistent-global/7"
+ 655   check-screen-row                     screen,                 8/y, "                                f                                                                                               ", "F - test-jump-to-nonexistent-global/8-text"
+ 656   check-background-color-in-screen-row screen,   0/bg=cursor,  8/y, "                                 |                                                                                              ", "F - test-jump-to-nonexistent-global/8-cursor"
+ 657   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                . ..............................................................                                ", "F - test-jump-to-nonexistent-global/8"
+ 658   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/9"
+ 659   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/10"
+ 660   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/11"
+ 661   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/12"
+ 662   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/13"
+ 663   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/14"
+ 664   # menu at bottom is correct in context
+ 665   check-screen-row                     screen,               0xf/y, " ^r  run main   enter  go   ^m  create   esc  cancel   ^a  <<   ^b  <word   ^f  word>   ^e  >>                                  ", "F - test-jump-to-nonexistent-global/15-text"
+ 666   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/15"
+ 667   # cancel
+ 668   edit-environment env, 0x1b/escape, 0/no-disk
+ 669   render-environment screen, env
+ 670   # hit ctrl-g again
+ 671   edit-environment env, 7/ctrl-g, 0/no-disk
+ 672   render-environment screen, env
+ 673   # word prepopulated like before, but no error
+ 674   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-0"
+ 675   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-1"
+ 676   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-2"
+ 677   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-3"
+ 678   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-4"
+ 679   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-5"
+ 680   check-screen-row                     screen,                 6/y, "                                    go to global (or leave blank to go to REPL)                                                 ", "F - test-jump-to-nonexistent-global/test2-6-text"
+ 681   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                ................................................................                                ", "F - test-jump-to-nonexistent-global/test2-6"
+ 682   check-screen-row-in-color            screen, 4/fg=error,     7/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-7-text"
+ 683   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                ................................................................                                ", "F - test-jump-to-nonexistent-global/test2-7"
+ 684   # same word at cursor
+ 685   check-screen-row                     screen,                 8/y, "                                f                                                                                               ", "F - test-jump-to-nonexistent-global/test2-8-text"
+ 686   # new cursor position
+ 687   check-background-color-in-screen-row screen,   0/bg=cursor,  8/y, "                                 |                                                                                              ", "F - test-jump-to-nonexistent-global/test2-8-cursor"
+ 688   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                . ..............................................................                                ", "F - test-jump-to-nonexistent-global/test2-8"
+ 689   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-9"
+ 690   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-10"
+ 691   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-11"
+ 692   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-12"
+ 693   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-13"
+ 694   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-14"
+ 695   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-jump-to-nonexistent-global/test2-15"
+ 696 }
+ 697 
+ 698 fn test-create-global {
+ 699   var env-storage: environment
+ 700   var env/esi: (addr environment) <- address env-storage
+ 701   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+ 702   # setup: screen
+ 703   var screen-on-stack: screen
+ 704   var screen/edi: (addr screen) <- address screen-on-stack
+ 705   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+ 706   # hit ctrl-g
+ 707   edit-environment env, 7/ctrl-g, 0/no-disk
+ 708   render-environment screen, env
+ 709   # type global name
+ 710   type-in env, screen, "fn1"
+ 711   # create
+ 712   edit-environment env, 0xd/ctrl-m, 0/no-disk
+ 713   render-environment screen, env
+ 714   #                                                                 | global definitions                                                                 | sandbox
+ 715   # cursor now on global side
+ 716   check-background-color-in-screen-row screen,   7/bg=cursor,  1/y, "                                           |                                                                                    ", "F - test-create-global/1-cursor"
+ 717   # no modal
+ 718   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-create-global/bg0"
+ 719   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-create-global/bg1"
+ 720   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-create-global/bg2"
+ 721   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-create-global/bg3"
+ 722   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-create-global/bg4"
+ 723   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-create-global/bg5"
+ 724   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                                                                                                                ", "F - test-create-global/bg6"
+ 725   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                                                                                                                ", "F - test-create-global/bg7"
+ 726   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                                                                                                                ", "F - test-create-global/bg8"
+ 727   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-create-global/bg9"
+ 728   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-create-global/bg10"
+ 729   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-create-global/bg11"
+ 730   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-create-global/bg12"
+ 731   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-create-global/bg13"
+ 732   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-create-global/bg14"
+ 733   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-create-global/bg15"
+ 734 }
+ 735 
+ 736 fn test-create-nonexistent-global {
+ 737   var env-storage: environment
+ 738   var env/esi: (addr environment) <- address env-storage
+ 739   initialize-environment env, 8/fake-screen-width, 3/fake-screen-height
+ 740   # setup: screen
+ 741   var screen-on-stack: screen
+ 742   var screen/edi: (addr screen) <- address screen-on-stack
+ 743   initialize-screen screen, 0x80/width=72, 0x10/height, 0/no-pixel-graphics
+ 744   # define a global
+ 745   type-in env, screen, "(define f 42)"
+ 746   edit-environment env, 0x13/ctrl-s, 0/no-disk
+ 747   render-environment screen, env
+ 748   # type in its name
+ 749   type-in env, screen, "f"
+ 750   # hit ctrl-g
+ 751   edit-environment env, 7/ctrl-g, 0/no-disk
+ 752   render-environment screen, env
+ 753   # submit
+ 754   edit-environment env, 0xd/ctrl-m, 0/no-disk
+ 755   render-environment screen, env
+ 756   # modal now shows an error
+ 757   #                                                                 | global definitions                                                                 | sandbox
+ 758   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-create-nonexistent-global/0"
+ 759   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-create-nonexistent-global/1"
+ 760   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-create-nonexistent-global/2"
+ 761   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-create-nonexistent-global/3"
+ 762   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-create-nonexistent-global/4"
+ 763   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-create-nonexistent-global/5"
+ 764   check-screen-row                     screen,                 6/y, "                                    go to global (or leave blank to go to REPL)                                                 ", "F - test-create-nonexistent-global/6-text"
+ 765   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                ................................................................                                ", "F - test-create-nonexistent-global/6"
+ 766   check-screen-row-in-color            screen, 4/fg=error,     7/y, "                                already exists                                                                                  ", "F - test-create-nonexistent-global/7-text"
+ 767   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                ................................................................                                ", "F - test-create-nonexistent-global/7"
+ 768   check-screen-row-in-color            screen, 0/fg,           8/y, "                                f                                                                                               ", "F - test-create-nonexistent-global/8-text"
+ 769   check-background-color-in-screen-row screen,   0/bg=cursor,  8/y, "                                 |                                                                                              ", "F - test-create-nonexistent-global/8-cursor"
+ 770   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                . ..............................................................                                ", "F - test-create-nonexistent-global/8"
+ 771   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-create-nonexistent-global/9"
+ 772   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-create-nonexistent-global/10"
+ 773   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-create-nonexistent-global/11"
+ 774   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-create-nonexistent-global/12"
+ 775   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-create-nonexistent-global/13"
+ 776   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-create-nonexistent-global/14"
+ 777   # menu at bottom is correct in context
+ 778   check-screen-row                     screen,               0xf/y, " ^r  run main   enter  go   ^m  create   esc  cancel   ^a  <<   ^b  <word   ^f  word>   ^e  >>                                  ", "F - test-create-nonexistent-global/15-text"
+ 779   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-create-nonexistent-global/15"
+ 780   # cancel
+ 781   edit-environment env, 0x1b/escape, 0/no-disk
+ 782   render-environment screen, env
+ 783   # hit ctrl-g again
+ 784   edit-environment env, 7/ctrl-g, 0/no-disk
+ 785   render-environment screen, env
+ 786   # word prepopulated like before, but no error
+ 787   check-background-color-in-screen-row screen, 0xf/bg=modal,   0/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-0"
+ 788   check-background-color-in-screen-row screen, 0xf/bg=modal,   1/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-1"
+ 789   check-background-color-in-screen-row screen, 0xf/bg=modal,   2/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-2"
+ 790   check-background-color-in-screen-row screen, 0xf/bg=modal,   3/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-3"
+ 791   check-background-color-in-screen-row screen, 0xf/bg=modal,   4/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-4"
+ 792   check-background-color-in-screen-row screen, 0xf/bg=modal,   5/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-5"
+ 793   check-screen-row                     screen,                 6/y, "                                    go to global (or leave blank to go to REPL)                                                 ", "F - test-create-nonexistent-global/test2-6-text"
+ 794   check-background-color-in-screen-row screen, 0xf/bg=modal,   6/y, "                                ................................................................                                ", "F - test-create-nonexistent-global/test2-6"
+ 795   check-screen-row-in-color            screen, 4/fg=error,     7/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-7-text"
+ 796   check-background-color-in-screen-row screen, 0xf/bg=modal,   7/y, "                                ................................................................                                ", "F - test-create-nonexistent-global/test2-7"
+ 797   # same word at cursor
+ 798   check-screen-row-in-color            screen, 0/fg,           8/y, "                                f                                                                                               ", "F - test-create-nonexistent-global/test2-8-text"
+ 799   # new cursor position
+ 800   check-background-color-in-screen-row screen,   0/bg=cursor,  8/y, "                                 |                                                                                              ", "F - test-create-nonexistent-global/test2-8-cursor"
+ 801   check-background-color-in-screen-row screen, 0xf/bg=modal,   8/y, "                                . ..............................................................                                ", "F - test-create-nonexistent-global/test2-8"
+ 802   check-background-color-in-screen-row screen, 0xf/bg=modal,   9/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-9"
+ 803   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xa/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-10"
+ 804   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xb/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-11"
+ 805   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xc/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-12"
+ 806   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xd/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-13"
+ 807   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xe/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-14"
+ 808   check-background-color-in-screen-row screen, 0xf/bg=modal, 0xf/y, "                                                                                                                                ", "F - test-create-nonexistent-global/test2-15"
+ 809 }
+ 810 
+ 811 fn render-go-modal screen: (addr screen), _self: (addr environment) {
+ 812   var self/esi: (addr environment) <- copy _self
+ 813   var width/eax: int <- copy 0
+ 814   var height/ecx: int <- copy 0
+ 815   width, height <- screen-size screen
+ 816   # xmin = max(0, width/2 - 0x20)
+ 817   var xmin: int
+ 818   var tmp/edx: int <- copy width
+ 819   tmp <- shift-right 1
+ 820   tmp <- subtract 0x20/half-global-name-capacity
+ 821   {
+ 822     compare tmp, 0
+ 823     break-if->=
+ 824     tmp <- copy 0
+ 825   }
+ 826   copy-to xmin, tmp
+ 827   # xmax = min(width, width/2 + 0x20)
+ 828   var xmax: int
+ 829   tmp <- copy width
+ 830   tmp <- shift-right 1
+ 831   tmp <- add 0x20/half-global-name-capacity
+ 832   {
+ 833     compare tmp, width
+ 834     break-if-<=
+ 835     tmp <- copy width
+ 836   }
+ 837   copy-to xmax, tmp
+ 838   # ymin = height/2 - 2
+ 839   var ymin: int
+ 840   tmp <- copy height
+ 841   tmp <- shift-right 1
+ 842   tmp <- subtract 2
+ 843   copy-to ymin, tmp
+ 844   # ymax = height/2 + 1
+ 845   var ymax: int
+ 846   tmp <- add 3
+ 847   copy-to ymax, tmp
+ 848   #
+ 849   clear-rect screen, xmin, ymin, xmax, ymax, 0xf/bg=modal
+ 850   add-to xmin, 4
+ 851   set-cursor-position screen, xmin, ymin
+ 852   draw-text-rightward-from-cursor screen, "go to global (or leave blank to go to REPL)", xmax, 8/fg=dark-grey, 0xf/bg=modal
+ 853   var partial-global-name-ah/eax: (addr handle gap-buffer) <- get self, partial-global-name
+ 854   var _partial-global-name/eax: (addr gap-buffer) <- lookup *partial-global-name-ah
+ 855   var partial-global-name/edx: (addr gap-buffer) <- copy _partial-global-name
+ 856   subtract-from xmin, 4
+ 857   increment ymin
+ 858   {
+ 859     var go-modal-error-ah/eax: (addr handle array byte) <- get self, go-modal-error
+ 860     var go-modal-error/eax: (addr array byte) <- lookup *go-modal-error-ah
+ 861     compare go-modal-error, 0
+ 862     break-if-=
+ 863     var dummy/eax: int <- draw-text-rightward screen, go-modal-error, xmin, xmax, ymin, 4/fg=error, 0xf/bg=modal
+ 864   }
+ 865   increment ymin
+ 866   var dummy/eax: int <- copy 0
+ 867   var dummy2/ecx: int <- copy 0
+ 868   dummy, dummy2 <- render-gap-buffer-wrapping-right-then-down screen, partial-global-name, xmin, ymin, xmax, ymax, 1/always-render-cursor, 0/fg=black, 0xf/bg=modal
+ 869 }
+ 870 
+ 871 fn render-go-modal-menu screen: (addr screen), _self: (addr environment) {
+ 872   var self/esi: (addr environment) <- copy _self
+ 873   var _width/eax: int <- copy 0
+ 874   var height/ecx: int <- copy 0
+ 875   _width, height <- screen-size screen
+ 876   var width/edx: int <- copy _width
+ 877   var y/ecx: int <- copy height
+ 878   y <- decrement
+ 879   var height/ebx: int <- copy y
+ 880   height <- increment
+ 881   clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg
+ 882   set-cursor-position screen, 0/x, y
+ 883   draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight
+ 884   draw-text-rightward-from-cursor screen, " run main  ", width, 7/fg, 0xc5/bg=blue-bg
+ 885   draw-text-rightward-from-cursor screen, " enter ", width, 0/fg, 0xc/bg=menu-really-highlight
+ 886   draw-text-rightward-from-cursor screen, " go  ", width, 7/fg, 0xc5/bg=blue-bg
+ 887   draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 0xc/bg=menu-really-highlight
+ 888   draw-text-rightward-from-cursor screen, " create  ", width, 7/fg, 0xc5/bg=blue-bg
+ 889   draw-text-rightward-from-cursor screen, " esc ", width, 0/fg, 0x5c/bg=menu-highlight
+ 890   draw-text-rightward-from-cursor screen, " cancel  ", width, 7/fg, 0xc5/bg=blue-bg
+ 891   draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight
+ 892   draw-text-rightward-from-cursor screen, " <<  ", width, 7/fg, 0xc5/bg=blue-bg
+ 893   draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight
+ 894   draw-text-rightward-from-cursor screen, " <word  ", width, 7/fg, 0xc5/bg=blue-bg
+ 895   draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight
+ 896   draw-text-rightward-from-cursor screen, " word>  ", width, 7/fg, 0xc5/bg=blue-bg
+ 897   draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight
+ 898   draw-text-rightward-from-cursor screen, " >>  ", width, 7/fg, 0xc5/bg=blue-bg
+ 899 }
+ 900 
+ 901 fn word-at-cursor _self: (addr environment), out: (addr stream byte) {
+ 902   var self/esi: (addr environment) <- copy _self
+ 903   var cursor-in-go-modal-a/eax: (addr boolean) <- get self, cursor-in-go-modal?
+ 904   compare *cursor-in-go-modal-a, 0/false
+ 905   {
+ 906     break-if-=
+ 907     # cursor in go modal
+ 908     return
+ 909   }
+ 910   var cursor-in-globals-a/edx: (addr boolean) <- get self, cursor-in-globals?
+ 911   compare *cursor-in-globals-a, 0/false
+ 912   {
+ 913     break-if-=
+ 914     # cursor in some global editor
+ 915     var globals/eax: (addr global-table) <- get self, globals
+ 916     var cursor-index-addr/ecx: (addr int) <- get globals, cursor-index
+ 917     var cursor-index/ecx: int <- copy *cursor-index-addr
+ 918     var globals-data-ah/eax: (addr handle array global) <- get globals, data
+ 919     var globals-data/eax: (addr array global) <- lookup *globals-data-ah
+ 920     var cursor-offset/ecx: (offset global) <- compute-offset globals-data, cursor-index
+ 921     var curr-global/eax: (addr global) <- index globals-data, cursor-offset
+ 922     var curr-global-data-ah/eax: (addr handle gap-buffer) <- get curr-global, input
+ 923     var curr-global-data/eax: (addr gap-buffer) <- lookup *curr-global-data-ah
+ 924     word-at-gap curr-global-data, out
+ 925     return
+ 926   }
+ 927   # cursor in sandbox
+ 928   var sandbox/ecx: (addr sandbox) <- get self, sandbox
+ 929   var sandbox-data-ah/eax: (addr handle gap-buffer) <- get sandbox, data
+ 930   var sandbox-data/eax: (addr gap-buffer) <- lookup *sandbox-data-ah
+ 931   word-at-gap sandbox-data, out
+ 932 }
+ 933 
+ 934 # Gotcha: some saved state may not load.
+ 935 fn load-state _self: (addr environment), data-disk: (addr disk) {
+ 936   var self/esi: (addr environment) <- copy _self
+ 937   # data-disk -> stream
+ 938   var s-storage: (stream byte 0x2000)  # space for 16/sectors
+ 939   var s/ebx: (addr stream byte) <- address s-storage
+ 940   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "loading sectors from data disk", 3/fg, 0/bg
+ 941   move-cursor-to-left-margin-of-next-line 0/screen
+ 942   load-sectors data-disk, 0/lba, 0x10/sectors, s
+ 943 #?   draw-stream-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, s, 7/fg, 0xc5/bg=blue-bg
+ 944   # stream -> gap-buffer (HACK: we temporarily cannibalize the sandbox's gap-buffer)
+ 945   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "parsing", 3/fg, 0/bg
+ 946   move-cursor-to-left-margin-of-next-line 0/screen
+ 947   var sandbox/eax: (addr sandbox) <- get self, sandbox
+ 948   var data-ah/eax: (addr handle gap-buffer) <- get sandbox, data
+ 949   var data/eax: (addr gap-buffer) <- lookup *data-ah
+ 950   load-gap-buffer-from-stream data, s
+ 951   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "  into gap buffer", 3/fg, 0/bg
+ 952   move-cursor-to-left-margin-of-next-line 0/screen
+ 953   clear-stream s
+ 954   # read: gap-buffer -> cell
+ 955   var initial-root-storage: (handle cell)
+ 956   var initial-root/ecx: (addr handle cell) <- address initial-root-storage
+ 957   var trace-storage: trace
+ 958   var trace/edi: (addr trace) <- address trace-storage
+ 959   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 960   read-cell data, initial-root, trace
+ 961   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "  into s-expressions", 3/fg, 0/bg
+ 962   move-cursor-to-left-margin-of-next-line 0/screen
+ 963   clear-gap-buffer data
+ 964   #
+ 965   {
+ 966     var initial-root-addr/eax: (addr cell) <- lookup *initial-root
+ 967     compare initial-root-addr, 0
+ 968     break-if-!=
+ 969     return
+ 970   }
+ 971   # load globals from assoc(initial-root, 'globals)
+ 972   var globals-literal-storage: (handle cell)
+ 973   var globals-literal-ah/eax: (addr handle cell) <- address globals-literal-storage
+ 974   new-symbol globals-literal-ah, "globals"
+ 975   var globals-literal/eax: (addr cell) <- lookup *globals-literal-ah
+ 976   var globals-cell-storage: (handle cell)
+ 977   var globals-cell-ah/edx: (addr handle cell) <- address globals-cell-storage
+ 978   clear-trace trace
+ 979   lookup-symbol globals-literal, globals-cell-ah, *initial-root, 0/no-globals, trace, 0/no-screen, 0/no-keyboard
+ 980   var globals-cell/eax: (addr cell) <- lookup *globals-cell-ah
+ 981   {
+ 982     compare globals-cell, 0
+ 983     break-if-=
+ 984     var globals/eax: (addr global-table) <- get self, globals
+ 985     load-globals globals-cell-ah, globals
+ 986   }
+ 987   # sandbox = assoc(initial-root, 'sandbox)
+ 988   draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "loading sandbox", 3/fg, 0/bg
+ 989   var sandbox-literal-storage: (handle cell)
+ 990   var sandbox-literal-ah/eax: (addr handle cell) <- address sandbox-literal-storage
+ 991   new-symbol sandbox-literal-ah, "sandbox"
+ 992   var sandbox-literal/eax: (addr cell) <- lookup *sandbox-literal-ah
+ 993   var sandbox-cell-storage: (handle cell)
+ 994   var sandbox-cell-ah/edx: (addr handle cell) <- address sandbox-cell-storage
+ 995   clear-trace trace
+ 996   lookup-symbol sandbox-literal, sandbox-cell-ah, *initial-root, 0/no-globals, trace, 0/no-screen, 0/no-keyboard
+ 997   var sandbox-cell/eax: (addr cell) <- lookup *sandbox-cell-ah
+ 998   {
+ 999     compare sandbox-cell, 0
+1000     break-if-=
+1001     # print: cell -> stream
+1002     clear-trace trace
+1003     print-cell sandbox-cell-ah, s, trace
+1004     # stream -> gap-buffer
+1005     var sandbox/eax: (addr sandbox) <- get self, sandbox
+1006     var data-ah/eax: (addr handle gap-buffer) <- get sandbox, data
+1007     var data/eax: (addr gap-buffer) <- lookup *data-ah
+1008     load-gap-buffer-from-stream data, s
+1009   }
+1010 }
+1011 
+1012 # Save state as an alist of alists:
+1013 #   ((globals . ((a . (fn ...))
+1014 #                ...))
+1015 #    (sandbox . ...))
+1016 fn store-state data-disk: (addr disk), sandbox: (addr sandbox), globals: (addr global-table) {
+1017   compare data-disk, 0/no-disk
+1018   {
+1019     break-if-!=
+1020     return
+1021   }
+1022   var stream-storage: (stream byte 0x2000)  # space enough for 16/sectors
+1023   var stream/edi: (addr stream byte) <- address stream-storage
+1024   write stream, "(\n"
+1025   write-globals stream, globals
+1026   write-sandbox stream, sandbox
+1027   write stream, ")\n"
+1028   store-sectors data-disk, 0/lba, 0x10/sectors, stream
+1029 }
 
diff --git a/html/shell/evaluate.mu.html b/html/shell/evaluate.mu.html index 7e81fa31..cb252db0 100644 --- a/html/shell/evaluate.mu.html +++ b/html/shell/evaluate.mu.html @@ -17,6 +17,7 @@ a { color:inherit; } .LineNr { } .Delimiter { color: #c000c0; } .CommentedCode { color: #8a8a8a; } +.muRegEdx { color: #878700; } .muRegEbx { color: #8787af; } .muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } @@ -29,7 +30,6 @@ a { color:inherit; } .muComment { color: #005faf; } .muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } --> @@ -69,533 +69,533 @@ if ('onhashchange' in window) { 2 # we never modify `_in-ah` or `env` 3 # ignore args past 'trace' on a first reading; they're for the environment not the language 4 # 'call-number' is just for showing intermediate progress; this is a _slow_ interpreter - 5 # side-effects if not in a test (screen-cell != 0): - 6 # prints intermediate states of the screen to real screen - 7 # stops if a keypress is encountered - 8 fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int { - 9 # stack overflow? # disable when enabling Really-debug-print - 10 check-stack - 11 { - 12 var screen-cell/eax: (addr handle cell) <- copy screen-cell - 13 compare screen-cell, 0 - 14 break-if-= - 15 var screen-cell-addr/eax: (addr cell) <- lookup *screen-cell - 16 compare screen-cell-addr, 0 - 17 break-if-= - 18 # if screen-cell exists, we're probably not in a test - 19 show-stack-state - 20 } - 21 # show intermediate progress on screen if necessary - 22 # treat input at the real keyboard as interrupting - 23 { - 24 compare screen-cell, 0 - 25 break-if-= - 26 var tmp/eax: int <- copy call-number - 27 tmp <- and 0xf # every 16 calls to evaluate - 28 compare tmp, 0 - 29 break-if-!= - 30 var screen-cell/eax: (addr handle cell) <- copy screen-cell - 31 var screen-cell-addr/eax: (addr cell) <- lookup *screen-cell - 32 compare screen-cell-addr, 0 - 33 break-if-= - 34 var screen-obj-ah/eax: (addr handle screen) <- get screen-cell-addr, screen-data - 35 var screen-obj/eax: (addr screen) <- lookup *screen-obj-ah - 36 compare screen-obj, 0 - 37 break-if-= - 38 var y/ecx: int <- render-screen 0/screen, screen-obj, 0x70/xmin, 1/ymin - 39 var key/eax: byte <- read-key 0/keyboard - 40 compare key, 0 - 41 break-if-= - 42 error trace, "key pressed; interrupting..." - 43 } - 44 # errors? skip - 45 { - 46 var error?/eax: boolean <- has-errors? trace - 47 compare error?, 0/false - 48 break-if-= - 49 return - 50 } - 51 var in-ah/esi: (addr handle cell) <- copy _in-ah - 52 #? dump-cell in-ah - 53 #? { - 54 #? var foo/eax: byte <- read-key 0/keyboard - 55 #? compare foo, 0 - 56 #? loop-if-= - 57 #? } - 58 +-- 19 lines: # trace "evaluate " in " in environment " env ----------------------------------------------------------------------------------------------------------------------------- - 77 trace-lower trace - 78 var in/eax: (addr cell) <- lookup *in-ah - 79 { - 80 var nil?/eax: boolean <- nil? in - 81 compare nil?, 0/false - 82 break-if-= - 83 # nil is a literal - 84 trace-text trace, "eval", "nil" - 85 copy-object _in-ah, _out-ah - 86 trace-higher trace - 87 return - 88 } - 89 var in-type/ecx: (addr int) <- get in, type - 90 compare *in-type, 1/number - 91 { - 92 break-if-!= - 93 # numbers are literals - 94 trace-text trace, "eval", "number" - 95 copy-object _in-ah, _out-ah - 96 trace-higher trace - 97 return - 98 } - 99 compare *in-type, 3/stream - 100 { - 101 break-if-!= - 102 # streams are literals - 103 trace-text trace, "eval", "stream" - 104 copy-object _in-ah, _out-ah - 105 trace-higher trace - 106 return - 107 } - 108 compare *in-type, 2/symbol - 109 { - 110 break-if-!= - 111 trace-text trace, "eval", "symbol" - 112 debug-print "a", 7/fg, 0/bg - 113 lookup-symbol in, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell - 114 debug-print "z", 7/fg, 0/bg - 115 trace-higher trace - 116 return - 117 } - 118 compare *in-type, 5/screen - 119 { - 120 break-if-!= - 121 trace-text trace, "eval", "screen" - 122 copy-object _in-ah, _out-ah - 123 trace-higher trace - 124 return - 125 } - 126 compare *in-type, 6/keyboard - 127 { - 128 break-if-!= - 129 trace-text trace, "eval", "keyboard" - 130 copy-object _in-ah, _out-ah - 131 trace-higher trace - 132 return - 133 } - 134 # 'in' is a syntax tree - 135 $evaluate:literal-function: { - 136 # trees starting with "litfn" are literals - 137 var expr/esi: (addr cell) <- copy in - 138 var in/edx: (addr cell) <- copy in - 139 var first-ah/ecx: (addr handle cell) <- get in, left - 140 var first/eax: (addr cell) <- lookup *first-ah - 141 var litfn?/eax: boolean <- litfn? first - 142 compare litfn?, 0/false - 143 break-if-= - 144 trace-text trace, "eval", "literal function" - 145 copy-object _in-ah, _out-ah - 146 trace-higher trace - 147 return - 148 } - 149 $evaluate:literal-macro: { - 150 # trees starting with "litmac" are literals - 151 var expr/esi: (addr cell) <- copy in - 152 var in/edx: (addr cell) <- copy in - 153 var first-ah/ecx: (addr handle cell) <- get in, left - 154 var first/eax: (addr cell) <- lookup *first-ah - 155 var litmac?/eax: boolean <- litmac? first - 156 compare litmac?, 0/false - 157 break-if-= - 158 trace-text trace, "eval", "literal macro" - 159 copy-object _in-ah, _out-ah - 160 trace-higher trace - 161 return - 162 } - 163 $evaluate:anonymous-function: { - 164 # trees starting with "fn" are anonymous functions - 165 var expr/esi: (addr cell) <- copy in - 166 var in/edx: (addr cell) <- copy in - 167 var first-ah/ecx: (addr handle cell) <- get in, left - 168 var first/eax: (addr cell) <- lookup *first-ah - 169 var fn?/eax: boolean <- fn? first - 170 compare fn?, 0/false - 171 break-if-= - 172 # turn (fn ...) into (litfn env ...) - 173 trace-text trace, "eval", "anonymous function" - 174 var rest-ah/eax: (addr handle cell) <- get in, right - 175 var tmp: (handle cell) - 176 var tmp-ah/edi: (addr handle cell) <- address tmp - 177 new-pair tmp-ah, env-h, *rest-ah - 178 var litfn: (handle cell) - 179 var litfn-ah/eax: (addr handle cell) <- address litfn - 180 new-symbol litfn-ah, "litfn" - 181 new-pair _out-ah, *litfn-ah, *tmp-ah - 182 trace-higher trace - 183 return - 184 } - 185 # builtins with "special" evaluation rules - 186 $evaluate:quote: { - 187 # trees starting with single quote create literals - 188 var expr/esi: (addr cell) <- copy in - 189 # if its first elem is not "'", break - 190 var first-ah/ecx: (addr handle cell) <- get in, left - 191 var rest-ah/edx: (addr handle cell) <- get in, right - 192 var first/eax: (addr cell) <- lookup *first-ah - 193 var quote?/eax: boolean <- symbol-equal? first, "'" - 194 compare quote?, 0/false - 195 break-if-= - 196 # - 197 trace-text trace, "eval", "quote" - 198 copy-object rest-ah, _out-ah - 199 trace-higher trace - 200 return - 201 } - 202 $evaluate:backquote: { - 203 # trees starting with single backquote create literals - 204 var expr/esi: (addr cell) <- copy in - 205 # if its first elem is not "'", break - 206 var first-ah/ecx: (addr handle cell) <- get in, left - 207 var rest-ah/edx: (addr handle cell) <- get in, right - 208 var first/eax: (addr cell) <- lookup *first-ah - 209 var backquote?/eax: boolean <- symbol-equal? first, "`" - 210 compare backquote?, 0/false - 211 break-if-= - 212 # - 213 trace-text trace, "eval", "backquote" - 214 debug-print "`(", 7/fg, 0/bg - 215 evaluate-backquote rest-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 216 debug-print ")", 7/fg, 0/bg - 217 trace-higher trace - 218 return - 219 } - 220 $evaluate:define: { - 221 # trees starting with "define" define globals - 222 var expr/esi: (addr cell) <- copy in - 223 # if its first elem is not "define", break - 224 var first-ah/ecx: (addr handle cell) <- get in, left - 225 var rest-ah/edx: (addr handle cell) <- get in, right - 226 var first/eax: (addr cell) <- lookup *first-ah - 227 var define?/eax: boolean <- symbol-equal? first, "define" - 228 compare define?, 0/false - 229 break-if-= - 230 # - 231 trace-text trace, "eval", "define" - 232 trace-text trace, "eval", "evaluating second arg" - 233 var rest/eax: (addr cell) <- lookup *rest-ah - 234 var first-arg-ah/ecx: (addr handle cell) <- get rest, left - 235 { - 236 var first-arg/eax: (addr cell) <- lookup *first-arg-ah - 237 var first-arg-type/eax: (addr int) <- get first-arg, type - 238 compare *first-arg-type, 2/symbol - 239 break-if-= - 240 error trace, "first arg to define must be a symbol" - 241 trace-higher trace - 242 return - 243 } - 244 rest-ah <- get rest, right - 245 rest <- lookup *rest-ah - 246 var second-arg-ah/edx: (addr handle cell) <- get rest, left - 247 debug-print "P", 4/fg, 0/bg - 248 increment call-number - 249 evaluate second-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 250 debug-print "Q", 4/fg, 0/bg - 251 # errors? skip - 252 { - 253 var error?/eax: boolean <- has-errors? trace - 254 compare error?, 0/false - 255 break-if-= - 256 trace-higher trace - 257 return - 258 } - 259 trace-text trace, "eval", "saving global binding" - 260 var first-arg/eax: (addr cell) <- lookup *first-arg-ah - 261 var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data - 262 var first-arg-data/eax: (addr stream byte) <- lookup *first-arg-data-ah - 263 var tmp-string: (handle array byte) - 264 var tmp-ah/edx: (addr handle array byte) <- address tmp-string - 265 rewind-stream first-arg-data - 266 stream-to-array first-arg-data, tmp-ah - 267 var first-arg-data-string/eax: (addr array byte) <- lookup *tmp-ah - 268 var out-ah/edi: (addr handle cell) <- copy _out-ah - 269 assign-or-create-global globals, first-arg-data-string, *out-ah, trace - 270 trace-higher trace - 271 return - 272 } - 273 $evaluate:set: { - 274 # trees starting with "set" mutate bindings - 275 var expr/esi: (addr cell) <- copy in - 276 # if its first elem is not "set", break - 277 var first-ah/ecx: (addr handle cell) <- get in, left - 278 var rest-ah/edx: (addr handle cell) <- get in, right - 279 var first/eax: (addr cell) <- lookup *first-ah - 280 var set?/eax: boolean <- symbol-equal? first, "set" - 281 compare set?, 0/false - 282 break-if-= - 283 # - 284 trace-text trace, "eval", "set" - 285 trace-text trace, "eval", "evaluating second arg" - 286 var rest/eax: (addr cell) <- lookup *rest-ah - 287 var first-arg-ah/ecx: (addr handle cell) <- get rest, left - 288 { - 289 var first-arg/eax: (addr cell) <- lookup *first-arg-ah - 290 var first-arg-type/eax: (addr int) <- get first-arg, type - 291 compare *first-arg-type, 2/symbol - 292 break-if-= - 293 error trace, "first arg to set must be a symbol" - 294 trace-higher trace - 295 return - 296 } - 297 rest-ah <- get rest, right - 298 rest <- lookup *rest-ah - 299 var second-arg-ah/edx: (addr handle cell) <- get rest, left - 300 debug-print "P", 4/fg, 0/bg - 301 increment call-number - 302 evaluate second-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 303 debug-print "Q", 4/fg, 0/bg - 304 # errors? skip - 305 { - 306 var error?/eax: boolean <- has-errors? trace - 307 compare error?, 0/false - 308 break-if-= - 309 trace-higher trace - 310 return - 311 } - 312 trace-text trace, "eval", "mutating binding" - 313 var first-arg/eax: (addr cell) <- lookup *first-arg-ah - 314 var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data - 315 var first-arg-data/eax: (addr stream byte) <- lookup *first-arg-data-ah - 316 mutate-binding first-arg-data, _out-ah, env-h, globals, trace - 317 trace-higher trace - 318 return - 319 } - 320 $evaluate:and: { - 321 var expr/esi: (addr cell) <- copy in - 322 # if its first elem is not "and", break - 323 var first-ah/ecx: (addr handle cell) <- get in, left - 324 var rest-ah/edx: (addr handle cell) <- get in, right - 325 var first/eax: (addr cell) <- lookup *first-ah - 326 var and?/eax: boolean <- symbol-equal? first, "and" - 327 compare and?, 0/false - 328 break-if-= - 329 # - 330 trace-text trace, "eval", "and" - 331 trace-text trace, "eval", "evaluating first arg" - 332 var rest/eax: (addr cell) <- lookup *rest-ah - 333 var first-arg-ah/ecx: (addr handle cell) <- get rest, left - 334 debug-print "R2", 4/fg, 0/bg - 335 increment call-number - 336 evaluate first-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 337 debug-print "S2", 4/fg, 0/bg - 338 # errors? skip - 339 { - 340 var error?/eax: boolean <- has-errors? trace - 341 compare error?, 0/false - 342 break-if-= - 343 trace-higher trace - 344 return - 345 } - 346 # if first arg is nil, short-circuit - 347 var out-ah/eax: (addr handle cell) <- copy _out-ah - 348 var out/eax: (addr cell) <- lookup *out-ah - 349 var nil?/eax: boolean <- nil? out - 350 compare nil?, 0/false - 351 { - 352 break-if-= - 353 trace-higher trace - 354 return - 355 } - 356 var rest/eax: (addr cell) <- lookup *rest-ah - 357 rest-ah <- get rest, right - 358 rest <- lookup *rest-ah - 359 var second-ah/eax: (addr handle cell) <- get rest, left - 360 debug-print "T2", 4/fg, 0/bg - 361 increment call-number - 362 evaluate second-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 363 debug-print "U2", 4/fg, 0/bg - 364 trace-higher trace - 365 return - 366 } - 367 $evaluate:or: { - 368 var expr/esi: (addr cell) <- copy in - 369 # if its first elem is not "or", break - 370 var first-ah/ecx: (addr handle cell) <- get in, left - 371 var rest-ah/edx: (addr handle cell) <- get in, right - 372 var first/eax: (addr cell) <- lookup *first-ah - 373 var or?/eax: boolean <- symbol-equal? first, "or" - 374 compare or?, 0/false - 375 break-if-= - 376 # - 377 trace-text trace, "eval", "or" - 378 trace-text trace, "eval", "evaluating first arg" - 379 var rest/eax: (addr cell) <- lookup *rest-ah - 380 var first-arg-ah/ecx: (addr handle cell) <- get rest, left - 381 debug-print "R2", 4/fg, 0/bg - 382 increment call-number - 383 evaluate first-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 384 debug-print "S2", 4/fg, 0/bg - 385 # errors? skip - 386 { - 387 var error?/eax: boolean <- has-errors? trace - 388 compare error?, 0/false - 389 break-if-= - 390 trace-higher trace - 391 return - 392 } - 393 # if first arg is not nil, short-circuit - 394 var out-ah/eax: (addr handle cell) <- copy _out-ah - 395 var out/eax: (addr cell) <- lookup *out-ah - 396 var nil?/eax: boolean <- nil? out - 397 compare nil?, 0/false - 398 { - 399 break-if-!= - 400 trace-higher trace - 401 return - 402 } - 403 var rest/eax: (addr cell) <- lookup *rest-ah - 404 rest-ah <- get rest, right - 405 rest <- lookup *rest-ah - 406 var second-ah/eax: (addr handle cell) <- get rest, left - 407 debug-print "T2", 4/fg, 0/bg - 408 increment call-number - 409 evaluate second-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 410 debug-print "U2", 4/fg, 0/bg - 411 # errors? skip - 412 { - 413 var error?/eax: boolean <- has-errors? trace - 414 compare error?, 0/false - 415 break-if-= - 416 trace-higher trace - 417 return - 418 } - 419 trace-higher trace - 420 return - 421 } - 422 $evaluate:if: { - 423 # trees starting with "if" are conditionals - 424 var expr/esi: (addr cell) <- copy in - 425 # if its first elem is not "if", break - 426 var first-ah/ecx: (addr handle cell) <- get in, left - 427 var rest-ah/edx: (addr handle cell) <- get in, right - 428 var first/eax: (addr cell) <- lookup *first-ah - 429 var if?/eax: boolean <- symbol-equal? first, "if" - 430 compare if?, 0/false - 431 break-if-= - 432 # - 433 trace-text trace, "eval", "if" - 434 trace-text trace, "eval", "evaluating first arg" - 435 var rest/eax: (addr cell) <- lookup *rest-ah - 436 var first-arg-ah/ecx: (addr handle cell) <- get rest, left - 437 var guard-h: (handle cell) - 438 var guard-ah/esi: (addr handle cell) <- address guard-h - 439 debug-print "R", 4/fg, 0/bg - 440 increment call-number - 441 evaluate first-arg-ah, guard-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 442 debug-print "S", 4/fg, 0/bg - 443 # errors? skip - 444 { - 445 var error?/eax: boolean <- has-errors? trace - 446 compare error?, 0/false - 447 break-if-= - 448 trace-higher trace - 449 return - 450 } - 451 rest-ah <- get rest, right - 452 rest <- lookup *rest-ah - 453 var branch-ah/edi: (addr handle cell) <- get rest, left - 454 var guard-a/eax: (addr cell) <- lookup *guard-ah - 455 var skip-to-third-arg?/eax: boolean <- nil? guard-a - 456 compare skip-to-third-arg?, 0/false - 457 { - 458 break-if-= - 459 trace-text trace, "eval", "skipping to third arg" - 460 var rest/eax: (addr cell) <- lookup *rest-ah - 461 rest-ah <- get rest, right - 462 rest <- lookup *rest-ah - 463 branch-ah <- get rest, left - 464 } - 465 debug-print "T", 4/fg, 0/bg - 466 increment call-number - 467 evaluate branch-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 468 debug-print "U", 4/fg, 0/bg - 469 trace-higher trace - 470 return - 471 } - 472 $evaluate:while: { - 473 # trees starting with "while" are loops - 474 var expr/esi: (addr cell) <- copy in - 475 # if its first elem is not "while", break - 476 var first-ah/ecx: (addr handle cell) <- get in, left - 477 var rest-ah/edx: (addr handle cell) <- get in, right - 478 var first/eax: (addr cell) <- lookup *first-ah - 479 var first-type/ecx: (addr int) <- get first, type - 480 compare *first-type, 2/symbol - 481 break-if-!= - 482 var sym-data-ah/eax: (addr handle stream byte) <- get first, text-data - 483 var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah - 484 var while?/eax: boolean <- stream-data-equal? sym-data, "while" - 485 compare while?, 0/false - 486 break-if-= - 487 # - 488 trace-text trace, "eval", "while" - 489 var rest/eax: (addr cell) <- lookup *rest-ah - 490 var first-arg-ah/ecx: (addr handle cell) <- get rest, left - 491 rest-ah <- get rest, right - 492 var guard-h: (handle cell) - 493 var guard-ah/esi: (addr handle cell) <- address guard-h - 494 $evaluate:while:loop-execution: { - 495 { - 496 var error?/eax: boolean <- has-errors? trace - 497 compare error?, 0/false - 498 break-if-!= $evaluate:while:loop-execution - 499 } - 500 trace-text trace, "eval", "loop termination check" - 501 debug-print "V", 4/fg, 0/bg - 502 increment call-number - 503 evaluate first-arg-ah, guard-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 504 debug-print "W", 4/fg, 0/bg - 505 # errors? skip - 506 { - 507 var error?/eax: boolean <- has-errors? trace - 508 compare error?, 0/false - 509 break-if-= - 510 trace-higher trace - 511 return - 512 } - 513 var guard-a/eax: (addr cell) <- lookup *guard-ah - 514 var done?/eax: boolean <- nil? guard-a - 515 compare done?, 0/false - 516 break-if-!= - 517 evaluate-exprs rest-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 518 # errors? skip - 519 { - 520 var error?/eax: boolean <- has-errors? trace - 521 compare error?, 0/false - 522 break-if-= - 523 trace-higher trace - 524 return - 525 } - 526 loop - 527 } - 528 trace-text trace, "eval", "loop terminated" - 529 trace-higher trace - 530 return - 531 } - 532 +-- 15 lines: # trace "evaluate function call elements in " in -------------------------------------------------------------------------------------------------------------------------- - 547 trace-lower trace - 548 var evaluated-list-storage: (handle cell) - 549 var evaluated-list-ah/esi: (addr handle cell) <- address evaluated-list-storage - 550 var curr-out-ah/edx: (addr handle cell) <- copy evaluated-list-ah - 551 var curr/ecx: (addr cell) <- copy in - 552 $evaluate-list:loop: { - 553 allocate-pair curr-out-ah - 554 var nil?/eax: boolean <- nil? curr - 555 compare nil?, 0/false - 556 break-if-!= - 557 # eval left - 558 var curr-out/eax: (addr cell) <- lookup *curr-out-ah - 559 var left-out-ah/edi: (addr handle cell) <- get curr-out, left - 560 var left-ah/esi: (addr handle cell) <- get curr, left - 561 debug-print "A", 4/fg, 0/bg - 562 increment call-number - 563 evaluate left-ah, left-out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number + 5 # side-effects if not in a test (inner-screen-var != 0): + 6 # prints intermediate states of the inner screen to outer screen + 7 # (which may not be the real screen if we're using double-buffering) + 8 # stops if a keypress is encountered + 9 # Inner screen is what Lisp programs modify. Outer screen is shows the program + 10 # and its inner screen to the environment. + 11 fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell), definitions-created: (addr stream int), call-number: (addr int) { + 12 # stack overflow? # disable when enabling Really-debug-print + 13 check-stack + 14 { + 15 var running-tests?/eax: boolean <- running-tests? + 16 compare running-tests?, 0/false + 17 break-if-!= + 18 show-stack-state + 19 } + 20 # show intermediate progress on screen if necessary + 21 # treat input at the real keyboard as interrupting + 22 { + 23 compare inner-screen-var, 0 + 24 break-if-= + 25 var call-number/eax: (addr int) <- copy call-number + 26 compare call-number, 0 + 27 break-if-= + 28 increment *call-number + 29 var tmp/eax: int <- copy *call-number + 30 tmp <- and 0xf/responsiveness=16 # every 16 calls to evaluate + 31 compare tmp, 0 + 32 break-if-!= + 33 var inner-screen-var/eax: (addr handle cell) <- copy inner-screen-var + 34 var inner-screen-var-addr/eax: (addr cell) <- lookup *inner-screen-var + 35 compare inner-screen-var-addr, 0 + 36 break-if-= + 37 var screen-obj-ah/eax: (addr handle screen) <- get inner-screen-var-addr, screen-data + 38 var screen-obj/eax: (addr screen) <- lookup *screen-obj-ah + 39 compare screen-obj, 0 + 40 break-if-= + 41 render-screen 0/screen, screen-obj, 0x58/xmin, 2/ymin + 42 var key/eax: byte <- read-key 0/keyboard + 43 compare key, 0 + 44 break-if-= + 45 error trace, "key pressed; interrupting..." + 46 } + 47 # errors? skip + 48 { + 49 var error?/eax: boolean <- has-errors? trace + 50 compare error?, 0/false + 51 break-if-= + 52 return + 53 } + 54 var in-ah/esi: (addr handle cell) <- copy _in-ah + 55 #? dump-cell in-ah + 56 #? { + 57 #? var foo/eax: byte <- read-key 0/keyboard + 58 #? compare foo, 0 + 59 #? loop-if-= + 60 #? } + 61 +-- 19 lines: # trace "evaluate " in " in environment " env ----------------------------------------------------------------------------------------------------------------------------- + 80 trace-lower trace + 81 var in/eax: (addr cell) <- lookup *in-ah + 82 { + 83 var nil?/eax: boolean <- nil? in + 84 compare nil?, 0/false + 85 break-if-= + 86 # nil is a literal + 87 trace-text trace, "eval", "nil" + 88 copy-object _in-ah, _out-ah + 89 trace-higher trace + 90 return + 91 } + 92 var in-type/ecx: (addr int) <- get in, type + 93 compare *in-type, 1/number + 94 { + 95 break-if-!= + 96 # numbers are literals + 97 trace-text trace, "eval", "number" + 98 copy-object _in-ah, _out-ah + 99 trace-higher trace + 100 return + 101 } + 102 compare *in-type, 3/stream + 103 { + 104 break-if-!= + 105 # streams are literals + 106 trace-text trace, "eval", "stream" + 107 copy-object _in-ah, _out-ah + 108 trace-higher trace + 109 return + 110 } + 111 compare *in-type, 2/symbol + 112 { + 113 break-if-!= + 114 trace-text trace, "eval", "symbol" + 115 debug-print "a", 7/fg, 0/bg + 116 lookup-symbol in, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var + 117 debug-print "z", 7/fg, 0/bg + 118 trace-higher trace + 119 return + 120 } + 121 compare *in-type, 5/screen + 122 { + 123 break-if-!= + 124 trace-text trace, "eval", "screen" + 125 copy-object _in-ah, _out-ah + 126 trace-higher trace + 127 return + 128 } + 129 compare *in-type, 6/keyboard + 130 { + 131 break-if-!= + 132 trace-text trace, "eval", "keyboard" + 133 copy-object _in-ah, _out-ah + 134 trace-higher trace + 135 return + 136 } + 137 # 'in' is a syntax tree + 138 $evaluate:literal-function: { + 139 # trees starting with "litfn" are literals + 140 var expr/esi: (addr cell) <- copy in + 141 var in/edx: (addr cell) <- copy in + 142 var first-ah/ecx: (addr handle cell) <- get in, left + 143 var first/eax: (addr cell) <- lookup *first-ah + 144 var litfn?/eax: boolean <- litfn? first + 145 compare litfn?, 0/false + 146 break-if-= + 147 trace-text trace, "eval", "literal function" + 148 copy-object _in-ah, _out-ah + 149 trace-higher trace + 150 return + 151 } + 152 $evaluate:literal-macro: { + 153 # trees starting with "litmac" are literals + 154 var expr/esi: (addr cell) <- copy in + 155 var in/edx: (addr cell) <- copy in + 156 var first-ah/ecx: (addr handle cell) <- get in, left + 157 var first/eax: (addr cell) <- lookup *first-ah + 158 var litmac?/eax: boolean <- litmac? first + 159 compare litmac?, 0/false + 160 break-if-= + 161 trace-text trace, "eval", "literal macro" + 162 copy-object _in-ah, _out-ah + 163 trace-higher trace + 164 return + 165 } + 166 $evaluate:anonymous-function: { + 167 # trees starting with "fn" are anonymous functions + 168 var expr/esi: (addr cell) <- copy in + 169 var in/edx: (addr cell) <- copy in + 170 var first-ah/ecx: (addr handle cell) <- get in, left + 171 var first/eax: (addr cell) <- lookup *first-ah + 172 var fn?/eax: boolean <- fn? first + 173 compare fn?, 0/false + 174 break-if-= + 175 # turn (fn ...) into (litfn env ...) + 176 trace-text trace, "eval", "anonymous function" + 177 var rest-ah/eax: (addr handle cell) <- get in, right + 178 var tmp: (handle cell) + 179 var tmp-ah/edi: (addr handle cell) <- address tmp + 180 new-pair tmp-ah, env-h, *rest-ah + 181 var litfn: (handle cell) + 182 var litfn-ah/eax: (addr handle cell) <- address litfn + 183 new-symbol litfn-ah, "litfn" + 184 new-pair _out-ah, *litfn-ah, *tmp-ah + 185 trace-higher trace + 186 return + 187 } + 188 # builtins with "special" evaluation rules + 189 $evaluate:quote: { + 190 # trees starting with single quote create literals + 191 var expr/esi: (addr cell) <- copy in + 192 # if its first elem is not "'", break + 193 var first-ah/ecx: (addr handle cell) <- get in, left + 194 var rest-ah/edx: (addr handle cell) <- get in, right + 195 var first/eax: (addr cell) <- lookup *first-ah + 196 var quote?/eax: boolean <- symbol-equal? first, "'" + 197 compare quote?, 0/false + 198 break-if-= + 199 # + 200 trace-text trace, "eval", "quote" + 201 copy-object rest-ah, _out-ah + 202 trace-higher trace + 203 return + 204 } + 205 $evaluate:backquote: { + 206 # trees starting with single backquote create literals + 207 var expr/esi: (addr cell) <- copy in + 208 # if its first elem is not "'", break + 209 var first-ah/ecx: (addr handle cell) <- get in, left + 210 var rest-ah/edx: (addr handle cell) <- get in, right + 211 var first/eax: (addr cell) <- lookup *first-ah + 212 var backquote?/eax: boolean <- symbol-equal? first, "`" + 213 compare backquote?, 0/false + 214 break-if-= + 215 # + 216 trace-text trace, "eval", "backquote" + 217 debug-print "`(", 7/fg, 0/bg + 218 evaluate-backquote rest-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 219 debug-print ")", 7/fg, 0/bg + 220 trace-higher trace + 221 return + 222 } + 223 $evaluate:define: { + 224 # trees starting with "define" define globals + 225 var expr/esi: (addr cell) <- copy in + 226 # if its first elem is not "define", break + 227 var first-ah/ecx: (addr handle cell) <- get in, left + 228 var rest-ah/edx: (addr handle cell) <- get in, right + 229 var first/eax: (addr cell) <- lookup *first-ah + 230 var define?/eax: boolean <- symbol-equal? first, "define" + 231 compare define?, 0/false + 232 break-if-= + 233 # + 234 trace-text trace, "eval", "define" + 235 trace-text trace, "eval", "evaluating second arg" + 236 var rest/eax: (addr cell) <- lookup *rest-ah + 237 var first-arg-ah/ecx: (addr handle cell) <- get rest, left + 238 { + 239 var first-arg/eax: (addr cell) <- lookup *first-arg-ah + 240 var first-arg-type/eax: (addr int) <- get first-arg, type + 241 compare *first-arg-type, 2/symbol + 242 break-if-= + 243 error trace, "first arg to define must be a symbol" + 244 trace-higher trace + 245 return + 246 } + 247 rest-ah <- get rest, right + 248 rest <- lookup *rest-ah + 249 var second-arg-ah/edx: (addr handle cell) <- get rest, left + 250 debug-print "P", 4/fg, 0/bg + 251 evaluate second-arg-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 252 debug-print "Q", 4/fg, 0/bg + 253 # errors? skip + 254 { + 255 var error?/eax: boolean <- has-errors? trace + 256 compare error?, 0/false + 257 break-if-= + 258 trace-higher trace + 259 return + 260 } + 261 trace-text trace, "eval", "saving global binding" + 262 var first-arg/eax: (addr cell) <- lookup *first-arg-ah + 263 var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data + 264 var first-arg-data/eax: (addr stream byte) <- lookup *first-arg-data-ah + 265 var tmp-string: (handle array byte) + 266 var tmp-ah/edx: (addr handle array byte) <- address tmp-string + 267 rewind-stream first-arg-data + 268 stream-to-array first-arg-data, tmp-ah + 269 var first-arg-data-string/eax: (addr array byte) <- lookup *tmp-ah + 270 var out-ah/edi: (addr handle cell) <- copy _out-ah + 271 var defined-index: int + 272 var defined-index-addr/ecx: (addr int) <- address defined-index + 273 assign-or-create-global globals, first-arg-data-string, *out-ah, defined-index-addr, trace + 274 { + 275 compare definitions-created, 0 + 276 break-if-= + 277 write-to-stream definitions-created, defined-index-addr + 278 } + 279 trace-higher trace + 280 return + 281 } + 282 $evaluate:set: { + 283 # trees starting with "set" mutate bindings + 284 var expr/esi: (addr cell) <- copy in + 285 # if its first elem is not "set", break + 286 var first-ah/ecx: (addr handle cell) <- get in, left + 287 var rest-ah/edx: (addr handle cell) <- get in, right + 288 var first/eax: (addr cell) <- lookup *first-ah + 289 var set?/eax: boolean <- symbol-equal? first, "set" + 290 compare set?, 0/false + 291 break-if-= + 292 # + 293 trace-text trace, "eval", "set" + 294 trace-text trace, "eval", "evaluating second arg" + 295 var rest/eax: (addr cell) <- lookup *rest-ah + 296 var first-arg-ah/ecx: (addr handle cell) <- get rest, left + 297 { + 298 var first-arg/eax: (addr cell) <- lookup *first-arg-ah + 299 var first-arg-type/eax: (addr int) <- get first-arg, type + 300 compare *first-arg-type, 2/symbol + 301 break-if-= + 302 error trace, "first arg to set must be a symbol" + 303 trace-higher trace + 304 return + 305 } + 306 rest-ah <- get rest, right + 307 rest <- lookup *rest-ah + 308 var second-arg-ah/edx: (addr handle cell) <- get rest, left + 309 debug-print "P", 4/fg, 0/bg + 310 evaluate second-arg-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 311 debug-print "Q", 4/fg, 0/bg + 312 # errors? skip + 313 { + 314 var error?/eax: boolean <- has-errors? trace + 315 compare error?, 0/false + 316 break-if-= + 317 trace-higher trace + 318 return + 319 } + 320 trace-text trace, "eval", "mutating binding" + 321 var first-arg/eax: (addr cell) <- lookup *first-arg-ah + 322 var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data + 323 var first-arg-data/eax: (addr stream byte) <- lookup *first-arg-data-ah + 324 mutate-binding first-arg-data, _out-ah, env-h, globals, trace + 325 trace-higher trace + 326 return + 327 } + 328 $evaluate:and: { + 329 var expr/esi: (addr cell) <- copy in + 330 # if its first elem is not "and", break + 331 var first-ah/ecx: (addr handle cell) <- get in, left + 332 var rest-ah/edx: (addr handle cell) <- get in, right + 333 var first/eax: (addr cell) <- lookup *first-ah + 334 var and?/eax: boolean <- symbol-equal? first, "and" + 335 compare and?, 0/false + 336 break-if-= + 337 # + 338 trace-text trace, "eval", "and" + 339 trace-text trace, "eval", "evaluating first arg" + 340 var rest/eax: (addr cell) <- lookup *rest-ah + 341 var first-arg-ah/ecx: (addr handle cell) <- get rest, left + 342 debug-print "R2", 4/fg, 0/bg + 343 evaluate first-arg-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 344 debug-print "S2", 4/fg, 0/bg + 345 # errors? skip + 346 { + 347 var error?/eax: boolean <- has-errors? trace + 348 compare error?, 0/false + 349 break-if-= + 350 trace-higher trace + 351 return + 352 } + 353 # if first arg is nil, short-circuit + 354 var out-ah/eax: (addr handle cell) <- copy _out-ah + 355 var out/eax: (addr cell) <- lookup *out-ah + 356 var nil?/eax: boolean <- nil? out + 357 compare nil?, 0/false + 358 { + 359 break-if-= + 360 trace-higher trace + 361 return + 362 } + 363 var rest/eax: (addr cell) <- lookup *rest-ah + 364 rest-ah <- get rest, right + 365 rest <- lookup *rest-ah + 366 var second-ah/eax: (addr handle cell) <- get rest, left + 367 debug-print "T2", 4/fg, 0/bg + 368 evaluate second-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 369 debug-print "U2", 4/fg, 0/bg + 370 trace-higher trace + 371 return + 372 } + 373 $evaluate:or: { + 374 var expr/esi: (addr cell) <- copy in + 375 # if its first elem is not "or", break + 376 var first-ah/ecx: (addr handle cell) <- get in, left + 377 var rest-ah/edx: (addr handle cell) <- get in, right + 378 var first/eax: (addr cell) <- lookup *first-ah + 379 var or?/eax: boolean <- symbol-equal? first, "or" + 380 compare or?, 0/false + 381 break-if-= + 382 # + 383 trace-text trace, "eval", "or" + 384 trace-text trace, "eval", "evaluating first arg" + 385 var rest/eax: (addr cell) <- lookup *rest-ah + 386 var first-arg-ah/ecx: (addr handle cell) <- get rest, left + 387 debug-print "R2", 4/fg, 0/bg + 388 evaluate first-arg-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 389 debug-print "S2", 4/fg, 0/bg + 390 # errors? skip + 391 { + 392 var error?/eax: boolean <- has-errors? trace + 393 compare error?, 0/false + 394 break-if-= + 395 trace-higher trace + 396 return + 397 } + 398 # if first arg is not nil, short-circuit + 399 var out-ah/eax: (addr handle cell) <- copy _out-ah + 400 var out/eax: (addr cell) <- lookup *out-ah + 401 var nil?/eax: boolean <- nil? out + 402 compare nil?, 0/false + 403 { + 404 break-if-!= + 405 trace-higher trace + 406 return + 407 } + 408 var rest/eax: (addr cell) <- lookup *rest-ah + 409 rest-ah <- get rest, right + 410 rest <- lookup *rest-ah + 411 var second-ah/eax: (addr handle cell) <- get rest, left + 412 debug-print "T2", 4/fg, 0/bg + 413 evaluate second-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 414 debug-print "U2", 4/fg, 0/bg + 415 # errors? skip + 416 { + 417 var error?/eax: boolean <- has-errors? trace + 418 compare error?, 0/false + 419 break-if-= + 420 trace-higher trace + 421 return + 422 } + 423 trace-higher trace + 424 return + 425 } + 426 $evaluate:if: { + 427 # trees starting with "if" are conditionals + 428 var expr/esi: (addr cell) <- copy in + 429 # if its first elem is not "if", break + 430 var first-ah/ecx: (addr handle cell) <- get in, left + 431 var rest-ah/edx: (addr handle cell) <- get in, right + 432 var first/eax: (addr cell) <- lookup *first-ah + 433 var if?/eax: boolean <- symbol-equal? first, "if" + 434 compare if?, 0/false + 435 break-if-= + 436 # + 437 trace-text trace, "eval", "if" + 438 trace-text trace, "eval", "evaluating first arg" + 439 var rest/eax: (addr cell) <- lookup *rest-ah + 440 var first-arg-ah/ecx: (addr handle cell) <- get rest, left + 441 var guard-h: (handle cell) + 442 var guard-ah/esi: (addr handle cell) <- address guard-h + 443 debug-print "R", 4/fg, 0/bg + 444 evaluate first-arg-ah, guard-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 445 debug-print "S", 4/fg, 0/bg + 446 # errors? skip + 447 { + 448 var error?/eax: boolean <- has-errors? trace + 449 compare error?, 0/false + 450 break-if-= + 451 trace-higher trace + 452 return + 453 } + 454 rest-ah <- get rest, right + 455 rest <- lookup *rest-ah + 456 var branch-ah/edi: (addr handle cell) <- get rest, left + 457 var guard-a/eax: (addr cell) <- lookup *guard-ah + 458 var skip-to-third-arg?/eax: boolean <- nil? guard-a + 459 compare skip-to-third-arg?, 0/false + 460 { + 461 break-if-= + 462 trace-text trace, "eval", "skipping to third arg" + 463 var rest/eax: (addr cell) <- lookup *rest-ah + 464 rest-ah <- get rest, right + 465 rest <- lookup *rest-ah + 466 branch-ah <- get rest, left + 467 } + 468 debug-print "T", 4/fg, 0/bg + 469 evaluate branch-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 470 debug-print "U", 4/fg, 0/bg + 471 trace-higher trace + 472 return + 473 } + 474 $evaluate:while: { + 475 # trees starting with "while" are loops + 476 var expr/esi: (addr cell) <- copy in + 477 # if its first elem is not "while", break + 478 var first-ah/ecx: (addr handle cell) <- get in, left + 479 var rest-ah/edx: (addr handle cell) <- get in, right + 480 var first/eax: (addr cell) <- lookup *first-ah + 481 var first-type/ecx: (addr int) <- get first, type + 482 compare *first-type, 2/symbol + 483 break-if-!= + 484 var sym-data-ah/eax: (addr handle stream byte) <- get first, text-data + 485 var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah + 486 var while?/eax: boolean <- stream-data-equal? sym-data, "while" + 487 compare while?, 0/false + 488 break-if-= + 489 # + 490 trace-text trace, "eval", "while" + 491 var rest/eax: (addr cell) <- lookup *rest-ah + 492 var first-arg-ah/ecx: (addr handle cell) <- get rest, left + 493 rest-ah <- get rest, right + 494 var guard-h: (handle cell) + 495 var guard-ah/esi: (addr handle cell) <- address guard-h + 496 $evaluate:while:loop-execution: { + 497 { + 498 var error?/eax: boolean <- has-errors? trace + 499 compare error?, 0/false + 500 break-if-!= $evaluate:while:loop-execution + 501 } + 502 trace-text trace, "eval", "loop termination check" + 503 debug-print "V", 4/fg, 0/bg + 504 evaluate first-arg-ah, guard-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 505 debug-print "W", 4/fg, 0/bg + 506 # errors? skip + 507 { + 508 var error?/eax: boolean <- has-errors? trace + 509 compare error?, 0/false + 510 break-if-= + 511 trace-higher trace + 512 return + 513 } + 514 var guard-a/eax: (addr cell) <- lookup *guard-ah + 515 var done?/eax: boolean <- nil? guard-a + 516 compare done?, 0/false + 517 break-if-!= + 518 evaluate-exprs rest-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 519 # errors? skip + 520 { + 521 var error?/eax: boolean <- has-errors? trace + 522 compare error?, 0/false + 523 break-if-= + 524 trace-higher trace + 525 return + 526 } + 527 loop + 528 } + 529 trace-text trace, "eval", "loop terminated" + 530 trace-higher trace + 531 return + 532 } + 533 +-- 15 lines: # trace "evaluate function call elements in " in -------------------------------------------------------------------------------------------------------------------------- + 548 trace-lower trace + 549 var evaluated-list-storage: (handle cell) + 550 var evaluated-list-ah/esi: (addr handle cell) <- address evaluated-list-storage + 551 var curr-out-ah/edx: (addr handle cell) <- copy evaluated-list-ah + 552 var curr/ecx: (addr cell) <- copy in + 553 $evaluate-list:loop: { + 554 allocate-pair curr-out-ah + 555 var nil?/eax: boolean <- nil? curr + 556 compare nil?, 0/false + 557 break-if-!= + 558 # eval left + 559 var curr-out/eax: (addr cell) <- lookup *curr-out-ah + 560 var left-out-ah/edi: (addr handle cell) <- get curr-out, left + 561 var left-ah/esi: (addr handle cell) <- get curr, left + 562 debug-print "A", 4/fg, 0/bg + 563 evaluate left-ah, left-out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number 564 debug-print "B", 4/fg, 0/bg 565 # errors? skip 566 { @@ -618,14 +618,14 @@ if ('onhashchange' in window) { 583 var function-ah/ecx: (addr handle cell) <- get evaluated-list, left 584 var args-ah/edx: (addr handle cell) <- get evaluated-list, right 585 debug-print "C", 4/fg, 0/bg - 586 apply function-ah, args-ah, _out-ah, globals, trace, screen-cell, keyboard-cell, call-number + 586 apply function-ah, args-ah, _out-ah, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number 587 debug-print "Y", 4/fg, 0/bg 588 trace-higher trace 589 +-- 15 lines: # trace "=> " _out-ah ----------------------------------------------------------------------------------------------------------------------------------------------------- 604 debug-print "Z", 4/fg, 0/bg 605 } 606 - 607 fn apply _f-ah: (addr handle cell), args-ah: (addr handle cell), out: (addr handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int { + 607 fn apply _f-ah: (addr handle cell), args-ah: (addr handle cell), out: (addr handle cell), globals: (addr global-table), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell), definitions-created: (addr stream int), call-number: (addr int) { 608 var f-ah/eax: (addr handle cell) <- copy _f-ah 609 var _f/eax: (addr cell) <- lookup *f-ah 610 var f/esi: (addr cell) <- copy _f @@ -634,7 +634,7 @@ if ('onhashchange' in window) { 613 var f-type/eax: (addr int) <- get f, type 614 compare *f-type, 4/primitive-function 615 break-if-!= - 616 apply-primitive f, args-ah, out, globals, trace + 616 apply-primitive f, args-ah, out, globals, trace 617 return 618 } 619 # if it's not a primitive function it must be an anonymous function @@ -646,8 +646,8 @@ if ('onhashchange' in window) { 643 break-if-!= 644 var first-ah/eax: (addr handle cell) <- get f, left 645 var first/eax: (addr cell) <- lookup *first-ah - 646 var litfn?/eax: boolean <- litfn? first - 647 compare litfn?, 0/false + 646 var litfn?/eax: boolean <- litfn? first + 647 compare litfn?, 0/false 648 break-if-= 649 var rest-ah/esi: (addr handle cell) <- get f, right 650 var rest/eax: (addr cell) <- lookup *rest-ah @@ -657,7 +657,7 @@ if ('onhashchange' in window) { 654 var params-ah/ecx: (addr handle cell) <- get rest, left 655 var body-ah/eax: (addr handle cell) <- get rest, right 656 debug-print "D", 7/fg, 0/bg - 657 apply-function params-ah, args-ah, body-ah, out, *callee-env-ah, globals, trace, screen-cell, keyboard-cell, call-number + 657 apply-function params-ah, args-ah, body-ah, out, *callee-env-ah, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number 658 debug-print "Y", 7/fg, 0/bg 659 trace-higher trace 660 return @@ -665,11 +665,11 @@ if ('onhashchange' in window) { 662 error trace, "unknown function" 663 } 664 - 665 fn apply-function params-ah: (addr handle cell), args-ah: (addr handle cell), body-ah: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int { + 665 fn apply-function params-ah: (addr handle cell), args-ah: (addr handle cell), body-ah: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell), definitions-created: (addr stream int), call-number: (addr int) { 666 # push bindings for params to env 667 var new-env-h: (handle cell) 668 var new-env-ah/esi: (addr handle cell) <- address new-env-h - 669 push-bindings params-ah, args-ah, env-h, new-env-ah, trace + 669 push-bindings params-ah, args-ah, env-h, new-env-ah, trace 670 # errors? skip 671 { 672 var error?/eax: boolean <- has-errors? trace @@ -678,10 +678,10 @@ if ('onhashchange' in window) { 675 return 676 } 677 # - 678 evaluate-exprs body-ah, out, new-env-h, globals, trace, screen-cell, keyboard-cell, call-number + 678 evaluate-exprs body-ah, out, new-env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number 679 } 680 - 681 fn evaluate-exprs _exprs-ah: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int { + 681 fn evaluate-exprs _exprs-ah: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell), definitions-created: (addr stream int), call-number: (addr int) { 682 # eval all exprs, writing result to `out` each time 683 var exprs-ah/ecx: (addr handle cell) <- copy _exprs-ah 684 $evaluate-exprs:loop: { @@ -696,1168 +696,1165 @@ if ('onhashchange' in window) { 693 { 694 var curr-ah/eax: (addr handle cell) <- get exprs, left 695 debug-print "E", 7/fg, 0/bg - 696 increment call-number - 697 evaluate curr-ah, out, env-h, globals, trace, screen-cell, keyboard-cell, call-number - 698 debug-print "X", 7/fg, 0/bg - 699 # errors? skip - 700 { - 701 var error?/eax: boolean <- has-errors? trace - 702 compare error?, 0/false - 703 break-if-= - 704 return - 705 } - 706 } - 707 # - 708 exprs-ah <- get exprs, right - 709 loop - 710 } - 711 # `out` contains result of evaluating final expression - 712 } - 713 - 714 # Bind params to corresponding args and add the bindings to old-env. Return - 715 # the result in env-ah. - 716 # - 717 # We never modify old-env, but we point to it. This way other parts of the - 718 # interpreter can continue using old-env, and everything works harmoniously - 719 # even though no cells are copied around. - 720 # - 721 # env should always be a DAG (ignoring internals of values). It doesn't have - 722 # to be a tree (some values may be shared), but there are also no cycles. - 723 # - 724 # Learn more: https://en.wikipedia.org/wiki/Persistent_data_structure - 725 fn push-bindings _params-ah: (addr handle cell), _args-ah: (addr handle cell), old-env-h: (handle cell), env-ah: (addr handle cell), trace: (addr trace) { - 726 var params-ah/edx: (addr handle cell) <- copy _params-ah - 727 var args-ah/ebx: (addr handle cell) <- copy _args-ah - 728 var _params/eax: (addr cell) <- lookup *params-ah - 729 var params/esi: (addr cell) <- copy _params - 730 { - 731 var params-nil?/eax: boolean <- nil? params - 732 compare params-nil?, 0/false - 733 break-if-= - 734 # nil is a literal - 735 trace-text trace, "eval", "done with push-bindings" - 736 copy-handle old-env-h, env-ah - 737 return - 738 } - 739 # Params can only be symbols or pairs. Args can be anything. - 740 +-- 22 lines: # trace "pushing bindings from " params " to " args ----------------------------------------------------------------------------------------------------------------------- - 762 trace-lower trace - 763 var params-type/eax: (addr int) <- get params, type - 764 compare *params-type, 2/symbol - 765 { - 766 break-if-!= - 767 trace-text trace, "eval", "symbol; binding to all remaining args" - 768 # create a new binding - 769 var new-binding-storage: (handle cell) - 770 var new-binding-ah/eax: (addr handle cell) <- address new-binding-storage - 771 new-pair new-binding-ah, *params-ah, *args-ah - 772 # push it to env - 773 new-pair env-ah, *new-binding-ah, old-env-h - 774 trace-higher trace - 775 return - 776 } - 777 compare *params-type, 0/pair - 778 { - 779 break-if-= - 780 error trace, "cannot bind a non-symbol" - 781 trace-higher trace - 782 return - 783 } - 784 var _args/eax: (addr cell) <- lookup *args-ah - 785 var args/edi: (addr cell) <- copy _args - 786 # params is now a pair, so args must be also - 787 { - 788 var args-nil?/eax: boolean <- nil? args - 789 compare args-nil?, 0/false - 790 break-if-= - 791 error trace, "not enough args to bind" - 792 return - 793 } - 794 var args-type/eax: (addr int) <- get args, type - 795 compare *args-type, 0/pair - 796 { - 797 break-if-= - 798 error trace, "args not in a proper list" - 799 trace-higher trace - 800 return - 801 } - 802 var intermediate-env-storage: (handle cell) - 803 var intermediate-env-ah/edx: (addr handle cell) <- address intermediate-env-storage - 804 var first-param-ah/eax: (addr handle cell) <- get params, left - 805 var first-arg-ah/ecx: (addr handle cell) <- get args, left - 806 push-bindings first-param-ah, first-arg-ah, old-env-h, intermediate-env-ah, trace - 807 # errors? skip - 808 { - 809 var error?/eax: boolean <- has-errors? trace - 810 compare error?, 0/false - 811 break-if-= - 812 trace-higher trace - 813 return - 814 } - 815 var remaining-params-ah/eax: (addr handle cell) <- get params, right - 816 var remaining-args-ah/ecx: (addr handle cell) <- get args, right - 817 push-bindings remaining-params-ah, remaining-args-ah, *intermediate-env-ah, env-ah, trace - 818 trace-higher trace - 819 } - 820 - 821 fn lookup-symbol sym: (addr cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) { - 822 # trace sym - 823 { - 824 var should-trace?/eax: boolean <- should-trace? trace - 825 compare should-trace?, 0/false - 826 break-if-= - 827 var stream-storage: (stream byte 0x800) # pessimistically sized just for the large alist loaded from disk in `main` - 828 var stream/ecx: (addr stream byte) <- address stream-storage - 829 write stream, "look up " - 830 var sym2/eax: (addr cell) <- copy sym - 831 var sym-data-ah/eax: (addr handle stream byte) <- get sym2, text-data - 832 var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah - 833 rewind-stream sym-data - 834 write-stream stream, sym-data - 835 write stream, " in " - 836 var env-ah/eax: (addr handle cell) <- address env-h - 837 var nested-trace-storage: trace - 838 var nested-trace/edi: (addr trace) <- address nested-trace-storage - 839 initialize-trace nested-trace, 1/only-errors, 0x10/capacity, 0/visible - 840 print-cell env-ah, stream, nested-trace - 841 trace trace, "eval", stream - 842 } - 843 trace-lower trace - 844 var _env/eax: (addr cell) <- lookup env-h - 845 var env/ebx: (addr cell) <- copy _env - 846 # if env is not a list, error - 847 { - 848 var env-type/ecx: (addr int) <- get env, type - 849 compare *env-type, 0/pair - 850 break-if-= - 851 error trace, "eval found a non-list environment" - 852 trace-higher trace - 853 return - 854 } - 855 # if env is nil, look up in globals - 856 { - 857 var env-nil?/eax: boolean <- nil? env - 858 compare env-nil?, 0/false - 859 break-if-= - 860 debug-print "b", 7/fg, 0/bg - 861 lookup-symbol-in-globals sym, out, globals, trace, screen-cell, keyboard-cell - 862 debug-print "x", 7/fg, 0/bg - 863 trace-higher trace - 864 +-- 19 lines: # trace "=> " out " (global)" --------------------------------------------------------------------------------------------------------------------------------------------- - 883 debug-print "y", 7/fg, 0/bg - 884 return - 885 } - 886 # check car - 887 var env-head-storage: (handle cell) - 888 var env-head-ah/eax: (addr handle cell) <- address env-head-storage - 889 car env, env-head-ah, trace - 890 var _env-head/eax: (addr cell) <- lookup *env-head-ah - 891 var env-head/ecx: (addr cell) <- copy _env-head - 892 # if car is not a list, abort - 893 { - 894 var env-head-type/eax: (addr int) <- get env-head, type - 895 compare *env-head-type, 0/pair - 896 break-if-= - 897 error trace, "environment is not a list of (key . value) pairs" - 898 trace-higher trace - 899 return - 900 } - 901 # check key - 902 var curr-key-storage: (handle cell) - 903 var curr-key-ah/eax: (addr handle cell) <- address curr-key-storage - 904 car env-head, curr-key-ah, trace - 905 var curr-key/eax: (addr cell) <- lookup *curr-key-ah - 906 # if key is not a symbol, abort - 907 { - 908 var curr-key-type/eax: (addr int) <- get curr-key, type - 909 compare *curr-key-type, 2/symbol - 910 break-if-= - 911 error trace, "environment contains a binding for a non-symbol" - 912 trace-higher trace - 913 return - 914 } - 915 # if key matches sym, return val - 916 var match?/eax: boolean <- cell-isomorphic? curr-key, sym, trace - 917 compare match?, 0/false - 918 { - 919 break-if-= - 920 cdr env-head, out, trace - 921 +-- 19 lines: # trace "=> " out " (match)" ---------------------------------------------------------------------------------------------------------------------------------------------- - 940 trace-higher trace - 941 return - 942 } - 943 # otherwise recurse - 944 var env-tail-storage: (handle cell) - 945 var env-tail-ah/eax: (addr handle cell) <- address env-tail-storage - 946 cdr env, env-tail-ah, trace - 947 lookup-symbol sym, out, *env-tail-ah, globals, trace, screen-cell, keyboard-cell - 948 trace-higher trace - 949 +-- 19 lines: # trace "=> " out " (recurse)" -------------------------------------------------------------------------------------------------------------------------------------------- - 968 } - 969 - 970 fn test-lookup-symbol-in-env { - 971 # tmp = (a . 3) - 972 var val-storage: (handle cell) - 973 var val-ah/ecx: (addr handle cell) <- address val-storage - 974 new-integer val-ah, 3 - 975 var key-storage: (handle cell) - 976 var key-ah/edx: (addr handle cell) <- address key-storage - 977 new-symbol key-ah, "a" - 978 var env-storage: (handle cell) - 979 var env-ah/ebx: (addr handle cell) <- address env-storage - 980 new-pair env-ah, *key-ah, *val-ah - 981 # env = ((a . 3)) - 982 var nil-storage: (handle cell) - 983 var nil-ah/ecx: (addr handle cell) <- address nil-storage - 984 allocate-pair nil-ah - 985 new-pair env-ah, *env-ah, *nil-ah - 986 # lookup sym(a) in env tmp - 987 var tmp-storage: (handle cell) - 988 var tmp-ah/edx: (addr handle cell) <- address tmp-storage - 989 new-symbol tmp-ah, "a" - 990 var in/eax: (addr cell) <- lookup *tmp-ah - 991 var trace-storage: trace - 992 var trace/edi: (addr trace) <- address trace-storage - 993 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible - 994 lookup-symbol in, tmp-ah, *env-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard - 995 var result/eax: (addr cell) <- lookup *tmp-ah - 996 var result-type/edx: (addr int) <- get result, type - 997 check-ints-equal *result-type, 1/number, "F - test-lookup-symbol-in-env/0" - 998 var result-value-addr/eax: (addr float) <- get result, number-data - 999 var result-value/eax: int <- convert *result-value-addr -1000 check-ints-equal result-value, 3, "F - test-lookup-symbol-in-env/1" -1001 } -1002 -1003 fn test-lookup-symbol-in-globals { -1004 var globals-storage: global-table -1005 var globals/edi: (addr global-table) <- address globals-storage -1006 initialize-globals globals -1007 # env = nil -1008 var nil-storage: (handle cell) -1009 var nil-ah/ecx: (addr handle cell) <- address nil-storage -1010 allocate-pair nil-ah -1011 # lookup sym(a), env -1012 var tmp-storage: (handle cell) -1013 var tmp-ah/ebx: (addr handle cell) <- address tmp-storage -1014 new-symbol tmp-ah, "+" -1015 var in/eax: (addr cell) <- lookup *tmp-ah -1016 var trace-storage: trace -1017 var trace/esi: (addr trace) <- address trace-storage -1018 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1019 lookup-symbol in, tmp-ah, *nil-ah, globals, trace, 0/no-screen, 0/no-keyboard -1020 var result/eax: (addr cell) <- lookup *tmp-ah -1021 var result-type/edx: (addr int) <- get result, type -1022 check-ints-equal *result-type, 4/primitive-function, "F - test-lookup-symbol-in-globals/0" -1023 var result-value/eax: (addr int) <- get result, index-data -1024 check-ints-equal *result-value, 1/add, "F - test-lookup-symbol-in-globals/1" -1025 } -1026 -1027 fn mutate-binding name: (addr stream byte), val: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace) { -1028 # trace name -1029 { -1030 var should-trace?/eax: boolean <- should-trace? trace -1031 compare should-trace?, 0/false -1032 break-if-= -1033 var stream-storage: (stream byte 0x800) # pessimistically sized just for the large alist loaded from disk in `main` -1034 var stream/ecx: (addr stream byte) <- address stream-storage -1035 write stream, "bind " -1036 rewind-stream name -1037 write-stream stream, name -1038 write stream, " to " -1039 var nested-trace-storage: trace -1040 var nested-trace/edi: (addr trace) <- address nested-trace-storage -1041 initialize-trace nested-trace, 1/only-errors, 0x10/capacity, 0/visible -1042 print-cell val, stream, nested-trace -1043 write stream, " in " -1044 var env-ah/eax: (addr handle cell) <- address env-h -1045 clear-trace nested-trace -1046 print-cell env-ah, stream, nested-trace -1047 trace trace, "eval", stream -1048 } -1049 trace-lower trace -1050 var _env/eax: (addr cell) <- lookup env-h -1051 var env/ebx: (addr cell) <- copy _env -1052 # if env is not a list, abort -1053 { -1054 var env-type/ecx: (addr int) <- get env, type -1055 compare *env-type, 0/pair -1056 break-if-= -1057 error trace, "eval found a non-list environment" -1058 trace-higher trace -1059 return -1060 } -1061 # if env is nil, look in globals -1062 { -1063 var env-nil?/eax: boolean <- nil? env -1064 compare env-nil?, 0/false -1065 break-if-= -1066 debug-print "b", 3/fg, 0/bg -1067 mutate-binding-in-globals name, val, globals, trace -1068 debug-print "x", 3/fg, 0/bg -1069 trace-higher trace -1070 +-- 19 lines: # trace "=> " val " (global)" --------------------------------------------------------------------------------------------------------------------------------------------- -1089 debug-print "y", 3/fg, 0/bg -1090 return -1091 } -1092 # check car -1093 var env-head-storage: (handle cell) -1094 var env-head-ah/eax: (addr handle cell) <- address env-head-storage -1095 car env, env-head-ah, trace -1096 var _env-head/eax: (addr cell) <- lookup *env-head-ah -1097 var env-head/ecx: (addr cell) <- copy _env-head -1098 # if car is not a list, abort -1099 { -1100 var env-head-type/eax: (addr int) <- get env-head, type -1101 compare *env-head-type, 0/pair -1102 break-if-= -1103 error trace, "environment is not a list of (key . value) pairs" -1104 trace-higher trace -1105 return -1106 } -1107 # check key -1108 var curr-key-storage: (handle cell) -1109 var curr-key-ah/eax: (addr handle cell) <- address curr-key-storage -1110 car env-head, curr-key-ah, trace -1111 var curr-key/eax: (addr cell) <- lookup *curr-key-ah -1112 # if key is not a symbol, abort -1113 { -1114 var curr-key-type/eax: (addr int) <- get curr-key, type -1115 compare *curr-key-type, 2/symbol -1116 break-if-= -1117 error trace, "environment contains a binding for a non-symbol" -1118 trace-higher trace -1119 return -1120 } -1121 # if key matches name, return val -1122 var curr-key-data-ah/eax: (addr handle stream byte) <- get curr-key, text-data -1123 var curr-key-data/eax: (addr stream byte) <- lookup *curr-key-data-ah -1124 var match?/eax: boolean <- streams-data-equal? curr-key-data, name -1125 compare match?, 0/false -1126 { -1127 break-if-= -1128 var dest/eax: (addr handle cell) <- get env-head, right -1129 copy-object val, dest -1130 trace-text trace, "eval", "=> done" -1131 trace-higher trace -1132 return -1133 } -1134 # otherwise recurse -1135 var env-tail-storage: (handle cell) -1136 var env-tail-ah/eax: (addr handle cell) <- address env-tail-storage -1137 cdr env, env-tail-ah, trace -1138 mutate-binding name, val, *env-tail-ah, globals, trace -1139 trace-higher trace -1140 } -1141 -1142 fn car _in: (addr cell), out: (addr handle cell), trace: (addr trace) { -1143 trace-text trace, "eval", "car" -1144 trace-lower trace -1145 var in/eax: (addr cell) <- copy _in -1146 # if in is not a list, abort -1147 { -1148 var in-type/ecx: (addr int) <- get in, type -1149 compare *in-type, 0/pair -1150 break-if-= -1151 error trace, "car on a non-list" -1152 trace-higher trace -1153 return -1154 } -1155 # if in is nil, abort -1156 { -1157 var in-nil?/eax: boolean <- nil? in -1158 compare in-nil?, 0/false -1159 break-if-= -1160 error trace, "car on nil" -1161 trace-higher trace -1162 return -1163 } -1164 var in-left/eax: (addr handle cell) <- get in, left -1165 copy-object in-left, out -1166 trace-higher trace -1167 return -1168 } -1169 -1170 fn cdr _in: (addr cell), out: (addr handle cell), trace: (addr trace) { -1171 trace-text trace, "eval", "cdr" -1172 trace-lower trace -1173 var in/eax: (addr cell) <- copy _in -1174 # if in is not a list, abort -1175 { -1176 var in-type/ecx: (addr int) <- get in, type -1177 compare *in-type, 0/pair -1178 break-if-= -1179 error trace, "car on a non-list" -1180 trace-higher trace -1181 return -1182 } -1183 # if in is nil, abort -1184 { -1185 var in-nil?/eax: boolean <- nil? in -1186 compare in-nil?, 0/false -1187 break-if-= -1188 error trace, "car on nil" -1189 trace-higher trace -1190 return -1191 } -1192 var in-right/eax: (addr handle cell) <- get in, right -1193 copy-object in-right, out -1194 trace-higher trace -1195 return -1196 } -1197 -1198 fn cell-isomorphic? _a: (addr cell), _b: (addr cell), trace: (addr trace) -> _/eax: boolean { -1199 trace-text trace, "eval", "cell-isomorphic?" -1200 trace-lower trace -1201 var a/esi: (addr cell) <- copy _a -1202 var b/edi: (addr cell) <- copy _b -1203 # if types don't match, return false -1204 var a-type-addr/eax: (addr int) <- get a, type -1205 var b-type-addr/ecx: (addr int) <- get b, type -1206 var b-type/ecx: int <- copy *b-type-addr -1207 compare b-type, *a-type-addr -1208 { -1209 break-if-= -1210 trace-higher trace -1211 trace-text trace, "eval", "=> false (type)" -1212 return 0/false -1213 } -1214 # if types are number, compare number-data -1215 # TODO: exactly comparing floats is a bad idea -1216 compare b-type, 1/number -1217 { -1218 break-if-!= -1219 var a-val-addr/eax: (addr float) <- get a, number-data -1220 var b-val-addr/ecx: (addr float) <- get b, number-data -1221 var a-val/xmm0: float <- copy *a-val-addr -1222 compare a-val, *b-val-addr -1223 { -1224 break-if-= -1225 trace-higher trace -1226 trace-text trace, "eval", "=> false (numbers)" -1227 return 0/false -1228 } -1229 trace-higher trace -1230 trace-text trace, "eval", "=> true (numbers)" -1231 return 1/true -1232 } -1233 $cell-isomorphic?:text-data: { -1234 { -1235 compare b-type, 2/symbol -1236 break-if-= -1237 compare b-type, 3/stream -1238 break-if-= -1239 break $cell-isomorphic?:text-data -1240 } -1241 var b-val-ah/eax: (addr handle stream byte) <- get b, text-data -1242 var _b-val/eax: (addr stream byte) <- lookup *b-val-ah -1243 var b-val/ecx: (addr stream byte) <- copy _b-val -1244 var a-val-ah/eax: (addr handle stream byte) <- get a, text-data -1245 var a-val/eax: (addr stream byte) <- lookup *a-val-ah -1246 var tmp-array: (handle array byte) -1247 var tmp-ah/edx: (addr handle array byte) <- address tmp-array -1248 rewind-stream a-val -1249 stream-to-array a-val, tmp-ah -1250 var tmp/eax: (addr array byte) <- lookup *tmp-ah -1251 var match?/eax: boolean <- stream-data-equal? b-val, tmp -1252 trace-higher trace -1253 { -1254 compare match?, 0/false -1255 break-if-= -1256 trace-text trace, "eval", "=> true (symbols)" -1257 } -1258 { -1259 compare match?, 0/false -1260 break-if-!= -1261 trace-text trace, "eval", "=> false (symbols)" -1262 } -1263 return match? -1264 } -1265 # if objects are primitive functions, compare index-data -1266 compare b-type, 4/primitive -1267 { -1268 break-if-!= -1269 var a-val-addr/eax: (addr int) <- get a, index-data -1270 var b-val-addr/ecx: (addr int) <- get b, index-data -1271 var a-val/eax: int <- copy *a-val-addr -1272 compare a-val, *b-val-addr -1273 { -1274 break-if-= -1275 trace-higher trace -1276 trace-text trace, "eval", "=> false (primitives)" -1277 return 0/false -1278 } -1279 trace-higher trace -1280 trace-text trace, "eval", "=> true (primitives)" -1281 return 1/true -1282 } -1283 # if objects are screens, check if they're the same object -1284 compare b-type, 5/screen -1285 { -1286 break-if-!= -1287 var a-val-addr/eax: (addr handle screen) <- get a, screen-data -1288 var b-val-addr/ecx: (addr handle screen) <- get b, screen-data -1289 var result/eax: boolean <- handle-equal? *a-val-addr, *b-val-addr -1290 compare result, 0/false -1291 return result -1292 } -1293 # if objects are keyboards, check if they have the same contents -1294 compare b-type, 6/keyboard -1295 { -1296 break-if-!= -1297 var a-val-addr/ecx: (addr handle gap-buffer) <- get a, keyboard-data -1298 var _a/eax: (addr gap-buffer) <- lookup *a-val-addr -1299 var a/ecx: (addr gap-buffer) <- copy _a -1300 var b-val-addr/eax: (addr handle gap-buffer) <- get b, keyboard-data -1301 var b/eax: (addr gap-buffer) <- lookup *b-val-addr -1302 var result/eax: boolean <- gap-buffers-equal? a, b -1303 return result -1304 } -1305 # if a is nil, b should be nil -1306 { -1307 # (assumes nil? returns 0 or 1) -1308 var _b-nil?/eax: boolean <- nil? b -1309 var b-nil?/ecx: boolean <- copy _b-nil? -1310 var a-nil?/eax: boolean <- nil? a -1311 # a == nil and b == nil => return true -1312 { -1313 compare a-nil?, 0/false -1314 break-if-= -1315 compare b-nil?, 0/false -1316 break-if-= -1317 trace-higher trace -1318 trace-text trace, "eval", "=> true (nils)" -1319 return 1/true -1320 } -1321 # a == nil => return false -1322 { -1323 compare a-nil?, 0/false -1324 break-if-= -1325 trace-higher trace -1326 trace-text trace, "eval", "=> false (b != nil)" -1327 return 0/false -1328 } -1329 # b == nil => return false -1330 { -1331 compare b-nil?, 0/false -1332 break-if-= -1333 trace-higher trace -1334 trace-text trace, "eval", "=> false (a != nil)" -1335 return 0/false -1336 } -1337 } -1338 # a and b are pairs -1339 var a-tmp-storage: (handle cell) -1340 var a-tmp-ah/edx: (addr handle cell) <- address a-tmp-storage -1341 var b-tmp-storage: (handle cell) -1342 var b-tmp-ah/ebx: (addr handle cell) <- address b-tmp-storage -1343 # if cars aren't equal, return false -1344 car a, a-tmp-ah, trace -1345 car b, b-tmp-ah, trace -1346 { -1347 var _a-tmp/eax: (addr cell) <- lookup *a-tmp-ah -1348 var a-tmp/ecx: (addr cell) <- copy _a-tmp -1349 var b-tmp/eax: (addr cell) <- lookup *b-tmp-ah -1350 var result/eax: boolean <- cell-isomorphic? a-tmp, b-tmp, trace -1351 compare result, 0/false -1352 break-if-!= -1353 trace-higher trace -1354 trace-text trace, "eval", "=> false (car mismatch)" -1355 return 0/false -1356 } -1357 # recurse on cdrs -1358 cdr a, a-tmp-ah, trace -1359 cdr b, b-tmp-ah, trace -1360 var _a-tmp/eax: (addr cell) <- lookup *a-tmp-ah -1361 var a-tmp/ecx: (addr cell) <- copy _a-tmp -1362 var b-tmp/eax: (addr cell) <- lookup *b-tmp-ah -1363 var result/eax: boolean <- cell-isomorphic? a-tmp, b-tmp, trace -1364 trace-higher trace -1365 return result -1366 } -1367 -1368 fn fn? _x: (addr cell) -> _/eax: boolean { -1369 var x/esi: (addr cell) <- copy _x -1370 var type/eax: (addr int) <- get x, type -1371 compare *type, 2/symbol -1372 { -1373 break-if-= -1374 return 0/false -1375 } -1376 var contents-ah/eax: (addr handle stream byte) <- get x, text-data -1377 var contents/eax: (addr stream byte) <- lookup *contents-ah -1378 var result/eax: boolean <- stream-data-equal? contents, "fn" -1379 return result -1380 } -1381 -1382 fn litfn? _x: (addr cell) -> _/eax: boolean { -1383 var x/esi: (addr cell) <- copy _x -1384 var type/eax: (addr int) <- get x, type -1385 compare *type, 2/symbol -1386 { -1387 break-if-= -1388 return 0/false -1389 } -1390 var contents-ah/eax: (addr handle stream byte) <- get x, text-data -1391 var contents/eax: (addr stream byte) <- lookup *contents-ah -1392 var result/eax: boolean <- stream-data-equal? contents, "litfn" -1393 return result -1394 } -1395 -1396 fn litmac? _x: (addr cell) -> _/eax: boolean { -1397 var x/esi: (addr cell) <- copy _x -1398 var type/eax: (addr int) <- get x, type -1399 compare *type, 2/symbol -1400 { -1401 break-if-= -1402 return 0/false -1403 } -1404 var contents-ah/eax: (addr handle stream byte) <- get x, text-data -1405 var contents/eax: (addr stream byte) <- lookup *contents-ah -1406 var result/eax: boolean <- stream-data-equal? contents, "litmac" -1407 return result -1408 } -1409 -1410 fn test-evaluate-is-well-behaved { -1411 var t-storage: trace -1412 var t/esi: (addr trace) <- address t-storage -1413 initialize-trace t, 0x100/max-depth, 0x10/capacity, 0/visible # we don't use trace UI -1414 # env = nil -1415 var env-storage: (handle cell) -1416 var env-ah/ecx: (addr handle cell) <- address env-storage -1417 allocate-pair env-ah -1418 # eval sym(a), nil env -1419 var tmp-storage: (handle cell) -1420 var tmp-ah/edx: (addr handle cell) <- address tmp-storage -1421 new-symbol tmp-ah, "a" -1422 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, t, 0/no-screen, 0/no-keyboard, 0/call-number -1423 # doesn't die -1424 check-trace-contains t, "error", "unbound symbol: a", "F - test-evaluate-is-well-behaved" -1425 } -1426 -1427 fn test-evaluate-number { -1428 # env = nil -1429 var env-storage: (handle cell) -1430 var env-ah/ecx: (addr handle cell) <- address env-storage -1431 allocate-pair env-ah -1432 # tmp = 3 -1433 var tmp-storage: (handle cell) -1434 var tmp-ah/edx: (addr handle cell) <- address tmp-storage -1435 new-integer tmp-ah, 3 -1436 var trace-storage: trace -1437 var trace/edi: (addr trace) <- address trace-storage -1438 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1439 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number -1440 # -1441 var result/eax: (addr cell) <- lookup *tmp-ah -1442 var result-type/edx: (addr int) <- get result, type -1443 check-ints-equal *result-type, 1/number, "F - test-evaluate-number/0" -1444 var result-value-addr/eax: (addr float) <- get result, number-data -1445 var result-value/eax: int <- convert *result-value-addr -1446 check-ints-equal result-value, 3, "F - test-evaluate-number/1" -1447 } -1448 -1449 fn test-evaluate-symbol { -1450 # tmp = (a . 3) -1451 var val-storage: (handle cell) -1452 var val-ah/ecx: (addr handle cell) <- address val-storage -1453 new-integer val-ah, 3 -1454 var key-storage: (handle cell) -1455 var key-ah/edx: (addr handle cell) <- address key-storage -1456 new-symbol key-ah, "a" -1457 var env-storage: (handle cell) -1458 var env-ah/ebx: (addr handle cell) <- address env-storage -1459 new-pair env-ah, *key-ah, *val-ah -1460 # env = ((a . 3)) -1461 var nil-storage: (handle cell) -1462 var nil-ah/ecx: (addr handle cell) <- address nil-storage -1463 allocate-pair nil-ah -1464 new-pair env-ah, *env-ah, *nil-ah -1465 # eval sym(a), env -1466 var tmp-storage: (handle cell) -1467 var tmp-ah/edx: (addr handle cell) <- address tmp-storage -1468 new-symbol tmp-ah, "a" -1469 var trace-storage: trace -1470 var trace/edi: (addr trace) <- address trace-storage -1471 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1472 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number -1473 var result/eax: (addr cell) <- lookup *tmp-ah -1474 var result-type/edx: (addr int) <- get result, type -1475 check-ints-equal *result-type, 1/number, "F - test-evaluate-symbol/0" -1476 var result-value-addr/eax: (addr float) <- get result, number-data -1477 var result-value/eax: int <- convert *result-value-addr -1478 check-ints-equal result-value, 3, "F - test-evaluate-symbol/1" -1479 } -1480 -1481 fn test-evaluate-quote { -1482 # env = nil -1483 var nil-storage: (handle cell) -1484 var nil-ah/ecx: (addr handle cell) <- address nil-storage -1485 allocate-pair nil-ah -1486 # eval `a, env -1487 var tmp-storage: (handle cell) -1488 var tmp-ah/edx: (addr handle cell) <- address tmp-storage -1489 new-symbol tmp-ah, "'" -1490 var tmp2-storage: (handle cell) -1491 var tmp2-ah/ebx: (addr handle cell) <- address tmp2-storage -1492 new-symbol tmp2-ah, "a" -1493 new-pair tmp-ah, *tmp-ah, *tmp2-ah -1494 var trace-storage: trace -1495 var trace/edi: (addr trace) <- address trace-storage -1496 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1497 evaluate tmp-ah, tmp-ah, *nil-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number -1498 var result/eax: (addr cell) <- lookup *tmp-ah -1499 var result-type/edx: (addr int) <- get result, type -1500 check-ints-equal *result-type, 2/symbol, "F - test-evaluate-quote/0" -1501 var sym?/eax: boolean <- symbol-equal? result, "a" -1502 check sym?, "F - test-evaluate-quote/1" -1503 } -1504 -1505 fn test-evaluate-primitive-function { -1506 var globals-storage: global-table -1507 var globals/edi: (addr global-table) <- address globals-storage -1508 initialize-globals globals -1509 var nil-storage: (handle cell) -1510 var nil-ah/ecx: (addr handle cell) <- address nil-storage -1511 allocate-pair nil-ah -1512 var add-storage: (handle cell) -1513 var add-ah/ebx: (addr handle cell) <- address add-storage -1514 new-symbol add-ah, "+" -1515 # eval +, nil env -1516 var tmp-storage: (handle cell) -1517 var tmp-ah/esi: (addr handle cell) <- address tmp-storage -1518 var trace-storage: trace -1519 var trace/edx: (addr trace) <- address trace-storage -1520 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1521 evaluate add-ah, tmp-ah, *nil-ah, globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number -1522 # -1523 var result/eax: (addr cell) <- lookup *tmp-ah -1524 var result-type/edx: (addr int) <- get result, type -1525 check-ints-equal *result-type, 4/primitive-function, "F - test-evaluate-primitive-function/0" -1526 var result-value/eax: (addr int) <- get result, index-data -1527 check-ints-equal *result-value, 1/add, "F - test-evaluate-primitive-function/1" -1528 } -1529 -1530 fn test-evaluate-primitive-function-call { -1531 var t-storage: trace -1532 var t/edi: (addr trace) <- address t-storage -1533 initialize-trace t, 0x100/max-depth, 0x100/capacity, 0/visible # we don't use trace UI -1534 # -1535 var nil-storage: (handle cell) -1536 var nil-ah/ecx: (addr handle cell) <- address nil-storage -1537 allocate-pair nil-ah -1538 var one-storage: (handle cell) -1539 var one-ah/edx: (addr handle cell) <- address one-storage -1540 new-integer one-ah, 1 -1541 var add-storage: (handle cell) -1542 var add-ah/ebx: (addr handle cell) <- address add-storage -1543 new-symbol add-ah, "+" -1544 # input is (+ 1 1) -1545 var tmp-storage: (handle cell) -1546 var tmp-ah/esi: (addr handle cell) <- address tmp-storage -1547 new-pair tmp-ah, *one-ah, *nil-ah -1548 new-pair tmp-ah, *one-ah, *tmp-ah -1549 new-pair tmp-ah, *add-ah, *tmp-ah -1550 #? dump-cell tmp-ah -1551 # -1552 var globals-storage: global-table -1553 var globals/edx: (addr global-table) <- address globals-storage -1554 initialize-globals globals -1555 # -1556 evaluate tmp-ah, tmp-ah, *nil-ah, globals, t, 0/no-screen, 0/no-keyboard, 0/call-number -1557 #? dump-trace t -1558 # -1559 var result/eax: (addr cell) <- lookup *tmp-ah -1560 var result-type/edx: (addr int) <- get result, type -1561 check-ints-equal *result-type, 1/number, "F - test-evaluate-primitive-function-call/0" -1562 var result-value-addr/eax: (addr float) <- get result, number-data -1563 var result-value/eax: int <- convert *result-value-addr -1564 check-ints-equal result-value, 2, "F - test-evaluate-primitive-function-call/1" -1565 } -1566 -1567 fn test-evaluate-backquote { -1568 # env = nil -1569 var nil-storage: (handle cell) -1570 var nil-ah/ecx: (addr handle cell) <- address nil-storage -1571 allocate-pair nil-ah -1572 # eval `a, env -1573 var tmp-storage: (handle cell) -1574 var tmp-ah/edx: (addr handle cell) <- address tmp-storage -1575 new-symbol tmp-ah, "`" -1576 var tmp2-storage: (handle cell) -1577 var tmp2-ah/ebx: (addr handle cell) <- address tmp2-storage -1578 new-symbol tmp2-ah, "a" -1579 new-pair tmp-ah, *tmp-ah, *tmp2-ah -1580 clear-object tmp2-ah -1581 var trace-storage: trace -1582 var trace/edi: (addr trace) <- address trace-storage -1583 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1584 evaluate tmp-ah, tmp2-ah, *nil-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number -1585 var result/eax: (addr cell) <- lookup *tmp2-ah -1586 var result-type/edx: (addr int) <- get result, type -1587 check-ints-equal *result-type, 2/symbol, "F - test-evaluate-backquote/0" -1588 var sym?/eax: boolean <- symbol-equal? result, "a" -1589 check sym?, "F - test-evaluate-backquote/1" -1590 } -1591 -1592 fn evaluate-backquote _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int { -1593 # stack overflow? # disable when enabling Really-debug-print -1594 #? dump-cell-from-cursor-over-full-screen _in-ah -1595 check-stack -1596 { -1597 var screen-cell/eax: (addr handle cell) <- copy screen-cell -1598 compare screen-cell, 0 -1599 break-if-= -1600 var screen-cell-addr/eax: (addr cell) <- lookup *screen-cell -1601 compare screen-cell-addr, 0 -1602 break-if-= -1603 # if screen-cell exists, we're probably not in a test -1604 show-stack-state -1605 } -1606 # errors? skip -1607 { -1608 var error?/eax: boolean <- has-errors? trace -1609 compare error?, 0/false -1610 break-if-= -1611 return -1612 } -1613 trace-lower trace -1614 var in-ah/esi: (addr handle cell) <- copy _in-ah -1615 var in/eax: (addr cell) <- lookup *in-ah -1616 { -1617 var nil?/eax: boolean <- nil? in -1618 compare nil?, 0/false -1619 break-if-= -1620 # nil is a literal -1621 trace-text trace, "eval", "backquote nil" -1622 copy-object _in-ah, _out-ah -1623 trace-higher trace -1624 return -1625 } -1626 var in-type/ecx: (addr int) <- get in, type -1627 compare *in-type, 0/pair -1628 { -1629 break-if-= -1630 # copy non-pairs directly -1631 # TODO: streams might need to be copied -1632 trace-text trace, "eval", "backquote atom" -1633 copy-object _in-ah, _out-ah -1634 trace-higher trace -1635 return -1636 } -1637 # 'in' is a pair -1638 debug-print "()", 4/fg, 0/bg -1639 var in-ah/esi: (addr handle cell) <- copy _in-ah -1640 var _in/eax: (addr cell) <- lookup *in-ah -1641 var in/ebx: (addr cell) <- copy _in -1642 var in-left-ah/ecx: (addr handle cell) <- get in, left -1643 debug-print "10", 4/fg, 0/bg -1644 # check for unquote -1645 $macroexpand-iter:unquote: { -1646 var in-left/eax: (addr cell) <- lookup *in-left-ah -1647 var unquote?/eax: boolean <- symbol-equal? in-left, "," -1648 compare unquote?, 0/false -1649 break-if-= -1650 trace-text trace, "eval", "unquote" -1651 var rest-ah/eax: (addr handle cell) <- get in, right -1652 increment call-number -1653 debug-print ",", 3/fg, 0/bg -1654 evaluate rest-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number -1655 debug-print ",)", 3/fg, 0/bg -1656 trace-higher trace -1657 return -1658 } -1659 # check for unquote-splice in in-left -1660 debug-print "11", 4/fg, 0/bg -1661 var out-ah/edi: (addr handle cell) <- copy _out-ah -1662 $macroexpand-iter:unquote-splice: { -1663 #? dump-cell-from-cursor-over-full-screen in-left-ah -1664 var in-left/eax: (addr cell) <- lookup *in-left-ah -1665 { -1666 debug-print "12", 4/fg, 0/bg -1667 { -1668 var in-left-is-nil?/eax: boolean <- nil? in-left -1669 compare in-left-is-nil?, 0/false -1670 } -1671 break-if-!= $macroexpand-iter:unquote-splice -1672 var in-left-type/ecx: (addr int) <- get in-left, type -1673 debug-print "13", 4/fg, 0/bg -1674 compare *in-left-type, 0/pair -1675 break-if-!= $macroexpand-iter:unquote-splice -1676 var in-left-left-ah/eax: (addr handle cell) <- get in-left, left -1677 debug-print "14", 4/fg, 0/bg -1678 var in-left-left/eax: (addr cell) <- lookup *in-left-left-ah -1679 debug-print "15", 4/fg, 0/bg -1680 var in-left-left-type/ecx: (addr int) <- get in-left-left, type -1681 var left-is-unquote-splice?/eax: boolean <- symbol-equal? in-left-left, ",@" -1682 debug-print "16", 4/fg, 0/bg -1683 compare left-is-unquote-splice?, 0/false -1684 } -1685 break-if-= -1686 debug-print "17", 4/fg, 0/bg -1687 trace-text trace, "eval", "unquote-splice" -1688 var in-unquote-payload-ah/eax: (addr handle cell) <- get in-left, right -1689 increment call-number -1690 evaluate in-unquote-payload-ah, out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number -1691 # errors? skip -1692 { -1693 var error?/eax: boolean <- has-errors? trace -1694 compare error?, 0/false -1695 break-if-= -1696 trace-higher trace -1697 return -1698 } -1699 # while (*out-ah != null) out-ah = cdr(out-ah) -1700 { -1701 var out/eax: (addr cell) <- lookup *out-ah -1702 { -1703 var done?/eax: boolean <- nil? out -1704 compare done?, 0/false -1705 } -1706 break-if-!= -1707 out-ah <- get out, right -1708 loop -1709 } -1710 # append result of in-right -1711 var in-right-ah/ecx: (addr handle cell) <- get in, right -1712 evaluate-backquote in-right-ah, out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number -1713 trace-higher trace -1714 return -1715 } -1716 debug-print "19", 4/fg, 0/bg -1717 # otherwise continue copying -1718 trace-text trace, "eval", "backquote: copy" -1719 var out-ah/edi: (addr handle cell) <- copy _out-ah -1720 allocate-pair out-ah -1721 debug-print "20", 7/fg, 0/bg -1722 #? dump-cell-from-cursor-over-full-screen out-ah -1723 var out/eax: (addr cell) <- lookup *out-ah -1724 var out-left-ah/edx: (addr handle cell) <- get out, left -1725 debug-print "`(l", 3/fg, 0/bg -1726 evaluate-backquote in-left-ah, out-left-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number -1727 debug-print "`r)", 3/fg, 0/bg -1728 # errors? skip -1729 { -1730 var error?/eax: boolean <- has-errors? trace -1731 compare error?, 0/false -1732 break-if-= -1733 trace-higher trace -1734 return -1735 } -1736 var in-right-ah/ecx: (addr handle cell) <- get in, right -1737 var out-right-ah/edx: (addr handle cell) <- get out, right -1738 debug-print "`r(", 3/fg, 0/bg -1739 evaluate-backquote in-right-ah, out-right-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number -1740 debug-print "`r)", 3/fg, 0/bg -1741 trace-higher trace -1742 } -1743 -1744 fn test-evaluate-backquote-list { -1745 var nil-storage: (handle cell) -1746 var nil-ah/ecx: (addr handle cell) <- address nil-storage -1747 allocate-pair nil-ah -1748 var backquote-storage: (handle cell) -1749 var backquote-ah/edx: (addr handle cell) <- address backquote-storage -1750 new-symbol backquote-ah, "`" -1751 # input is `(a b) -1752 var a-storage: (handle cell) -1753 var a-ah/ebx: (addr handle cell) <- address a-storage -1754 new-symbol a-ah, "a" -1755 var b-storage: (handle cell) -1756 var b-ah/esi: (addr handle cell) <- address b-storage -1757 new-symbol b-ah, "b" -1758 var tmp-storage: (handle cell) -1759 var tmp-ah/eax: (addr handle cell) <- address tmp-storage -1760 new-pair tmp-ah, *b-ah, *nil-ah -1761 new-pair tmp-ah, *a-ah, *tmp-ah -1762 new-pair tmp-ah, *backquote-ah, *tmp-ah -1763 # -1764 var trace-storage: trace -1765 var trace/edi: (addr trace) <- address trace-storage -1766 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1767 evaluate tmp-ah, tmp-ah, *nil-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number -1768 # result is (a b) -1769 var result/eax: (addr cell) <- lookup *tmp-ah -1770 { -1771 var result-type/eax: (addr int) <- get result, type -1772 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list/0" -1773 } -1774 { -1775 var a1-ah/eax: (addr handle cell) <- get result, left -1776 var a1/eax: (addr cell) <- lookup *a1-ah -1777 var check1/eax: boolean <- symbol-equal? a1, "a" -1778 check check1, "F - test-evaluate-backquote-list/1" -1779 } -1780 var rest-ah/eax: (addr handle cell) <- get result, right -1781 var rest/eax: (addr cell) <- lookup *rest-ah -1782 { -1783 var a2-ah/eax: (addr handle cell) <- get rest, left -1784 var a2/eax: (addr cell) <- lookup *a2-ah -1785 var check2/eax: boolean <- symbol-equal? a2, "b" -1786 check check2, "F - test-evaluate-backquote-list/2" -1787 } -1788 var rest-ah/eax: (addr handle cell) <- get rest, right -1789 var rest/eax: (addr cell) <- lookup *rest-ah -1790 var check3/eax: boolean <- nil? rest -1791 check check3, "F - test-evaluate-backquote-list/3" -1792 } -1793 -1794 fn test-evaluate-backquote-list-with-unquote { -1795 var nil-h: (handle cell) -1796 var nil-ah/eax: (addr handle cell) <- address nil-h -1797 allocate-pair nil-ah -1798 var backquote-h: (handle cell) -1799 var backquote-ah/eax: (addr handle cell) <- address backquote-h -1800 new-symbol backquote-ah, "`" -1801 var unquote-h: (handle cell) -1802 var unquote-ah/eax: (addr handle cell) <- address unquote-h -1803 new-symbol unquote-ah, "," -1804 var a-h: (handle cell) -1805 var a-ah/eax: (addr handle cell) <- address a-h -1806 new-symbol a-ah, "a" -1807 var b-h: (handle cell) -1808 var b-ah/eax: (addr handle cell) <- address b-h -1809 new-symbol b-ah, "b" -1810 # env = ((b . 3)) -1811 var val-h: (handle cell) -1812 var val-ah/eax: (addr handle cell) <- address val-h -1813 new-integer val-ah, 3 -1814 var env-h: (handle cell) -1815 var env-ah/eax: (addr handle cell) <- address env-h -1816 new-pair env-ah, b-h, val-h -1817 new-pair env-ah, env-h, nil-h -1818 # input is `(a ,b) -1819 var tmp-h: (handle cell) -1820 var tmp-ah/eax: (addr handle cell) <- address tmp-h -1821 # tmp = cons(unquote, b) -1822 new-pair tmp-ah, unquote-h, b-h -1823 # tmp = cons(tmp, nil) -1824 new-pair tmp-ah, tmp-h, nil-h -1825 # tmp = cons(a, tmp) -1826 new-pair tmp-ah, a-h, tmp-h -1827 # tmp = cons(backquote, tmp) -1828 new-pair tmp-ah, backquote-h, tmp-h -1829 # -1830 var trace-storage: trace -1831 var trace/edi: (addr trace) <- address trace-storage -1832 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1833 evaluate tmp-ah, tmp-ah, env-h, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number -1834 # result is (a 3) -1835 var result/eax: (addr cell) <- lookup *tmp-ah -1836 { -1837 var result-type/eax: (addr int) <- get result, type -1838 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list-with-unquote/0" -1839 } -1840 { -1841 var a1-ah/eax: (addr handle cell) <- get result, left -1842 var a1/eax: (addr cell) <- lookup *a1-ah -1843 var check1/eax: boolean <- symbol-equal? a1, "a" -1844 check check1, "F - test-evaluate-backquote-list-with-unquote/1" -1845 } -1846 var rest-ah/eax: (addr handle cell) <- get result, right -1847 var rest/eax: (addr cell) <- lookup *rest-ah -1848 { -1849 var a2-ah/eax: (addr handle cell) <- get rest, left -1850 var a2/eax: (addr cell) <- lookup *a2-ah -1851 var a2-value-addr/eax: (addr float) <- get a2, number-data -1852 var a2-value/eax: int <- convert *a2-value-addr -1853 check-ints-equal a2-value, 3, "F - test-evaluate-backquote-list-with-unquote/2" -1854 } -1855 var rest-ah/eax: (addr handle cell) <- get rest, right -1856 var rest/eax: (addr cell) <- lookup *rest-ah -1857 var check3/eax: boolean <- nil? rest -1858 check check3, "F - test-evaluate-backquote-list-with-unquote/3" -1859 } -1860 -1861 fn test-evaluate-backquote-list-with-unquote-splice { -1862 var nil-h: (handle cell) -1863 var nil-ah/eax: (addr handle cell) <- address nil-h -1864 allocate-pair nil-ah -1865 var backquote-h: (handle cell) -1866 var backquote-ah/eax: (addr handle cell) <- address backquote-h -1867 new-symbol backquote-ah, "`" -1868 var unquote-splice-h: (handle cell) -1869 var unquote-splice-ah/eax: (addr handle cell) <- address unquote-splice-h -1870 new-symbol unquote-splice-ah, ",@" -1871 var a-h: (handle cell) -1872 var a-ah/eax: (addr handle cell) <- address a-h -1873 new-symbol a-ah, "a" -1874 var b-h: (handle cell) -1875 var b-ah/eax: (addr handle cell) <- address b-h -1876 new-symbol b-ah, "b" -1877 # env = ((b . (a 3))) -1878 var val-h: (handle cell) -1879 var val-ah/eax: (addr handle cell) <- address val-h -1880 new-integer val-ah, 3 -1881 new-pair val-ah, val-h, nil-h -1882 new-pair val-ah, a-h, val-h -1883 var env-h: (handle cell) -1884 var env-ah/eax: (addr handle cell) <- address env-h -1885 new-pair env-ah, b-h, val-h -1886 new-pair env-ah, env-h, nil-h -1887 # input is `(a ,@b b) -1888 var tmp-h: (handle cell) -1889 var tmp-ah/eax: (addr handle cell) <- address tmp-h -1890 # tmp = cons(b, nil) -1891 new-pair tmp-ah, b-h, nil-h -1892 # tmp2 = cons(unquote-splice, b) -1893 var tmp2-h: (handle cell) -1894 var tmp2-ah/ecx: (addr handle cell) <- address tmp2-h -1895 new-pair tmp2-ah, unquote-splice-h, b-h -1896 # tmp = cons(tmp2, tmp) -1897 new-pair tmp-ah, tmp2-h, tmp-h -1898 # tmp = cons(a, tmp) -1899 new-pair tmp-ah, a-h, tmp-h -1900 # tmp = cons(backquote, tmp) -1901 new-pair tmp-ah, backquote-h, tmp-h -1902 #? dump-cell-from-cursor-over-full-screen tmp-ah -1903 # -1904 var trace-storage: trace -1905 var trace/edi: (addr trace) <- address trace-storage -1906 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -1907 evaluate tmp-ah, tmp-ah, env-h, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number -1908 # result is (a a 3 b) -1909 #? dump-cell-from-cursor-over-full-screen tmp-ah -1910 var result/eax: (addr cell) <- lookup *tmp-ah -1911 { -1912 var result-type/eax: (addr int) <- get result, type -1913 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list-with-unquote-splice/0" -1914 } -1915 { -1916 var a1-ah/eax: (addr handle cell) <- get result, left -1917 var a1/eax: (addr cell) <- lookup *a1-ah -1918 var check1/eax: boolean <- symbol-equal? a1, "a" -1919 check check1, "F - test-evaluate-backquote-list-with-unquote-splice/1" -1920 } -1921 var rest-ah/eax: (addr handle cell) <- get result, right -1922 var rest/eax: (addr cell) <- lookup *rest-ah -1923 { -1924 var a2-ah/eax: (addr handle cell) <- get rest, left -1925 var a2/eax: (addr cell) <- lookup *a2-ah -1926 var check2/eax: boolean <- symbol-equal? a2, "a" -1927 check check2, "F - test-evaluate-backquote-list-with-unquote-splice/2" -1928 } -1929 var rest-ah/eax: (addr handle cell) <- get rest, right -1930 var rest/eax: (addr cell) <- lookup *rest-ah -1931 { -1932 var a3-ah/eax: (addr handle cell) <- get rest, left -1933 var a3/eax: (addr cell) <- lookup *a3-ah -1934 var a3-value-addr/eax: (addr float) <- get a3, number-data -1935 var a3-value/eax: int <- convert *a3-value-addr -1936 check-ints-equal a3-value, 3, "F - test-evaluate-backquote-list-with-unquote-splice/3" -1937 } -1938 var rest-ah/eax: (addr handle cell) <- get rest, right -1939 var rest/eax: (addr cell) <- lookup *rest-ah -1940 { -1941 var a4-ah/eax: (addr handle cell) <- get rest, left -1942 var a4/eax: (addr cell) <- lookup *a4-ah -1943 var check4/eax: boolean <- symbol-equal? a4, "b" -1944 check check4, "F - test-evaluate-backquote-list-with-unquote-splice/4" -1945 } -1946 var rest-ah/eax: (addr handle cell) <- get rest, right -1947 var rest/eax: (addr cell) <- lookup *rest-ah -1948 var check5/eax: boolean <- nil? rest -1949 check check5, "F - test-evaluate-backquote-list-with-unquote-splice/5" -1950 } + 696 evaluate curr-ah, out, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number + 697 debug-print "X", 7/fg, 0/bg + 698 # errors? skip + 699 { + 700 var error?/eax: boolean <- has-errors? trace + 701 compare error?, 0/false + 702 break-if-= + 703 return + 704 } + 705 } + 706 # + 707 exprs-ah <- get exprs, right + 708 loop + 709 } + 710 # `out` contains result of evaluating final expression + 711 } + 712 + 713 # Bind params to corresponding args and add the bindings to old-env. Return + 714 # the result in env-ah. + 715 # + 716 # We never modify old-env, but we point to it. This way other parts of the + 717 # interpreter can continue using old-env, and everything works harmoniously + 718 # even though no cells are copied around. + 719 # + 720 # env should always be a DAG (ignoring internals of values). It doesn't have + 721 # to be a tree (some values may be shared), but there are also no cycles. + 722 # + 723 # Learn more: https://en.wikipedia.org/wiki/Persistent_data_structure + 724 fn push-bindings _params-ah: (addr handle cell), _args-ah: (addr handle cell), old-env-h: (handle cell), env-ah: (addr handle cell), trace: (addr trace) { + 725 var params-ah/edx: (addr handle cell) <- copy _params-ah + 726 var args-ah/ebx: (addr handle cell) <- copy _args-ah + 727 var _params/eax: (addr cell) <- lookup *params-ah + 728 var params/esi: (addr cell) <- copy _params + 729 { + 730 var params-nil?/eax: boolean <- nil? params + 731 compare params-nil?, 0/false + 732 break-if-= + 733 # nil is a literal + 734 trace-text trace, "eval", "done with push-bindings" + 735 copy-handle old-env-h, env-ah + 736 return + 737 } + 738 # Params can only be symbols or pairs. Args can be anything. + 739 +-- 22 lines: # trace "pushing bindings from " params " to " args ----------------------------------------------------------------------------------------------------------------------- + 761 trace-lower trace + 762 var params-type/eax: (addr int) <- get params, type + 763 compare *params-type, 2/symbol + 764 { + 765 break-if-!= + 766 trace-text trace, "eval", "symbol; binding to all remaining args" + 767 # create a new binding + 768 var new-binding-storage: (handle cell) + 769 var new-binding-ah/eax: (addr handle cell) <- address new-binding-storage + 770 new-pair new-binding-ah, *params-ah, *args-ah + 771 # push it to env + 772 new-pair env-ah, *new-binding-ah, old-env-h + 773 trace-higher trace + 774 return + 775 } + 776 compare *params-type, 0/pair + 777 { + 778 break-if-= + 779 error trace, "cannot bind a non-symbol" + 780 trace-higher trace + 781 return + 782 } + 783 var _args/eax: (addr cell) <- lookup *args-ah + 784 var args/edi: (addr cell) <- copy _args + 785 # params is now a pair, so args must be also + 786 { + 787 var args-nil?/eax: boolean <- nil? args + 788 compare args-nil?, 0/false + 789 break-if-= + 790 error trace, "not enough args to bind" + 791 return + 792 } + 793 var args-type/eax: (addr int) <- get args, type + 794 compare *args-type, 0/pair + 795 { + 796 break-if-= + 797 error trace, "args not in a proper list" + 798 trace-higher trace + 799 return + 800 } + 801 var intermediate-env-storage: (handle cell) + 802 var intermediate-env-ah/edx: (addr handle cell) <- address intermediate-env-storage + 803 var first-param-ah/eax: (addr handle cell) <- get params, left + 804 var first-arg-ah/ecx: (addr handle cell) <- get args, left + 805 push-bindings first-param-ah, first-arg-ah, old-env-h, intermediate-env-ah, trace + 806 # errors? skip + 807 { + 808 var error?/eax: boolean <- has-errors? trace + 809 compare error?, 0/false + 810 break-if-= + 811 trace-higher trace + 812 return + 813 } + 814 var remaining-params-ah/eax: (addr handle cell) <- get params, right + 815 var remaining-args-ah/ecx: (addr handle cell) <- get args, right + 816 push-bindings remaining-params-ah, remaining-args-ah, *intermediate-env-ah, env-ah, trace + 817 trace-higher trace + 818 } + 819 + 820 fn lookup-symbol sym: (addr cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell) { + 821 # trace sym + 822 { + 823 var should-trace?/eax: boolean <- should-trace? trace + 824 compare should-trace?, 0/false + 825 break-if-= + 826 var stream-storage: (stream byte 0x800) # pessimistically sized just for the large alist loaded from disk in `main` + 827 var stream/ecx: (addr stream byte) <- address stream-storage + 828 write stream, "look up " + 829 var sym2/eax: (addr cell) <- copy sym + 830 var sym-data-ah/eax: (addr handle stream byte) <- get sym2, text-data + 831 var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah + 832 rewind-stream sym-data + 833 write-stream stream, sym-data + 834 write stream, " in " + 835 var env-ah/eax: (addr handle cell) <- address env-h + 836 var nested-trace-storage: trace + 837 var nested-trace/edi: (addr trace) <- address nested-trace-storage + 838 initialize-trace nested-trace, 1/only-errors, 0x10/capacity, 0/visible + 839 print-cell env-ah, stream, nested-trace + 840 trace trace, "eval", stream + 841 } + 842 trace-lower trace + 843 var _env/eax: (addr cell) <- lookup env-h + 844 var env/ebx: (addr cell) <- copy _env + 845 # if env is not a list, error + 846 { + 847 var env-type/ecx: (addr int) <- get env, type + 848 compare *env-type, 0/pair + 849 break-if-= + 850 error trace, "eval found a non-list environment" + 851 trace-higher trace + 852 return + 853 } + 854 # if env is nil, look up in globals + 855 { + 856 var env-nil?/eax: boolean <- nil? env + 857 compare env-nil?, 0/false + 858 break-if-= + 859 debug-print "b", 7/fg, 0/bg + 860 lookup-symbol-in-globals sym, out, globals, trace, inner-screen-var, inner-keyboard-var + 861 debug-print "x", 7/fg, 0/bg + 862 trace-higher trace + 863 +-- 19 lines: # trace "=> " out " (global)" --------------------------------------------------------------------------------------------------------------------------------------------- + 882 debug-print "y", 7/fg, 0/bg + 883 return + 884 } + 885 # check car + 886 var env-head-storage: (handle cell) + 887 var env-head-ah/eax: (addr handle cell) <- address env-head-storage + 888 car env, env-head-ah, trace + 889 var _env-head/eax: (addr cell) <- lookup *env-head-ah + 890 var env-head/ecx: (addr cell) <- copy _env-head + 891 # if car is not a list, abort + 892 { + 893 var env-head-type/eax: (addr int) <- get env-head, type + 894 compare *env-head-type, 0/pair + 895 break-if-= + 896 error trace, "environment is not a list of (key . value) pairs" + 897 trace-higher trace + 898 return + 899 } + 900 # check key + 901 var curr-key-storage: (handle cell) + 902 var curr-key-ah/eax: (addr handle cell) <- address curr-key-storage + 903 car env-head, curr-key-ah, trace + 904 var curr-key/eax: (addr cell) <- lookup *curr-key-ah + 905 # if key is not a symbol, abort + 906 { + 907 var curr-key-type/eax: (addr int) <- get curr-key, type + 908 compare *curr-key-type, 2/symbol + 909 break-if-= + 910 error trace, "environment contains a binding for a non-symbol" + 911 trace-higher trace + 912 return + 913 } + 914 # if key matches sym, return val + 915 var match?/eax: boolean <- cell-isomorphic? curr-key, sym, trace + 916 compare match?, 0/false + 917 { + 918 break-if-= + 919 cdr env-head, out, trace + 920 +-- 19 lines: # trace "=> " out " (match)" ---------------------------------------------------------------------------------------------------------------------------------------------- + 939 trace-higher trace + 940 return + 941 } + 942 # otherwise recurse + 943 var env-tail-storage: (handle cell) + 944 var env-tail-ah/eax: (addr handle cell) <- address env-tail-storage + 945 cdr env, env-tail-ah, trace + 946 lookup-symbol sym, out, *env-tail-ah, globals, trace, inner-screen-var, inner-keyboard-var + 947 trace-higher trace + 948 +-- 19 lines: # trace "=> " out " (recurse)" -------------------------------------------------------------------------------------------------------------------------------------------- + 967 } + 968 + 969 fn test-lookup-symbol-in-env { + 970 # tmp = (a . 3) + 971 var val-storage: (handle cell) + 972 var val-ah/ecx: (addr handle cell) <- address val-storage + 973 new-integer val-ah, 3 + 974 var key-storage: (handle cell) + 975 var key-ah/edx: (addr handle cell) <- address key-storage + 976 new-symbol key-ah, "a" + 977 var env-storage: (handle cell) + 978 var env-ah/ebx: (addr handle cell) <- address env-storage + 979 new-pair env-ah, *key-ah, *val-ah + 980 # env = ((a . 3)) + 981 var nil-storage: (handle cell) + 982 var nil-ah/ecx: (addr handle cell) <- address nil-storage + 983 allocate-pair nil-ah + 984 new-pair env-ah, *env-ah, *nil-ah + 985 # lookup sym(a) in env tmp + 986 var tmp-storage: (handle cell) + 987 var tmp-ah/edx: (addr handle cell) <- address tmp-storage + 988 new-symbol tmp-ah, "a" + 989 var in/eax: (addr cell) <- lookup *tmp-ah + 990 var trace-storage: trace + 991 var trace/edi: (addr trace) <- address trace-storage + 992 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible + 993 lookup-symbol in, tmp-ah, *env-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard + 994 var result/eax: (addr cell) <- lookup *tmp-ah + 995 var result-type/edx: (addr int) <- get result, type + 996 check-ints-equal *result-type, 1/number, "F - test-lookup-symbol-in-env/0" + 997 var result-value-addr/eax: (addr float) <- get result, number-data + 998 var result-value/eax: int <- convert *result-value-addr + 999 check-ints-equal result-value, 3, "F - test-lookup-symbol-in-env/1" +1000 } +1001 +1002 fn test-lookup-symbol-in-globals { +1003 var globals-storage: global-table +1004 var globals/edi: (addr global-table) <- address globals-storage +1005 initialize-globals globals +1006 # env = nil +1007 var nil-storage: (handle cell) +1008 var nil-ah/ecx: (addr handle cell) <- address nil-storage +1009 allocate-pair nil-ah +1010 # lookup sym(a), env +1011 var tmp-storage: (handle cell) +1012 var tmp-ah/ebx: (addr handle cell) <- address tmp-storage +1013 new-symbol tmp-ah, "+" +1014 var in/eax: (addr cell) <- lookup *tmp-ah +1015 var trace-storage: trace +1016 var trace/esi: (addr trace) <- address trace-storage +1017 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1018 lookup-symbol in, tmp-ah, *nil-ah, globals, trace, 0/no-screen, 0/no-keyboard +1019 var result/eax: (addr cell) <- lookup *tmp-ah +1020 var result-type/edx: (addr int) <- get result, type +1021 check-ints-equal *result-type, 4/primitive-function, "F - test-lookup-symbol-in-globals/0" +1022 var result-value/eax: (addr int) <- get result, index-data +1023 check-ints-equal *result-value, 1/add, "F - test-lookup-symbol-in-globals/1" +1024 } +1025 +1026 fn mutate-binding name: (addr stream byte), val: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace) { +1027 # trace name +1028 { +1029 var should-trace?/eax: boolean <- should-trace? trace +1030 compare should-trace?, 0/false +1031 break-if-= +1032 var stream-storage: (stream byte 0x800) # pessimistically sized just for the large alist loaded from disk in `main` +1033 var stream/ecx: (addr stream byte) <- address stream-storage +1034 write stream, "bind " +1035 rewind-stream name +1036 write-stream stream, name +1037 write stream, " to " +1038 var nested-trace-storage: trace +1039 var nested-trace/edi: (addr trace) <- address nested-trace-storage +1040 initialize-trace nested-trace, 1/only-errors, 0x10/capacity, 0/visible +1041 print-cell val, stream, nested-trace +1042 write stream, " in " +1043 var env-ah/eax: (addr handle cell) <- address env-h +1044 clear-trace nested-trace +1045 print-cell env-ah, stream, nested-trace +1046 trace trace, "eval", stream +1047 } +1048 trace-lower trace +1049 var _env/eax: (addr cell) <- lookup env-h +1050 var env/ebx: (addr cell) <- copy _env +1051 # if env is not a list, abort +1052 { +1053 var env-type/ecx: (addr int) <- get env, type +1054 compare *env-type, 0/pair +1055 break-if-= +1056 error trace, "eval found a non-list environment" +1057 trace-higher trace +1058 return +1059 } +1060 # if env is nil, look in globals +1061 { +1062 var env-nil?/eax: boolean <- nil? env +1063 compare env-nil?, 0/false +1064 break-if-= +1065 debug-print "b", 3/fg, 0/bg +1066 mutate-binding-in-globals name, val, globals, trace +1067 debug-print "x", 3/fg, 0/bg +1068 trace-higher trace +1069 +-- 19 lines: # trace "=> " val " (global)" --------------------------------------------------------------------------------------------------------------------------------------------- +1088 debug-print "y", 3/fg, 0/bg +1089 return +1090 } +1091 # check car +1092 var env-head-storage: (handle cell) +1093 var env-head-ah/eax: (addr handle cell) <- address env-head-storage +1094 car env, env-head-ah, trace +1095 var _env-head/eax: (addr cell) <- lookup *env-head-ah +1096 var env-head/ecx: (addr cell) <- copy _env-head +1097 # if car is not a list, abort +1098 { +1099 var env-head-type/eax: (addr int) <- get env-head, type +1100 compare *env-head-type, 0/pair +1101 break-if-= +1102 error trace, "environment is not a list of (key . value) pairs" +1103 trace-higher trace +1104 return +1105 } +1106 # check key +1107 var curr-key-storage: (handle cell) +1108 var curr-key-ah/eax: (addr handle cell) <- address curr-key-storage +1109 car env-head, curr-key-ah, trace +1110 var curr-key/eax: (addr cell) <- lookup *curr-key-ah +1111 # if key is not a symbol, abort +1112 { +1113 var curr-key-type/eax: (addr int) <- get curr-key, type +1114 compare *curr-key-type, 2/symbol +1115 break-if-= +1116 error trace, "environment contains a binding for a non-symbol" +1117 trace-higher trace +1118 return +1119 } +1120 # if key matches name, return val +1121 var curr-key-data-ah/eax: (addr handle stream byte) <- get curr-key, text-data +1122 var curr-key-data/eax: (addr stream byte) <- lookup *curr-key-data-ah +1123 var match?/eax: boolean <- streams-data-equal? curr-key-data, name +1124 compare match?, 0/false +1125 { +1126 break-if-= +1127 var dest/eax: (addr handle cell) <- get env-head, right +1128 copy-object val, dest +1129 trace-text trace, "eval", "=> done" +1130 trace-higher trace +1131 return +1132 } +1133 # otherwise recurse +1134 var env-tail-storage: (handle cell) +1135 var env-tail-ah/eax: (addr handle cell) <- address env-tail-storage +1136 cdr env, env-tail-ah, trace +1137 mutate-binding name, val, *env-tail-ah, globals, trace +1138 trace-higher trace +1139 } +1140 +1141 fn car _in: (addr cell), out: (addr handle cell), trace: (addr trace) { +1142 trace-text trace, "eval", "car" +1143 trace-lower trace +1144 var in/eax: (addr cell) <- copy _in +1145 # if in is not a list, abort +1146 { +1147 var in-type/ecx: (addr int) <- get in, type +1148 compare *in-type, 0/pair +1149 break-if-= +1150 error trace, "car on a non-list" +1151 trace-higher trace +1152 return +1153 } +1154 # if in is nil, abort +1155 { +1156 var in-nil?/eax: boolean <- nil? in +1157 compare in-nil?, 0/false +1158 break-if-= +1159 error trace, "car on nil" +1160 trace-higher trace +1161 return +1162 } +1163 var in-left/eax: (addr handle cell) <- get in, left +1164 copy-object in-left, out +1165 trace-higher trace +1166 return +1167 } +1168 +1169 fn cdr _in: (addr cell), out: (addr handle cell), trace: (addr trace) { +1170 trace-text trace, "eval", "cdr" +1171 trace-lower trace +1172 var in/eax: (addr cell) <- copy _in +1173 # if in is not a list, abort +1174 { +1175 var in-type/ecx: (addr int) <- get in, type +1176 compare *in-type, 0/pair +1177 break-if-= +1178 error trace, "car on a non-list" +1179 trace-higher trace +1180 return +1181 } +1182 # if in is nil, abort +1183 { +1184 var in-nil?/eax: boolean <- nil? in +1185 compare in-nil?, 0/false +1186 break-if-= +1187 error trace, "car on nil" +1188 trace-higher trace +1189 return +1190 } +1191 var in-right/eax: (addr handle cell) <- get in, right +1192 copy-object in-right, out +1193 trace-higher trace +1194 return +1195 } +1196 +1197 fn cell-isomorphic? _a: (addr cell), _b: (addr cell), trace: (addr trace) -> _/eax: boolean { +1198 trace-text trace, "eval", "cell-isomorphic?" +1199 trace-lower trace +1200 var a/esi: (addr cell) <- copy _a +1201 var b/edi: (addr cell) <- copy _b +1202 # if types don't match, return false +1203 var a-type-addr/eax: (addr int) <- get a, type +1204 var b-type-addr/ecx: (addr int) <- get b, type +1205 var b-type/ecx: int <- copy *b-type-addr +1206 compare b-type, *a-type-addr +1207 { +1208 break-if-= +1209 trace-higher trace +1210 trace-text trace, "eval", "=> false (type)" +1211 return 0/false +1212 } +1213 # if types are number, compare number-data +1214 # TODO: exactly comparing floats is a bad idea +1215 compare b-type, 1/number +1216 { +1217 break-if-!= +1218 var a-val-addr/eax: (addr float) <- get a, number-data +1219 var b-val-addr/ecx: (addr float) <- get b, number-data +1220 var a-val/xmm0: float <- copy *a-val-addr +1221 compare a-val, *b-val-addr +1222 { +1223 break-if-= +1224 trace-higher trace +1225 trace-text trace, "eval", "=> false (numbers)" +1226 return 0/false +1227 } +1228 trace-higher trace +1229 trace-text trace, "eval", "=> true (numbers)" +1230 return 1/true +1231 } +1232 $cell-isomorphic?:text-data: { +1233 { +1234 compare b-type, 2/symbol +1235 break-if-= +1236 compare b-type, 3/stream +1237 break-if-= +1238 break $cell-isomorphic?:text-data +1239 } +1240 var b-val-ah/eax: (addr handle stream byte) <- get b, text-data +1241 var _b-val/eax: (addr stream byte) <- lookup *b-val-ah +1242 var b-val/ecx: (addr stream byte) <- copy _b-val +1243 var a-val-ah/eax: (addr handle stream byte) <- get a, text-data +1244 var a-val/eax: (addr stream byte) <- lookup *a-val-ah +1245 var tmp-array: (handle array byte) +1246 var tmp-ah/edx: (addr handle array byte) <- address tmp-array +1247 rewind-stream a-val +1248 stream-to-array a-val, tmp-ah +1249 var tmp/eax: (addr array byte) <- lookup *tmp-ah +1250 var match?/eax: boolean <- stream-data-equal? b-val, tmp +1251 trace-higher trace +1252 { +1253 compare match?, 0/false +1254 break-if-= +1255 trace-text trace, "eval", "=> true (symbols)" +1256 } +1257 { +1258 compare match?, 0/false +1259 break-if-!= +1260 trace-text trace, "eval", "=> false (symbols)" +1261 } +1262 return match? +1263 } +1264 # if objects are primitive functions, compare index-data +1265 compare b-type, 4/primitive +1266 { +1267 break-if-!= +1268 var a-val-addr/eax: (addr int) <- get a, index-data +1269 var b-val-addr/ecx: (addr int) <- get b, index-data +1270 var a-val/eax: int <- copy *a-val-addr +1271 compare a-val, *b-val-addr +1272 { +1273 break-if-= +1274 trace-higher trace +1275 trace-text trace, "eval", "=> false (primitives)" +1276 return 0/false +1277 } +1278 trace-higher trace +1279 trace-text trace, "eval", "=> true (primitives)" +1280 return 1/true +1281 } +1282 # if objects are screens, check if they're the same object +1283 compare b-type, 5/screen +1284 { +1285 break-if-!= +1286 var a-val-addr/eax: (addr handle screen) <- get a, screen-data +1287 var b-val-addr/ecx: (addr handle screen) <- get b, screen-data +1288 var result/eax: boolean <- handle-equal? *a-val-addr, *b-val-addr +1289 compare result, 0/false +1290 return result +1291 } +1292 # if objects are keyboards, check if they have the same contents +1293 compare b-type, 6/keyboard +1294 { +1295 break-if-!= +1296 var a-val-addr/ecx: (addr handle gap-buffer) <- get a, keyboard-data +1297 var _a/eax: (addr gap-buffer) <- lookup *a-val-addr +1298 var a/ecx: (addr gap-buffer) <- copy _a +1299 var b-val-addr/eax: (addr handle gap-buffer) <- get b, keyboard-data +1300 var b/eax: (addr gap-buffer) <- lookup *b-val-addr +1301 var result/eax: boolean <- gap-buffers-equal? a, b +1302 return result +1303 } +1304 # if a is nil, b should be nil +1305 { +1306 # (assumes nil? returns 0 or 1) +1307 var _b-nil?/eax: boolean <- nil? b +1308 var b-nil?/ecx: boolean <- copy _b-nil? +1309 var a-nil?/eax: boolean <- nil? a +1310 # a == nil and b == nil => return true +1311 { +1312 compare a-nil?, 0/false +1313 break-if-= +1314 compare b-nil?, 0/false +1315 break-if-= +1316 trace-higher trace +1317 trace-text trace, "eval", "=> true (nils)" +1318 return 1/true +1319 } +1320 # a == nil => return false +1321 { +1322 compare a-nil?, 0/false +1323 break-if-= +1324 trace-higher trace +1325 trace-text trace, "eval", "=> false (b != nil)" +1326 return 0/false +1327 } +1328 # b == nil => return false +1329 { +1330 compare b-nil?, 0/false +1331 break-if-= +1332 trace-higher trace +1333 trace-text trace, "eval", "=> false (a != nil)" +1334 return 0/false +1335 } +1336 } +1337 # a and b are pairs +1338 var a-tmp-storage: (handle cell) +1339 var a-tmp-ah/edx: (addr handle cell) <- address a-tmp-storage +1340 var b-tmp-storage: (handle cell) +1341 var b-tmp-ah/ebx: (addr handle cell) <- address b-tmp-storage +1342 # if cars aren't equal, return false +1343 car a, a-tmp-ah, trace +1344 car b, b-tmp-ah, trace +1345 { +1346 var _a-tmp/eax: (addr cell) <- lookup *a-tmp-ah +1347 var a-tmp/ecx: (addr cell) <- copy _a-tmp +1348 var b-tmp/eax: (addr cell) <- lookup *b-tmp-ah +1349 var result/eax: boolean <- cell-isomorphic? a-tmp, b-tmp, trace +1350 compare result, 0/false +1351 break-if-!= +1352 trace-higher trace +1353 trace-text trace, "eval", "=> false (car mismatch)" +1354 return 0/false +1355 } +1356 # recurse on cdrs +1357 cdr a, a-tmp-ah, trace +1358 cdr b, b-tmp-ah, trace +1359 var _a-tmp/eax: (addr cell) <- lookup *a-tmp-ah +1360 var a-tmp/ecx: (addr cell) <- copy _a-tmp +1361 var b-tmp/eax: (addr cell) <- lookup *b-tmp-ah +1362 var result/eax: boolean <- cell-isomorphic? a-tmp, b-tmp, trace +1363 trace-higher trace +1364 return result +1365 } +1366 +1367 fn fn? _x: (addr cell) -> _/eax: boolean { +1368 var x/esi: (addr cell) <- copy _x +1369 var type/eax: (addr int) <- get x, type +1370 compare *type, 2/symbol +1371 { +1372 break-if-= +1373 return 0/false +1374 } +1375 var contents-ah/eax: (addr handle stream byte) <- get x, text-data +1376 var contents/eax: (addr stream byte) <- lookup *contents-ah +1377 var result/eax: boolean <- stream-data-equal? contents, "fn" +1378 return result +1379 } +1380 +1381 fn litfn? _x: (addr cell) -> _/eax: boolean { +1382 var x/esi: (addr cell) <- copy _x +1383 var type/eax: (addr int) <- get x, type +1384 compare *type, 2/symbol +1385 { +1386 break-if-= +1387 return 0/false +1388 } +1389 var contents-ah/eax: (addr handle stream byte) <- get x, text-data +1390 var contents/eax: (addr stream byte) <- lookup *contents-ah +1391 var result/eax: boolean <- stream-data-equal? contents, "litfn" +1392 return result +1393 } +1394 +1395 fn litmac? _x: (addr cell) -> _/eax: boolean { +1396 var x/esi: (addr cell) <- copy _x +1397 var type/eax: (addr int) <- get x, type +1398 compare *type, 2/symbol +1399 { +1400 break-if-= +1401 return 0/false +1402 } +1403 var contents-ah/eax: (addr handle stream byte) <- get x, text-data +1404 var contents/eax: (addr stream byte) <- lookup *contents-ah +1405 var result/eax: boolean <- stream-data-equal? contents, "litmac" +1406 return result +1407 } +1408 +1409 fn test-evaluate-is-well-behaved { +1410 var t-storage: trace +1411 var t/esi: (addr trace) <- address t-storage +1412 initialize-trace t, 0x100/max-depth, 0x10/capacity, 0/visible # we don't use trace UI +1413 # env = nil +1414 var env-storage: (handle cell) +1415 var env-ah/ecx: (addr handle cell) <- address env-storage +1416 allocate-pair env-ah +1417 # eval sym(a), nil env +1418 var tmp-storage: (handle cell) +1419 var tmp-ah/edx: (addr handle cell) <- address tmp-storage +1420 new-symbol tmp-ah, "a" +1421 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, t, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1422 # doesn't die +1423 check-trace-contains t, "error", "unbound symbol: a", "F - test-evaluate-is-well-behaved" +1424 } +1425 +1426 fn test-evaluate-number { +1427 # env = nil +1428 var env-storage: (handle cell) +1429 var env-ah/ecx: (addr handle cell) <- address env-storage +1430 allocate-pair env-ah +1431 # tmp = 3 +1432 var tmp-storage: (handle cell) +1433 var tmp-ah/edx: (addr handle cell) <- address tmp-storage +1434 new-integer tmp-ah, 3 +1435 var trace-storage: trace +1436 var trace/edi: (addr trace) <- address trace-storage +1437 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1438 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1439 # +1440 var result/eax: (addr cell) <- lookup *tmp-ah +1441 var result-type/edx: (addr int) <- get result, type +1442 check-ints-equal *result-type, 1/number, "F - test-evaluate-number/0" +1443 var result-value-addr/eax: (addr float) <- get result, number-data +1444 var result-value/eax: int <- convert *result-value-addr +1445 check-ints-equal result-value, 3, "F - test-evaluate-number/1" +1446 } +1447 +1448 fn test-evaluate-symbol { +1449 # tmp = (a . 3) +1450 var val-storage: (handle cell) +1451 var val-ah/ecx: (addr handle cell) <- address val-storage +1452 new-integer val-ah, 3 +1453 var key-storage: (handle cell) +1454 var key-ah/edx: (addr handle cell) <- address key-storage +1455 new-symbol key-ah, "a" +1456 var env-storage: (handle cell) +1457 var env-ah/ebx: (addr handle cell) <- address env-storage +1458 new-pair env-ah, *key-ah, *val-ah +1459 # env = ((a . 3)) +1460 var nil-storage: (handle cell) +1461 var nil-ah/ecx: (addr handle cell) <- address nil-storage +1462 allocate-pair nil-ah +1463 new-pair env-ah, *env-ah, *nil-ah +1464 # eval sym(a), env +1465 var tmp-storage: (handle cell) +1466 var tmp-ah/edx: (addr handle cell) <- address tmp-storage +1467 new-symbol tmp-ah, "a" +1468 var trace-storage: trace +1469 var trace/edi: (addr trace) <- address trace-storage +1470 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1471 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1472 var result/eax: (addr cell) <- lookup *tmp-ah +1473 var result-type/edx: (addr int) <- get result, type +1474 check-ints-equal *result-type, 1/number, "F - test-evaluate-symbol/0" +1475 var result-value-addr/eax: (addr float) <- get result, number-data +1476 var result-value/eax: int <- convert *result-value-addr +1477 check-ints-equal result-value, 3, "F - test-evaluate-symbol/1" +1478 } +1479 +1480 fn test-evaluate-quote { +1481 # env = nil +1482 var nil-storage: (handle cell) +1483 var nil-ah/ecx: (addr handle cell) <- address nil-storage +1484 allocate-pair nil-ah +1485 # eval `a, env +1486 var tmp-storage: (handle cell) +1487 var tmp-ah/edx: (addr handle cell) <- address tmp-storage +1488 new-symbol tmp-ah, "'" +1489 var tmp2-storage: (handle cell) +1490 var tmp2-ah/ebx: (addr handle cell) <- address tmp2-storage +1491 new-symbol tmp2-ah, "a" +1492 new-pair tmp-ah, *tmp-ah, *tmp2-ah +1493 var trace-storage: trace +1494 var trace/edi: (addr trace) <- address trace-storage +1495 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1496 evaluate tmp-ah, tmp-ah, *nil-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1497 var result/eax: (addr cell) <- lookup *tmp-ah +1498 var result-type/edx: (addr int) <- get result, type +1499 check-ints-equal *result-type, 2/symbol, "F - test-evaluate-quote/0" +1500 var sym?/eax: boolean <- symbol-equal? result, "a" +1501 check sym?, "F - test-evaluate-quote/1" +1502 } +1503 +1504 fn test-evaluate-primitive-function { +1505 var globals-storage: global-table +1506 var globals/edi: (addr global-table) <- address globals-storage +1507 initialize-globals globals +1508 var nil-storage: (handle cell) +1509 var nil-ah/ecx: (addr handle cell) <- address nil-storage +1510 allocate-pair nil-ah +1511 var add-storage: (handle cell) +1512 var add-ah/ebx: (addr handle cell) <- address add-storage +1513 new-symbol add-ah, "+" +1514 # eval +, nil env +1515 var tmp-storage: (handle cell) +1516 var tmp-ah/esi: (addr handle cell) <- address tmp-storage +1517 var trace-storage: trace +1518 var trace/edx: (addr trace) <- address trace-storage +1519 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1520 evaluate add-ah, tmp-ah, *nil-ah, globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1521 # +1522 var result/eax: (addr cell) <- lookup *tmp-ah +1523 var result-type/edx: (addr int) <- get result, type +1524 check-ints-equal *result-type, 4/primitive-function, "F - test-evaluate-primitive-function/0" +1525 var result-value/eax: (addr int) <- get result, index-data +1526 check-ints-equal *result-value, 1/add, "F - test-evaluate-primitive-function/1" +1527 } +1528 +1529 fn test-evaluate-primitive-function-call { +1530 var t-storage: trace +1531 var t/edi: (addr trace) <- address t-storage +1532 initialize-trace t, 0x100/max-depth, 0x100/capacity, 0/visible # we don't use trace UI +1533 # +1534 var nil-storage: (handle cell) +1535 var nil-ah/ecx: (addr handle cell) <- address nil-storage +1536 allocate-pair nil-ah +1537 var one-storage: (handle cell) +1538 var one-ah/edx: (addr handle cell) <- address one-storage +1539 new-integer one-ah, 1 +1540 var add-storage: (handle cell) +1541 var add-ah/ebx: (addr handle cell) <- address add-storage +1542 new-symbol add-ah, "+" +1543 # input is (+ 1 1) +1544 var tmp-storage: (handle cell) +1545 var tmp-ah/esi: (addr handle cell) <- address tmp-storage +1546 new-pair tmp-ah, *one-ah, *nil-ah +1547 new-pair tmp-ah, *one-ah, *tmp-ah +1548 new-pair tmp-ah, *add-ah, *tmp-ah +1549 #? dump-cell tmp-ah +1550 # +1551 var globals-storage: global-table +1552 var globals/edx: (addr global-table) <- address globals-storage +1553 initialize-globals globals +1554 # +1555 evaluate tmp-ah, tmp-ah, *nil-ah, globals, t, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1556 #? dump-trace t +1557 # +1558 var result/eax: (addr cell) <- lookup *tmp-ah +1559 var result-type/edx: (addr int) <- get result, type +1560 check-ints-equal *result-type, 1/number, "F - test-evaluate-primitive-function-call/0" +1561 var result-value-addr/eax: (addr float) <- get result, number-data +1562 var result-value/eax: int <- convert *result-value-addr +1563 check-ints-equal result-value, 2, "F - test-evaluate-primitive-function-call/1" +1564 } +1565 +1566 fn test-evaluate-backquote { +1567 # env = nil +1568 var nil-storage: (handle cell) +1569 var nil-ah/ecx: (addr handle cell) <- address nil-storage +1570 allocate-pair nil-ah +1571 # eval `a, env +1572 var tmp-storage: (handle cell) +1573 var tmp-ah/edx: (addr handle cell) <- address tmp-storage +1574 new-symbol tmp-ah, "`" +1575 var tmp2-storage: (handle cell) +1576 var tmp2-ah/ebx: (addr handle cell) <- address tmp2-storage +1577 new-symbol tmp2-ah, "a" +1578 new-pair tmp-ah, *tmp-ah, *tmp2-ah +1579 clear-object tmp2-ah +1580 var trace-storage: trace +1581 var trace/edi: (addr trace) <- address trace-storage +1582 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1583 evaluate tmp-ah, tmp2-ah, *nil-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1584 var result/eax: (addr cell) <- lookup *tmp2-ah +1585 var result-type/edx: (addr int) <- get result, type +1586 check-ints-equal *result-type, 2/symbol, "F - test-evaluate-backquote/0" +1587 var sym?/eax: boolean <- symbol-equal? result, "a" +1588 check sym?, "F - test-evaluate-backquote/1" +1589 } +1590 +1591 fn evaluate-backquote _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell), definitions-created: (addr stream int), call-number: (addr int) { +1592 # stack overflow? # disable when enabling Really-debug-print +1593 #? dump-cell-from-cursor-over-full-screen _in-ah +1594 check-stack +1595 { +1596 var inner-screen-var/eax: (addr handle cell) <- copy inner-screen-var +1597 compare inner-screen-var, 0 +1598 break-if-= +1599 var inner-screen-var-addr/eax: (addr cell) <- lookup *inner-screen-var +1600 compare inner-screen-var-addr, 0 +1601 break-if-= +1602 # if inner-screen-var exists, we're probably not in a test +1603 show-stack-state +1604 } +1605 # errors? skip +1606 { +1607 var error?/eax: boolean <- has-errors? trace +1608 compare error?, 0/false +1609 break-if-= +1610 return +1611 } +1612 trace-lower trace +1613 var in-ah/esi: (addr handle cell) <- copy _in-ah +1614 var in/eax: (addr cell) <- lookup *in-ah +1615 { +1616 var nil?/eax: boolean <- nil? in +1617 compare nil?, 0/false +1618 break-if-= +1619 # nil is a literal +1620 trace-text trace, "eval", "backquote nil" +1621 copy-object _in-ah, _out-ah +1622 trace-higher trace +1623 return +1624 } +1625 var in-type/ecx: (addr int) <- get in, type +1626 compare *in-type, 0/pair +1627 { +1628 break-if-= +1629 # copy non-pairs directly +1630 # TODO: streams might need to be copied +1631 trace-text trace, "eval", "backquote atom" +1632 copy-object _in-ah, _out-ah +1633 trace-higher trace +1634 return +1635 } +1636 # 'in' is a pair +1637 debug-print "()", 4/fg, 0/bg +1638 var in-ah/esi: (addr handle cell) <- copy _in-ah +1639 var _in/eax: (addr cell) <- lookup *in-ah +1640 var in/ebx: (addr cell) <- copy _in +1641 var in-left-ah/ecx: (addr handle cell) <- get in, left +1642 debug-print "10", 4/fg, 0/bg +1643 # check for unquote +1644 $macroexpand-iter:unquote: { +1645 var in-left/eax: (addr cell) <- lookup *in-left-ah +1646 var unquote?/eax: boolean <- symbol-equal? in-left, "," +1647 compare unquote?, 0/false +1648 break-if-= +1649 trace-text trace, "eval", "unquote" +1650 var rest-ah/eax: (addr handle cell) <- get in, right +1651 debug-print ",", 3/fg, 0/bg +1652 evaluate rest-ah, _out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number +1653 debug-print ",)", 3/fg, 0/bg +1654 trace-higher trace +1655 return +1656 } +1657 # check for unquote-splice in in-left +1658 debug-print "11", 4/fg, 0/bg +1659 var out-ah/edi: (addr handle cell) <- copy _out-ah +1660 $macroexpand-iter:unquote-splice: { +1661 #? dump-cell-from-cursor-over-full-screen in-left-ah +1662 var in-left/eax: (addr cell) <- lookup *in-left-ah +1663 { +1664 debug-print "12", 4/fg, 0/bg +1665 { +1666 var in-left-is-nil?/eax: boolean <- nil? in-left +1667 compare in-left-is-nil?, 0/false +1668 } +1669 break-if-!= $macroexpand-iter:unquote-splice +1670 var in-left-type/ecx: (addr int) <- get in-left, type +1671 debug-print "13", 4/fg, 0/bg +1672 compare *in-left-type, 0/pair +1673 break-if-!= $macroexpand-iter:unquote-splice +1674 var in-left-left-ah/eax: (addr handle cell) <- get in-left, left +1675 debug-print "14", 4/fg, 0/bg +1676 var in-left-left/eax: (addr cell) <- lookup *in-left-left-ah +1677 debug-print "15", 4/fg, 0/bg +1678 var in-left-left-type/ecx: (addr int) <- get in-left-left, type +1679 var left-is-unquote-splice?/eax: boolean <- symbol-equal? in-left-left, ",@" +1680 debug-print "16", 4/fg, 0/bg +1681 compare left-is-unquote-splice?, 0/false +1682 } +1683 break-if-= +1684 debug-print "17", 4/fg, 0/bg +1685 trace-text trace, "eval", "unquote-splice" +1686 var in-unquote-payload-ah/eax: (addr handle cell) <- get in-left, right +1687 evaluate in-unquote-payload-ah, out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number +1688 # errors? skip +1689 { +1690 var error?/eax: boolean <- has-errors? trace +1691 compare error?, 0/false +1692 break-if-= +1693 trace-higher trace +1694 return +1695 } +1696 # while (*out-ah != null) out-ah = cdr(out-ah) +1697 { +1698 var out/eax: (addr cell) <- lookup *out-ah +1699 { +1700 var done?/eax: boolean <- nil? out +1701 compare done?, 0/false +1702 } +1703 break-if-!= +1704 out-ah <- get out, right +1705 loop +1706 } +1707 # append result of in-right +1708 var in-right-ah/ecx: (addr handle cell) <- get in, right +1709 evaluate-backquote in-right-ah, out-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number +1710 trace-higher trace +1711 return +1712 } +1713 debug-print "19", 4/fg, 0/bg +1714 # otherwise continue copying +1715 trace-text trace, "eval", "backquote: copy" +1716 var out-ah/edi: (addr handle cell) <- copy _out-ah +1717 allocate-pair out-ah +1718 debug-print "20", 7/fg, 0/bg +1719 #? dump-cell-from-cursor-over-full-screen out-ah +1720 var out/eax: (addr cell) <- lookup *out-ah +1721 var out-left-ah/edx: (addr handle cell) <- get out, left +1722 debug-print "`(l", 3/fg, 0/bg +1723 evaluate-backquote in-left-ah, out-left-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number +1724 debug-print "`r)", 3/fg, 0/bg +1725 # errors? skip +1726 { +1727 var error?/eax: boolean <- has-errors? trace +1728 compare error?, 0/false +1729 break-if-= +1730 trace-higher trace +1731 return +1732 } +1733 var in-right-ah/ecx: (addr handle cell) <- get in, right +1734 var out-right-ah/edx: (addr handle cell) <- get out, right +1735 debug-print "`r(", 3/fg, 0/bg +1736 evaluate-backquote in-right-ah, out-right-ah, env-h, globals, trace, inner-screen-var, inner-keyboard-var, definitions-created, call-number +1737 debug-print "`r)", 3/fg, 0/bg +1738 trace-higher trace +1739 } +1740 +1741 fn test-evaluate-backquote-list { +1742 var nil-storage: (handle cell) +1743 var nil-ah/ecx: (addr handle cell) <- address nil-storage +1744 allocate-pair nil-ah +1745 var backquote-storage: (handle cell) +1746 var backquote-ah/edx: (addr handle cell) <- address backquote-storage +1747 new-symbol backquote-ah, "`" +1748 # input is `(a b) +1749 var a-storage: (handle cell) +1750 var a-ah/ebx: (addr handle cell) <- address a-storage +1751 new-symbol a-ah, "a" +1752 var b-storage: (handle cell) +1753 var b-ah/esi: (addr handle cell) <- address b-storage +1754 new-symbol b-ah, "b" +1755 var tmp-storage: (handle cell) +1756 var tmp-ah/eax: (addr handle cell) <- address tmp-storage +1757 new-pair tmp-ah, *b-ah, *nil-ah +1758 new-pair tmp-ah, *a-ah, *tmp-ah +1759 new-pair tmp-ah, *backquote-ah, *tmp-ah +1760 # +1761 var trace-storage: trace +1762 var trace/edi: (addr trace) <- address trace-storage +1763 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1764 evaluate tmp-ah, tmp-ah, *nil-ah, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1765 # result is (a b) +1766 var result/eax: (addr cell) <- lookup *tmp-ah +1767 { +1768 var result-type/eax: (addr int) <- get result, type +1769 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list/0" +1770 } +1771 { +1772 var a1-ah/eax: (addr handle cell) <- get result, left +1773 var a1/eax: (addr cell) <- lookup *a1-ah +1774 var check1/eax: boolean <- symbol-equal? a1, "a" +1775 check check1, "F - test-evaluate-backquote-list/1" +1776 } +1777 var rest-ah/eax: (addr handle cell) <- get result, right +1778 var rest/eax: (addr cell) <- lookup *rest-ah +1779 { +1780 var a2-ah/eax: (addr handle cell) <- get rest, left +1781 var a2/eax: (addr cell) <- lookup *a2-ah +1782 var check2/eax: boolean <- symbol-equal? a2, "b" +1783 check check2, "F - test-evaluate-backquote-list/2" +1784 } +1785 var rest-ah/eax: (addr handle cell) <- get rest, right +1786 var rest/eax: (addr cell) <- lookup *rest-ah +1787 var check3/eax: boolean <- nil? rest +1788 check check3, "F - test-evaluate-backquote-list/3" +1789 } +1790 +1791 fn test-evaluate-backquote-list-with-unquote { +1792 var nil-h: (handle cell) +1793 var nil-ah/eax: (addr handle cell) <- address nil-h +1794 allocate-pair nil-ah +1795 var backquote-h: (handle cell) +1796 var backquote-ah/eax: (addr handle cell) <- address backquote-h +1797 new-symbol backquote-ah, "`" +1798 var unquote-h: (handle cell) +1799 var unquote-ah/eax: (addr handle cell) <- address unquote-h +1800 new-symbol unquote-ah, "," +1801 var a-h: (handle cell) +1802 var a-ah/eax: (addr handle cell) <- address a-h +1803 new-symbol a-ah, "a" +1804 var b-h: (handle cell) +1805 var b-ah/eax: (addr handle cell) <- address b-h +1806 new-symbol b-ah, "b" +1807 # env = ((b . 3)) +1808 var val-h: (handle cell) +1809 var val-ah/eax: (addr handle cell) <- address val-h +1810 new-integer val-ah, 3 +1811 var env-h: (handle cell) +1812 var env-ah/eax: (addr handle cell) <- address env-h +1813 new-pair env-ah, b-h, val-h +1814 new-pair env-ah, env-h, nil-h +1815 # input is `(a ,b) +1816 var tmp-h: (handle cell) +1817 var tmp-ah/eax: (addr handle cell) <- address tmp-h +1818 # tmp = cons(unquote, b) +1819 new-pair tmp-ah, unquote-h, b-h +1820 # tmp = cons(tmp, nil) +1821 new-pair tmp-ah, tmp-h, nil-h +1822 # tmp = cons(a, tmp) +1823 new-pair tmp-ah, a-h, tmp-h +1824 # tmp = cons(backquote, tmp) +1825 new-pair tmp-ah, backquote-h, tmp-h +1826 # +1827 var trace-storage: trace +1828 var trace/edi: (addr trace) <- address trace-storage +1829 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1830 evaluate tmp-ah, tmp-ah, env-h, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1831 # result is (a 3) +1832 var result/eax: (addr cell) <- lookup *tmp-ah +1833 { +1834 var result-type/eax: (addr int) <- get result, type +1835 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list-with-unquote/0" +1836 } +1837 { +1838 var a1-ah/eax: (addr handle cell) <- get result, left +1839 var a1/eax: (addr cell) <- lookup *a1-ah +1840 var check1/eax: boolean <- symbol-equal? a1, "a" +1841 check check1, "F - test-evaluate-backquote-list-with-unquote/1" +1842 } +1843 var rest-ah/eax: (addr handle cell) <- get result, right +1844 var rest/eax: (addr cell) <- lookup *rest-ah +1845 { +1846 var a2-ah/eax: (addr handle cell) <- get rest, left +1847 var a2/eax: (addr cell) <- lookup *a2-ah +1848 var a2-value-addr/eax: (addr float) <- get a2, number-data +1849 var a2-value/eax: int <- convert *a2-value-addr +1850 check-ints-equal a2-value, 3, "F - test-evaluate-backquote-list-with-unquote/2" +1851 } +1852 var rest-ah/eax: (addr handle cell) <- get rest, right +1853 var rest/eax: (addr cell) <- lookup *rest-ah +1854 var check3/eax: boolean <- nil? rest +1855 check check3, "F - test-evaluate-backquote-list-with-unquote/3" +1856 } +1857 +1858 fn test-evaluate-backquote-list-with-unquote-splice { +1859 var nil-h: (handle cell) +1860 var nil-ah/eax: (addr handle cell) <- address nil-h +1861 allocate-pair nil-ah +1862 var backquote-h: (handle cell) +1863 var backquote-ah/eax: (addr handle cell) <- address backquote-h +1864 new-symbol backquote-ah, "`" +1865 var unquote-splice-h: (handle cell) +1866 var unquote-splice-ah/eax: (addr handle cell) <- address unquote-splice-h +1867 new-symbol unquote-splice-ah, ",@" +1868 var a-h: (handle cell) +1869 var a-ah/eax: (addr handle cell) <- address a-h +1870 new-symbol a-ah, "a" +1871 var b-h: (handle cell) +1872 var b-ah/eax: (addr handle cell) <- address b-h +1873 new-symbol b-ah, "b" +1874 # env = ((b . (a 3))) +1875 var val-h: (handle cell) +1876 var val-ah/eax: (addr handle cell) <- address val-h +1877 new-integer val-ah, 3 +1878 new-pair val-ah, val-h, nil-h +1879 new-pair val-ah, a-h, val-h +1880 var env-h: (handle cell) +1881 var env-ah/eax: (addr handle cell) <- address env-h +1882 new-pair env-ah, b-h, val-h +1883 new-pair env-ah, env-h, nil-h +1884 # input is `(a ,@b b) +1885 var tmp-h: (handle cell) +1886 var tmp-ah/eax: (addr handle cell) <- address tmp-h +1887 # tmp = cons(b, nil) +1888 new-pair tmp-ah, b-h, nil-h +1889 # tmp2 = cons(unquote-splice, b) +1890 var tmp2-h: (handle cell) +1891 var tmp2-ah/ecx: (addr handle cell) <- address tmp2-h +1892 new-pair tmp2-ah, unquote-splice-h, b-h +1893 # tmp = cons(tmp2, tmp) +1894 new-pair tmp-ah, tmp2-h, tmp-h +1895 # tmp = cons(a, tmp) +1896 new-pair tmp-ah, a-h, tmp-h +1897 # tmp = cons(backquote, tmp) +1898 new-pair tmp-ah, backquote-h, tmp-h +1899 #? dump-cell-from-cursor-over-full-screen tmp-ah +1900 # +1901 var trace-storage: trace +1902 var trace/edi: (addr trace) <- address trace-storage +1903 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +1904 evaluate tmp-ah, tmp-ah, env-h, 0/no-globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number +1905 # result is (a a 3 b) +1906 #? dump-cell-from-cursor-over-full-screen tmp-ah +1907 var result/eax: (addr cell) <- lookup *tmp-ah +1908 { +1909 var result-type/eax: (addr int) <- get result, type +1910 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list-with-unquote-splice/0" +1911 } +1912 { +1913 var a1-ah/eax: (addr handle cell) <- get result, left +1914 var a1/eax: (addr cell) <- lookup *a1-ah +1915 var check1/eax: boolean <- symbol-equal? a1, "a" +1916 check check1, "F - test-evaluate-backquote-list-with-unquote-splice/1" +1917 } +1918 var rest-ah/eax: (addr handle cell) <- get result, right +1919 var rest/eax: (addr cell) <- lookup *rest-ah +1920 { +1921 var a2-ah/eax: (addr handle cell) <- get rest, left +1922 var a2/eax: (addr cell) <- lookup *a2-ah +1923 var check2/eax: boolean <- symbol-equal? a2, "a" +1924 check check2, "F - test-evaluate-backquote-list-with-unquote-splice/2" +1925 } +1926 var rest-ah/eax: (addr handle cell) <- get rest, right +1927 var rest/eax: (addr cell) <- lookup *rest-ah +1928 { +1929 var a3-ah/eax: (addr handle cell) <- get rest, left +1930 var a3/eax: (addr cell) <- lookup *a3-ah +1931 var a3-value-addr/eax: (addr float) <- get a3, number-data +1932 var a3-value/eax: int <- convert *a3-value-addr +1933 check-ints-equal a3-value, 3, "F - test-evaluate-backquote-list-with-unquote-splice/3" +1934 } +1935 var rest-ah/eax: (addr handle cell) <- get rest, right +1936 var rest/eax: (addr cell) <- lookup *rest-ah +1937 { +1938 var a4-ah/eax: (addr handle cell) <- get rest, left +1939 var a4/eax: (addr cell) <- lookup *a4-ah +1940 var check4/eax: boolean <- symbol-equal? a4, "b" +1941 check check4, "F - test-evaluate-backquote-list-with-unquote-splice/4" +1942 } +1943 var rest-ah/eax: (addr handle cell) <- get rest, right +1944 var rest/eax: (addr cell) <- lookup *rest-ah +1945 var check5/eax: boolean <- nil? rest +1946 check check5, "F - test-evaluate-backquote-list-with-unquote-splice/5" +1947 } diff --git a/html/shell/gap-buffer.mu.html b/html/shell/gap-buffer.mu.html index 265a4cc6..f22c381f 100644 --- a/html/shell/gap-buffer.mu.html +++ b/html/shell/gap-buffer.mu.html @@ -16,6 +16,7 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } .Delimiter { color: #c000c0; } +.muRegEdx { color: #878700; } .muRegEbx { color: #8787af; } .muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } @@ -27,7 +28,6 @@ a { color:inherit; } .muComment { color: #005faf; } .muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } --> @@ -105,7 +105,7 @@ if ('onhashchange' in window) { 40 return result 41 } 42 - 43 fn gap-buffer-capacity _gap: (addr gap-buffer) -> _/ecx: int { + 43 fn gap-buffer-capacity _gap: (addr gap-buffer) -> _/edx: int { 44 var gap/esi: (addr gap-buffer) <- copy _gap 45 var left/eax: (addr grapheme-stack) <- get gap, left 46 var left-data-ah/eax: (addr handle array grapheme) <- get left, data @@ -115,17 +115,17 @@ if ('onhashchange' in window) { 50 } 51 52 # just for tests - 53 fn initialize-gap-buffer-with self: (addr gap-buffer), s: (addr array byte) { + 53 fn initialize-gap-buffer-with self: (addr gap-buffer), keys: (addr array byte) { 54 initialize-gap-buffer self, 0x40/capacity - 55 var stream-storage: (stream byte 0x40/capacity) - 56 var stream/ecx: (addr stream byte) <- address stream-storage - 57 write stream, s + 55 var input-stream-storage: (stream byte 0x40/capacity) + 56 var input-stream/ecx: (addr stream byte) <- address input-stream-storage + 57 write input-stream, keys 58 { - 59 var done?/eax: boolean <- stream-empty? stream + 59 var done?/eax: boolean <- stream-empty? input-stream 60 compare done?, 0/false 61 break-if-!= - 62 var g/eax: grapheme <- read-grapheme stream - 63 add-grapheme-at-gap self, g + 62 var g/eax: grapheme <- read-grapheme input-stream + 63 add-grapheme-at-gap self, g 64 loop 65 } 66 } @@ -140,7 +140,7 @@ if ('onhashchange' in window) { 75 compare key, 0/null 76 break-if-= 77 var g/eax: grapheme <- copy key - 78 edit-gap-buffer self, g + 78 edit-gap-buffer self, g 79 loop 80 } 81 } @@ -228,7 +228,7 @@ if ('onhashchange' in window) { 163 var _g: gap-buffer 164 var g/esi: (addr gap-buffer) <- address _g 165 initialize-gap-buffer-with g, "abc" - 166 gap-to-start g + 166 gap-to-start g 167 # 168 var out-storage: (stream byte 0x10) 169 var out/eax: (addr stream byte) <- address out-storage @@ -251,7 +251,7 @@ if ('onhashchange' in window) { 186 var _g: gap-buffer 187 var g/esi: (addr gap-buffer) <- address _g 188 initialize-gap-buffer-with g, " abc" - 189 gap-to-start g + 189 gap-to-start g 190 # 191 var out-storage: (stream byte 0x10) 192 var out/eax: (addr stream byte) <- address out-storage @@ -274,7 +274,7 @@ if ('onhashchange' in window) { 209 var _g: gap-buffer 210 var g/esi: (addr gap-buffer) <- address _g 211 initialize-gap-buffer-with g, "a bc d" - 212 gap-to-start g + 212 gap-to-start g 213 # 214 var out-storage: (stream byte 0x10) 215 var out/eax: (addr stream byte) <- address out-storage @@ -286,7 +286,7 @@ if ('onhashchange' in window) { 221 var _g: gap-buffer 222 var g/esi: (addr gap-buffer) <- address _g 223 initialize-gap-buffer-with g, "a bc d" - 224 var dummy/eax: grapheme <- gap-left g + 224 var dummy/eax: grapheme <- gap-left g 225 # gap is at final word 226 var out-storage: (stream byte 0x10) 227 var out/eax: (addr stream byte) <- address out-storage @@ -298,7 +298,7 @@ if ('onhashchange' in window) { 233 var _g: gap-buffer 234 var g/esi: (addr gap-buffer) <- address _g 235 initialize-gap-buffer-with g, "abc " - 236 var dummy/eax: grapheme <- gap-left g + 236 var dummy/eax: grapheme <- gap-left g 237 # gap is at final word 238 var out-storage: (stream byte 0x10) 239 var out/eax: (addr stream byte) <- address out-storage @@ -451,1068 +451,1090 @@ if ('onhashchange' in window) { 386 fn render-gap-buffer-wrapping-right-then-down screen: (addr screen), _gap: (addr gap-buffer), xmin: int, ymin: int, xmax: int, ymax: int, render-cursor?: boolean, color: int, background-color: int -> _/eax: int, _/ecx: int { 387 var gap/esi: (addr gap-buffer) <- copy _gap 388 var left/edx: (addr grapheme-stack) <- get gap, left - 389 var highlight-matching-open-paren?/ebx: boolean <- copy 0/false + 389 var highlight-matching-open-paren?/ebx: boolean <- copy 0/false 390 var matching-open-paren-depth/edi: int <- copy 0 - 391 highlight-matching-open-paren?, matching-open-paren-depth <- highlight-matching-open-paren? gap, render-cursor? + 391 highlight-matching-open-paren?, matching-open-paren-depth <- highlight-matching-open-paren? gap, render-cursor? 392 var x2/eax: int <- copy 0 393 var y2/ecx: int <- copy 0 - 394 x2, y2 <- render-stack-from-bottom-wrapping-right-then-down screen, left, xmin, ymin, xmax, ymax, xmin, ymin, highlight-matching-open-paren?, matching-open-paren-depth, color, background-color + 394 x2, y2 <- render-stack-from-bottom-wrapping-right-then-down screen, left, xmin, ymin, xmax, ymax, xmin, ymin, highlight-matching-open-paren?, matching-open-paren-depth, color, background-color 395 var right/edx: (addr grapheme-stack) <- get gap, right 396 x2, y2 <- render-stack-from-top-wrapping-right-then-down screen, right, xmin, ymin, xmax, ymax, x2, y2, render-cursor?, color, background-color 397 # decide whether we still need to print a cursor - 398 var bg/ebx: int <- copy background-color - 399 compare render-cursor?, 0/false - 400 { - 401 break-if-= - 402 # if the right side is empty, grapheme stack didn't print the cursor - 403 var empty?/eax: boolean <- grapheme-stack-empty? right - 404 compare empty?, 0/false - 405 break-if-= - 406 bg <- copy 7/cursor - 407 } - 408 # print a grapheme either way so that cursor position doesn't affect printed width - 409 var space/edx: grapheme <- copy 0x20 - 410 x2, y2 <- render-grapheme screen, space, xmin, ymin, xmax, ymax, x2, y2, color, bg - 411 return x2, y2 - 412 } - 413 - 414 fn render-gap-buffer screen: (addr screen), gap: (addr gap-buffer), x: int, y: int, render-cursor?: boolean, color: int, background-color: int -> _/eax: int { - 415 var _width/eax: int <- copy 0 - 416 var _height/ecx: int <- copy 0 - 417 _width, _height <- screen-size screen - 418 var width/edx: int <- copy _width - 419 var height/ebx: int <- copy _height - 420 var x2/eax: int <- copy 0 - 421 var y2/ecx: int <- copy 0 - 422 x2, y2 <- render-gap-buffer-wrapping-right-then-down screen, gap, x, y, width, height, render-cursor?, color, background-color - 423 return x2 # y2? yolo - 424 } - 425 - 426 fn gap-buffer-length _gap: (addr gap-buffer) -> _/eax: int { - 427 var gap/esi: (addr gap-buffer) <- copy _gap - 428 var left/eax: (addr grapheme-stack) <- get gap, left - 429 var tmp/eax: (addr int) <- get left, top - 430 var left-length/ecx: int <- copy *tmp - 431 var right/esi: (addr grapheme-stack) <- get gap, right - 432 tmp <- get right, top - 433 var result/eax: int <- copy *tmp - 434 result <- add left-length - 435 return result - 436 } - 437 - 438 fn add-grapheme-at-gap _self: (addr gap-buffer), g: grapheme { - 439 var self/esi: (addr gap-buffer) <- copy _self - 440 var left/eax: (addr grapheme-stack) <- get self, left - 441 push-grapheme-stack left, g - 442 } - 443 - 444 fn add-code-point-at-gap self: (addr gap-buffer), c: code-point { - 445 var g/eax: grapheme <- copy c - 446 add-grapheme-at-gap self, g - 447 } - 448 - 449 fn gap-to-start self: (addr gap-buffer) { - 450 { - 451 var curr/eax: grapheme <- gap-left self - 452 compare curr, -1 - 453 loop-if-!= - 454 } - 455 } - 456 - 457 fn gap-to-end self: (addr gap-buffer) { - 458 { - 459 var curr/eax: grapheme <- gap-right self - 460 compare curr, -1 - 461 loop-if-!= - 462 } - 463 } - 464 - 465 fn gap-at-start? _self: (addr gap-buffer) -> _/eax: boolean { - 466 var self/esi: (addr gap-buffer) <- copy _self - 467 var left/eax: (addr grapheme-stack) <- get self, left - 468 var result/eax: boolean <- grapheme-stack-empty? left - 469 return result - 470 } - 471 - 472 fn gap-at-end? _self: (addr gap-buffer) -> _/eax: boolean { - 473 var self/esi: (addr gap-buffer) <- copy _self - 474 var right/eax: (addr grapheme-stack) <- get self, right - 475 var result/eax: boolean <- grapheme-stack-empty? right - 476 return result - 477 } - 478 - 479 fn gap-right _self: (addr gap-buffer) -> _/eax: grapheme { - 480 var self/esi: (addr gap-buffer) <- copy _self - 481 var g/eax: grapheme <- copy 0 - 482 var right/ecx: (addr grapheme-stack) <- get self, right - 483 g <- pop-grapheme-stack right - 484 compare g, -1 - 485 { - 486 break-if-= - 487 var left/ecx: (addr grapheme-stack) <- get self, left - 488 push-grapheme-stack left, g - 489 } - 490 return g - 491 } - 492 - 493 fn gap-left _self: (addr gap-buffer) -> _/eax: grapheme { - 494 var self/esi: (addr gap-buffer) <- copy _self - 495 var g/eax: grapheme <- copy 0 - 496 { - 497 var left/ecx: (addr grapheme-stack) <- get self, left - 498 g <- pop-grapheme-stack left - 499 } - 500 compare g, -1 - 501 { - 502 break-if-= - 503 var right/ecx: (addr grapheme-stack) <- get self, right - 504 push-grapheme-stack right, g - 505 } - 506 return g - 507 } - 508 - 509 fn index-of-gap _self: (addr gap-buffer) -> _/eax: int { - 510 var self/eax: (addr gap-buffer) <- copy _self - 511 var left/eax: (addr grapheme-stack) <- get self, left - 512 var top-addr/eax: (addr int) <- get left, top - 513 var result/eax: int <- copy *top-addr - 514 return result - 515 } - 516 - 517 fn first-grapheme-in-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme { - 518 var self/esi: (addr gap-buffer) <- copy _self - 519 # try to read from left - 520 var left/eax: (addr grapheme-stack) <- get self, left - 521 var top-addr/ecx: (addr int) <- get left, top - 522 compare *top-addr, 0 - 523 { - 524 break-if-<= - 525 var data-ah/eax: (addr handle array grapheme) <- get left, data - 526 var data/eax: (addr array grapheme) <- lookup *data-ah - 527 var result-addr/eax: (addr grapheme) <- index data, 0 - 528 return *result-addr - 529 } - 530 # try to read from right - 531 var right/eax: (addr grapheme-stack) <- get self, right - 532 top-addr <- get right, top - 533 compare *top-addr, 0 - 534 { - 535 break-if-<= - 536 var data-ah/eax: (addr handle array grapheme) <- get right, data - 537 var data/eax: (addr array grapheme) <- lookup *data-ah - 538 var top/ecx: int <- copy *top-addr - 539 top <- decrement - 540 var result-addr/eax: (addr grapheme) <- index data, top - 541 return *result-addr - 542 } - 543 # give up - 544 return -1 - 545 } - 546 - 547 fn grapheme-before-cursor-in-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme { - 548 var self/esi: (addr gap-buffer) <- copy _self - 549 # try to read from left - 550 var left/ecx: (addr grapheme-stack) <- get self, left - 551 var top-addr/edx: (addr int) <- get left, top - 552 compare *top-addr, 0 - 553 { - 554 break-if-<= - 555 var result/eax: grapheme <- pop-grapheme-stack left - 556 push-grapheme-stack left, result - 557 return result - 558 } - 559 # give up - 560 return -1 - 561 } - 562 - 563 fn delete-before-gap _self: (addr gap-buffer) { - 564 var self/eax: (addr gap-buffer) <- copy _self - 565 var left/eax: (addr grapheme-stack) <- get self, left - 566 var dummy/eax: grapheme <- pop-grapheme-stack left - 567 } - 568 - 569 fn pop-after-gap _self: (addr gap-buffer) -> _/eax: grapheme { - 570 var self/eax: (addr gap-buffer) <- copy _self - 571 var right/eax: (addr grapheme-stack) <- get self, right - 572 var result/eax: grapheme <- pop-grapheme-stack right - 573 return result - 574 } - 575 - 576 fn gap-buffer-equal? _self: (addr gap-buffer), s: (addr array byte) -> _/eax: boolean { - 577 var self/esi: (addr gap-buffer) <- copy _self - 578 # complication: graphemes may be multiple bytes - 579 # so don't rely on length - 580 # instead turn the expected result into a stream and arrange to read from it in order - 581 var stream-storage: (stream byte 0x10/capacity) - 582 var expected-stream/ecx: (addr stream byte) <- address stream-storage - 583 write expected-stream, s - 584 # compare left - 585 var left/edx: (addr grapheme-stack) <- get self, left - 586 var result/eax: boolean <- prefix-match? left, expected-stream - 587 compare result, 0/false - 588 { - 589 break-if-!= - 590 return result - 591 } - 592 # compare right - 593 var right/edx: (addr grapheme-stack) <- get self, right - 594 result <- suffix-match? right, expected-stream - 595 compare result, 0/false - 596 { - 597 break-if-!= - 598 return result - 599 } - 600 # ensure there's nothing left over - 601 result <- stream-empty? expected-stream - 602 return result - 603 } - 604 - 605 fn test-gap-buffer-equal-from-end { - 606 var _g: gap-buffer - 607 var g/esi: (addr gap-buffer) <- address _g - 608 initialize-gap-buffer g, 0x10 - 609 # - 610 add-code-point-at-gap g, 0x61/a - 611 add-code-point-at-gap g, 0x61/a - 612 add-code-point-at-gap g, 0x61/a - 613 # gap is at end (right is empty) - 614 var result/eax: boolean <- gap-buffer-equal? g, "aaa" - 615 check result, "F - test-gap-buffer-equal-from-end" - 616 } - 617 - 618 fn test-gap-buffer-equal-from-middle { - 619 var _g: gap-buffer - 620 var g/esi: (addr gap-buffer) <- address _g - 621 initialize-gap-buffer g, 0x10 - 622 # - 623 add-code-point-at-gap g, 0x61/a - 624 add-code-point-at-gap g, 0x61/a - 625 add-code-point-at-gap g, 0x61/a - 626 var dummy/eax: grapheme <- gap-left g - 627 # gap is in the middle - 628 var result/eax: boolean <- gap-buffer-equal? g, "aaa" - 629 check result, "F - test-gap-buffer-equal-from-middle" - 630 } - 631 - 632 fn test-gap-buffer-equal-from-start { - 633 var _g: gap-buffer - 634 var g/esi: (addr gap-buffer) <- address _g - 635 initialize-gap-buffer g, 0x10 - 636 # - 637 add-code-point-at-gap g, 0x61/a - 638 add-code-point-at-gap g, 0x61/a - 639 add-code-point-at-gap g, 0x61/a - 640 var dummy/eax: grapheme <- gap-left g - 641 dummy <- gap-left g - 642 dummy <- gap-left g - 643 # gap is at the start - 644 var result/eax: boolean <- gap-buffer-equal? g, "aaa" - 645 check result, "F - test-gap-buffer-equal-from-start" - 646 } - 647 - 648 fn test-gap-buffer-equal-fails { - 649 # g = "aaa" - 650 var _g: gap-buffer - 651 var g/esi: (addr gap-buffer) <- address _g - 652 initialize-gap-buffer g, 0x10 - 653 add-code-point-at-gap g, 0x61/a - 654 add-code-point-at-gap g, 0x61/a - 655 add-code-point-at-gap g, 0x61/a - 656 # - 657 var result/eax: boolean <- gap-buffer-equal? g, "aa" - 658 check-not result, "F - test-gap-buffer-equal-fails" - 659 } - 660 - 661 fn gap-buffers-equal? self: (addr gap-buffer), g: (addr gap-buffer) -> _/eax: boolean { - 662 var tmp/eax: int <- gap-buffer-length self - 663 var len/ecx: int <- copy tmp - 664 var leng/eax: int <- gap-buffer-length g - 665 compare len, leng - 666 { - 667 break-if-= - 668 return 0/false - 669 } - 670 var i/edx: int <- copy 0 - 671 { - 672 compare i, len - 673 break-if->= - 674 { - 675 var tmp/eax: grapheme <- gap-index self, i - 676 var curr/ecx: grapheme <- copy tmp - 677 var currg/eax: grapheme <- gap-index g, i - 678 compare curr, currg - 679 break-if-= - 680 return 0/false - 681 } - 682 i <- increment - 683 loop - 684 } - 685 return 1/true - 686 } - 687 - 688 fn gap-index _self: (addr gap-buffer), _n: int -> _/eax: grapheme { - 689 var self/esi: (addr gap-buffer) <- copy _self - 690 var n/ebx: int <- copy _n - 691 # if n < left->length, index into left - 692 var left/edi: (addr grapheme-stack) <- get self, left - 693 var left-len-a/edx: (addr int) <- get left, top - 694 compare n, *left-len-a - 695 { - 696 break-if->= - 697 var data-ah/eax: (addr handle array grapheme) <- get left, data - 698 var data/eax: (addr array grapheme) <- lookup *data-ah - 699 var result/eax: (addr grapheme) <- index data, n - 700 return *result - 701 } - 702 # shrink n - 703 n <- subtract *left-len-a - 704 # if n < right->length, index into right - 705 var right/edi: (addr grapheme-stack) <- get self, right - 706 var right-len-a/edx: (addr int) <- get right, top - 707 compare n, *right-len-a - 708 { - 709 break-if->= - 710 var data-ah/eax: (addr handle array grapheme) <- get right, data - 711 var data/eax: (addr array grapheme) <- lookup *data-ah - 712 # idx = right->len - n - 1 - 713 var idx/ebx: int <- copy n - 714 idx <- subtract *right-len-a - 715 idx <- negate - 716 idx <- subtract 1 - 717 var result/eax: (addr grapheme) <- index data, idx - 718 return *result - 719 } - 720 # error - 721 abort "gap-index: out of bounds" - 722 return 0 - 723 } - 724 - 725 fn test-gap-buffers-equal? { - 726 var _a: gap-buffer - 727 var a/esi: (addr gap-buffer) <- address _a - 728 initialize-gap-buffer-with a, "abc" - 729 var _b: gap-buffer - 730 var b/edi: (addr gap-buffer) <- address _b - 731 initialize-gap-buffer-with b, "abc" - 732 var _c: gap-buffer - 733 var c/ebx: (addr gap-buffer) <- address _c - 734 initialize-gap-buffer-with c, "ab" - 735 var _d: gap-buffer - 736 var d/edx: (addr gap-buffer) <- address _d - 737 initialize-gap-buffer-with d, "abd" - 738 # - 739 var result/eax: boolean <- gap-buffers-equal? a, a - 740 check result, "F - test-gap-buffers-equal? - reflexive" - 741 result <- gap-buffers-equal? a, b - 742 check result, "F - test-gap-buffers-equal? - equal" - 743 # length not equal - 744 result <- gap-buffers-equal? a, c - 745 check-not result, "F - test-gap-buffers-equal? - not equal" - 746 # contents not equal - 747 result <- gap-buffers-equal? a, d - 748 check-not result, "F - test-gap-buffers-equal? - not equal 2" - 749 result <- gap-buffers-equal? d, a - 750 check-not result, "F - test-gap-buffers-equal? - not equal 3" - 751 } - 752 - 753 fn test-gap-buffer-index { - 754 var gap-storage: gap-buffer - 755 var gap/esi: (addr gap-buffer) <- address gap-storage - 756 initialize-gap-buffer-with gap, "abc" - 757 # gap is at end, all contents are in left - 758 var g/eax: grapheme <- gap-index gap, 0 - 759 var x/ecx: int <- copy g - 760 check-ints-equal x, 0x61/a, "F - test-gap-index/left-1" - 761 var g/eax: grapheme <- gap-index gap, 1 + 398 var fg/edi: int <- copy color + 399 var bg/ebx: int <- copy background-color + 400 compare render-cursor?, 0/false + 401 { + 402 break-if-= + 403 # if the right side is empty, grapheme stack didn't print the cursor + 404 var empty?/eax: boolean <- grapheme-stack-empty? right + 405 compare empty?, 0/false + 406 break-if-= + 407 # swap foreground and background + 408 fg <- copy background-color + 409 bg <- copy color + 410 } + 411 # print a grapheme either way so that cursor position doesn't affect printed width + 412 var space/edx: grapheme <- copy 0x20 + 413 x2, y2 <- render-grapheme screen, space, xmin, ymin, xmax, ymax, x2, y2, fg, bg + 414 return x2, y2 + 415 } + 416 + 417 fn render-gap-buffer screen: (addr screen), gap: (addr gap-buffer), x: int, y: int, render-cursor?: boolean, color: int, background-color: int -> _/eax: int { + 418 var _width/eax: int <- copy 0 + 419 var _height/ecx: int <- copy 0 + 420 _width, _height <- screen-size screen + 421 var width/edx: int <- copy _width + 422 var height/ebx: int <- copy _height + 423 var x2/eax: int <- copy 0 + 424 var y2/ecx: int <- copy 0 + 425 x2, y2 <- render-gap-buffer-wrapping-right-then-down screen, gap, x, y, width, height, render-cursor?, color, background-color + 426 return x2 # y2? yolo + 427 } + 428 + 429 fn gap-buffer-length _gap: (addr gap-buffer) -> _/eax: int { + 430 var gap/esi: (addr gap-buffer) <- copy _gap + 431 var left/eax: (addr grapheme-stack) <- get gap, left + 432 var tmp/eax: (addr int) <- get left, top + 433 var left-length/ecx: int <- copy *tmp + 434 var right/esi: (addr grapheme-stack) <- get gap, right + 435 tmp <- get right, top + 436 var result/eax: int <- copy *tmp + 437 result <- add left-length + 438 return result + 439 } + 440 + 441 fn add-grapheme-at-gap _self: (addr gap-buffer), g: grapheme { + 442 var self/esi: (addr gap-buffer) <- copy _self + 443 var left/eax: (addr grapheme-stack) <- get self, left + 444 push-grapheme-stack left, g + 445 } + 446 + 447 fn add-code-point-at-gap self: (addr gap-buffer), c: code-point { + 448 var g/eax: grapheme <- copy c + 449 add-grapheme-at-gap self, g + 450 } + 451 + 452 fn gap-to-start self: (addr gap-buffer) { + 453 { + 454 var curr/eax: grapheme <- gap-left self + 455 compare curr, -1 + 456 loop-if-!= + 457 } + 458 } + 459 + 460 fn gap-to-end self: (addr gap-buffer) { + 461 { + 462 var curr/eax: grapheme <- gap-right self + 463 compare curr, -1 + 464 loop-if-!= + 465 } + 466 } + 467 + 468 fn gap-at-start? _self: (addr gap-buffer) -> _/eax: boolean { + 469 var self/esi: (addr gap-buffer) <- copy _self + 470 var left/eax: (addr grapheme-stack) <- get self, left + 471 var result/eax: boolean <- grapheme-stack-empty? left + 472 return result + 473 } + 474 + 475 fn gap-at-end? _self: (addr gap-buffer) -> _/eax: boolean { + 476 var self/esi: (addr gap-buffer) <- copy _self + 477 var right/eax: (addr grapheme-stack) <- get self, right + 478 var result/eax: boolean <- grapheme-stack-empty? right + 479 return result + 480 } + 481 + 482 fn gap-right _self: (addr gap-buffer) -> _/eax: grapheme { + 483 var self/esi: (addr gap-buffer) <- copy _self + 484 var g/eax: grapheme <- copy 0 + 485 var right/ecx: (addr grapheme-stack) <- get self, right + 486 g <- pop-grapheme-stack right + 487 compare g, -1 + 488 { + 489 break-if-= + 490 var left/ecx: (addr grapheme-stack) <- get self, left + 491 push-grapheme-stack left, g + 492 } + 493 return g + 494 } + 495 + 496 fn gap-left _self: (addr gap-buffer) -> _/eax: grapheme { + 497 var self/esi: (addr gap-buffer) <- copy _self + 498 var g/eax: grapheme <- copy 0 + 499 { + 500 var left/ecx: (addr grapheme-stack) <- get self, left + 501 g <- pop-grapheme-stack left + 502 } + 503 compare g, -1 + 504 { + 505 break-if-= + 506 var right/ecx: (addr grapheme-stack) <- get self, right + 507 push-grapheme-stack right, g + 508 } + 509 return g + 510 } + 511 + 512 fn index-of-gap _self: (addr gap-buffer) -> _/eax: int { + 513 var self/eax: (addr gap-buffer) <- copy _self + 514 var left/eax: (addr grapheme-stack) <- get self, left + 515 var top-addr/eax: (addr int) <- get left, top + 516 var result/eax: int <- copy *top-addr + 517 return result + 518 } + 519 + 520 fn first-grapheme-in-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme { + 521 var self/esi: (addr gap-buffer) <- copy _self + 522 # try to read from left + 523 var left/eax: (addr grapheme-stack) <- get self, left + 524 var top-addr/ecx: (addr int) <- get left, top + 525 compare *top-addr, 0 + 526 { + 527 break-if-<= + 528 var data-ah/eax: (addr handle array grapheme) <- get left, data + 529 var data/eax: (addr array grapheme) <- lookup *data-ah + 530 var result-addr/eax: (addr grapheme) <- index data, 0 + 531 return *result-addr + 532 } + 533 # try to read from right + 534 var right/eax: (addr grapheme-stack) <- get self, right + 535 top-addr <- get right, top + 536 compare *top-addr, 0 + 537 { + 538 break-if-<= + 539 var data-ah/eax: (addr handle array grapheme) <- get right, data + 540 var data/eax: (addr array grapheme) <- lookup *data-ah + 541 var top/ecx: int <- copy *top-addr + 542 top <- decrement + 543 var result-addr/eax: (addr grapheme) <- index data, top + 544 return *result-addr + 545 } + 546 # give up + 547 return -1 + 548 } + 549 + 550 fn grapheme-before-cursor-in-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme { + 551 var self/esi: (addr gap-buffer) <- copy _self + 552 # try to read from left + 553 var left/ecx: (addr grapheme-stack) <- get self, left + 554 var top-addr/edx: (addr int) <- get left, top + 555 compare *top-addr, 0 + 556 { + 557 break-if-<= + 558 var result/eax: grapheme <- pop-grapheme-stack left + 559 push-grapheme-stack left, result + 560 return result + 561 } + 562 # give up + 563 return -1 + 564 } + 565 + 566 fn delete-before-gap _self: (addr gap-buffer) { + 567 var self/eax: (addr gap-buffer) <- copy _self + 568 var left/eax: (addr grapheme-stack) <- get self, left + 569 var dummy/eax: grapheme <- pop-grapheme-stack left + 570 } + 571 + 572 fn pop-after-gap _self: (addr gap-buffer) -> _/eax: grapheme { + 573 var self/eax: (addr gap-buffer) <- copy _self + 574 var right/eax: (addr grapheme-stack) <- get self, right + 575 var result/eax: grapheme <- pop-grapheme-stack right + 576 return result + 577 } + 578 + 579 fn gap-buffer-equal? _self: (addr gap-buffer), s: (addr array byte) -> _/eax: boolean { + 580 var self/esi: (addr gap-buffer) <- copy _self + 581 # complication: graphemes may be multiple bytes + 582 # so don't rely on length + 583 # instead turn the expected result into a stream and arrange to read from it in order + 584 var stream-storage: (stream byte 0x10/capacity) + 585 var expected-stream/ecx: (addr stream byte) <- address stream-storage + 586 write expected-stream, s + 587 # compare left + 588 var left/edx: (addr grapheme-stack) <- get self, left + 589 var result/eax: boolean <- prefix-match? left, expected-stream + 590 compare result, 0/false + 591 { + 592 break-if-!= + 593 return result + 594 } + 595 # compare right + 596 var right/edx: (addr grapheme-stack) <- get self, right + 597 result <- suffix-match? right, expected-stream + 598 compare result, 0/false + 599 { + 600 break-if-!= + 601 return result + 602 } + 603 # ensure there's nothing left over + 604 result <- stream-empty? expected-stream + 605 return result + 606 } + 607 + 608 fn test-gap-buffer-equal-from-end { + 609 var _g: gap-buffer + 610 var g/esi: (addr gap-buffer) <- address _g + 611 initialize-gap-buffer g, 0x10 + 612 # + 613 add-code-point-at-gap g, 0x61/a + 614 add-code-point-at-gap g, 0x61/a + 615 add-code-point-at-gap g, 0x61/a + 616 # gap is at end (right is empty) + 617 var result/eax: boolean <- gap-buffer-equal? g, "aaa" + 618 check result, "F - test-gap-buffer-equal-from-end" + 619 } + 620 + 621 fn test-gap-buffer-equal-from-middle { + 622 var _g: gap-buffer + 623 var g/esi: (addr gap-buffer) <- address _g + 624 initialize-gap-buffer g, 0x10 + 625 # + 626 add-code-point-at-gap g, 0x61/a + 627 add-code-point-at-gap g, 0x61/a + 628 add-code-point-at-gap g, 0x61/a + 629 var dummy/eax: grapheme <- gap-left g + 630 # gap is in the middle + 631 var result/eax: boolean <- gap-buffer-equal? g, "aaa" + 632 check result, "F - test-gap-buffer-equal-from-middle" + 633 } + 634 + 635 fn test-gap-buffer-equal-from-start { + 636 var _g: gap-buffer + 637 var g/esi: (addr gap-buffer) <- address _g + 638 initialize-gap-buffer g, 0x10 + 639 # + 640 add-code-point-at-gap g, 0x61/a + 641 add-code-point-at-gap g, 0x61/a + 642 add-code-point-at-gap g, 0x61/a + 643 var dummy/eax: grapheme <- gap-left g + 644 dummy <- gap-left g + 645 dummy <- gap-left g + 646 # gap is at the start + 647 var result/eax: boolean <- gap-buffer-equal? g, "aaa" + 648 check result, "F - test-gap-buffer-equal-from-start" + 649 } + 650 + 651 fn test-gap-buffer-equal-fails { + 652 # g = "aaa" + 653 var _g: gap-buffer + 654 var g/esi: (addr gap-buffer) <- address _g + 655 initialize-gap-buffer g, 0x10 + 656 add-code-point-at-gap g, 0x61/a + 657 add-code-point-at-gap g, 0x61/a + 658 add-code-point-at-gap g, 0x61/a + 659 # + 660 var result/eax: boolean <- gap-buffer-equal? g, "aa" + 661 check-not result, "F - test-gap-buffer-equal-fails" + 662 } + 663 + 664 fn gap-buffers-equal? self: (addr gap-buffer), g: (addr gap-buffer) -> _/eax: boolean { + 665 var tmp/eax: int <- gap-buffer-length self + 666 var len/ecx: int <- copy tmp + 667 var leng/eax: int <- gap-buffer-length g + 668 compare len, leng + 669 { + 670 break-if-= + 671 return 0/false + 672 } + 673 var i/edx: int <- copy 0 + 674 { + 675 compare i, len + 676 break-if->= + 677 { + 678 var tmp/eax: grapheme <- gap-index self, i + 679 var curr/ecx: grapheme <- copy tmp + 680 var currg/eax: grapheme <- gap-index g, i + 681 compare curr, currg + 682 break-if-= + 683 return 0/false + 684 } + 685 i <- increment + 686 loop + 687 } + 688 return 1/true + 689 } + 690 + 691 fn gap-index _self: (addr gap-buffer), _n: int -> _/eax: grapheme { + 692 var self/esi: (addr gap-buffer) <- copy _self + 693 var n/ebx: int <- copy _n + 694 # if n < left->length, index into left + 695 var left/edi: (addr grapheme-stack) <- get self, left + 696 var left-len-a/edx: (addr int) <- get left, top + 697 compare n, *left-len-a + 698 { + 699 break-if->= + 700 var data-ah/eax: (addr handle array grapheme) <- get left, data + 701 var data/eax: (addr array grapheme) <- lookup *data-ah + 702 var result/eax: (addr grapheme) <- index data, n + 703 return *result + 704 } + 705 # shrink n + 706 n <- subtract *left-len-a + 707 # if n < right->length, index into right + 708 var right/edi: (addr grapheme-stack) <- get self, right + 709 var right-len-a/edx: (addr int) <- get right, top + 710 compare n, *right-len-a + 711 { + 712 break-if->= + 713 var data-ah/eax: (addr handle array grapheme) <- get right, data + 714 var data/eax: (addr array grapheme) <- lookup *data-ah + 715 # idx = right->len - n - 1 + 716 var idx/ebx: int <- copy n + 717 idx <- subtract *right-len-a + 718 idx <- negate + 719 idx <- subtract 1 + 720 var result/eax: (addr grapheme) <- index data, idx + 721 return *result + 722 } + 723 # error + 724 abort "gap-index: out of bounds" + 725 return 0 + 726 } + 727 + 728 fn test-gap-buffers-equal? { + 729 var _a: gap-buffer + 730 var a/esi: (addr gap-buffer) <- address _a + 731 initialize-gap-buffer-with a, "abc" + 732 var _b: gap-buffer + 733 var b/edi: (addr gap-buffer) <- address _b + 734 initialize-gap-buffer-with b, "abc" + 735 var _c: gap-buffer + 736 var c/ebx: (addr gap-buffer) <- address _c + 737 initialize-gap-buffer-with c, "ab" + 738 var _d: gap-buffer + 739 var d/edx: (addr gap-buffer) <- address _d + 740 initialize-gap-buffer-with d, "abd" + 741 # + 742 var result/eax: boolean <- gap-buffers-equal? a, a + 743 check result, "F - test-gap-buffers-equal? - reflexive" + 744 result <- gap-buffers-equal? a, b + 745 check result, "F - test-gap-buffers-equal? - equal" + 746 # length not equal + 747 result <- gap-buffers-equal? a, c + 748 check-not result, "F - test-gap-buffers-equal? - not equal" + 749 # contents not equal + 750 result <- gap-buffers-equal? a, d + 751 check-not result, "F - test-gap-buffers-equal? - not equal 2" + 752 result <- gap-buffers-equal? d, a + 753 check-not result, "F - test-gap-buffers-equal? - not equal 3" + 754 } + 755 + 756 fn test-gap-buffer-index { + 757 var gap-storage: gap-buffer + 758 var gap/esi: (addr gap-buffer) <- address gap-storage + 759 initialize-gap-buffer-with gap, "abc" + 760 # gap is at end, all contents are in left + 761 var g/eax: grapheme <- gap-index gap, 0 762 var x/ecx: int <- copy g - 763 check-ints-equal x, 0x62/b, "F - test-gap-index/left-2" - 764 var g/eax: grapheme <- gap-index gap, 2 + 763 check-ints-equal x, 0x61/a, "F - test-gap-index/left-1" + 764 var g/eax: grapheme <- gap-index gap, 1 765 var x/ecx: int <- copy g - 766 check-ints-equal x, 0x63/c, "F - test-gap-index/left-3" - 767 # now check when everything is to the right - 768 gap-to-start gap - 769 rewind-gap-buffer gap - 770 var g/eax: grapheme <- gap-index gap, 0 - 771 var x/ecx: int <- copy g - 772 check-ints-equal x, 0x61/a, "F - test-gap-index/right-1" - 773 var g/eax: grapheme <- gap-index gap, 1 + 766 check-ints-equal x, 0x62/b, "F - test-gap-index/left-2" + 767 var g/eax: grapheme <- gap-index gap, 2 + 768 var x/ecx: int <- copy g + 769 check-ints-equal x, 0x63/c, "F - test-gap-index/left-3" + 770 # now check when everything is to the right + 771 gap-to-start gap + 772 rewind-gap-buffer gap + 773 var g/eax: grapheme <- gap-index gap, 0 774 var x/ecx: int <- copy g - 775 check-ints-equal x, 0x62/b, "F - test-gap-index/right-2" - 776 var g/eax: grapheme <- gap-index gap, 2 + 775 check-ints-equal x, 0x61/a, "F - test-gap-index/right-1" + 776 var g/eax: grapheme <- gap-index gap, 1 777 var x/ecx: int <- copy g - 778 check-ints-equal x, 0x63/c, "F - test-gap-index/right-3" - 779 } - 780 - 781 fn copy-gap-buffer _src-ah: (addr handle gap-buffer), _dest-ah: (addr handle gap-buffer) { - 782 # obtain src-a, dest-a - 783 var src-ah/eax: (addr handle gap-buffer) <- copy _src-ah - 784 var _src-a/eax: (addr gap-buffer) <- lookup *src-ah - 785 var src-a/esi: (addr gap-buffer) <- copy _src-a - 786 var dest-ah/eax: (addr handle gap-buffer) <- copy _dest-ah - 787 var _dest-a/eax: (addr gap-buffer) <- lookup *dest-ah - 788 var dest-a/edi: (addr gap-buffer) <- copy _dest-a - 789 # copy left grapheme-stack - 790 var src/ecx: (addr grapheme-stack) <- get src-a, left - 791 var dest/edx: (addr grapheme-stack) <- get dest-a, left - 792 copy-grapheme-stack src, dest - 793 # copy right grapheme-stack - 794 src <- get src-a, right - 795 dest <- get dest-a, right - 796 copy-grapheme-stack src, dest - 797 } - 798 - 799 fn gap-buffer-is-decimal-integer? _self: (addr gap-buffer) -> _/eax: boolean { - 800 var self/esi: (addr gap-buffer) <- copy _self - 801 var curr/ecx: (addr grapheme-stack) <- get self, left - 802 var result/eax: boolean <- grapheme-stack-is-decimal-integer? curr - 803 { - 804 compare result, 0/false - 805 break-if-= - 806 curr <- get self, right - 807 result <- grapheme-stack-is-decimal-integer? curr - 808 } - 809 return result - 810 } - 811 - 812 fn test-render-gap-buffer-without-cursor { - 813 # setup - 814 var gap-storage: gap-buffer - 815 var gap/esi: (addr gap-buffer) <- address gap-storage - 816 initialize-gap-buffer-with gap, "abc" - 817 # setup: screen - 818 var screen-on-stack: screen - 819 var screen/edi: (addr screen) <- address screen-on-stack - 820 initialize-screen screen, 5, 4, 0/no-pixel-graphics - 821 # - 822 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 0/no-cursor, 3/fg, 0xc5/bg=blue-bg - 823 check-screen-row screen, 0/y, "abc ", "F - test-render-gap-buffer-without-cursor" - 824 check-ints-equal x, 4, "F - test-render-gap-buffer-without-cursor: result" - 825 # abc - 826 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-render-gap-buffer-without-cursor: bg" - 827 } - 828 - 829 fn test-render-gap-buffer-with-cursor-at-end { - 830 # setup - 831 var gap-storage: gap-buffer - 832 var gap/esi: (addr gap-buffer) <- address gap-storage - 833 initialize-gap-buffer-with gap, "abc" - 834 gap-to-end gap - 835 # setup: screen - 836 var screen-on-stack: screen - 837 var screen/edi: (addr screen) <- address screen-on-stack - 838 initialize-screen screen, 5, 4, 0/no-pixel-graphics - 839 # - 840 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg - 841 check-screen-row screen, 0/y, "abc ", "F - test-render-gap-buffer-with-cursor-at-end" - 842 # we've drawn one extra grapheme for the cursor - 843 check-ints-equal x, 4, "F - test-render-gap-buffer-with-cursor-at-end: result" - 844 # abc - 845 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " |", "F - test-render-gap-buffer-with-cursor-at-end: bg" - 846 } - 847 - 848 fn test-render-gap-buffer-with-cursor-in-middle { - 849 # setup - 850 var gap-storage: gap-buffer - 851 var gap/esi: (addr gap-buffer) <- address gap-storage - 852 initialize-gap-buffer-with gap, "abc" - 853 gap-to-end gap - 854 var dummy/eax: grapheme <- gap-left gap - 855 # setup: screen - 856 var screen-on-stack: screen - 857 var screen/edi: (addr screen) <- address screen-on-stack - 858 initialize-screen screen, 5, 4, 0/no-pixel-graphics - 859 # - 860 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg - 861 check-screen-row screen, 0/y, "abc ", "F - test-render-gap-buffer-with-cursor-in-middle" - 862 check-ints-equal x, 4, "F - test-render-gap-buffer-with-cursor-in-middle: result" - 863 # abc - 864 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-gap-buffer-with-cursor-in-middle: bg" - 865 } - 866 - 867 fn test-render-gap-buffer-with-cursor-at-start { - 868 var gap-storage: gap-buffer - 869 var gap/esi: (addr gap-buffer) <- address gap-storage - 870 initialize-gap-buffer-with gap, "abc" - 871 gap-to-start gap - 872 # setup: screen - 873 var screen-on-stack: screen - 874 var screen/edi: (addr screen) <- address screen-on-stack - 875 initialize-screen screen, 5, 4, 0/no-pixel-graphics - 876 # - 877 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg - 878 check-screen-row screen, 0/y, "abc ", "F - test-render-gap-buffer-with-cursor-at-start" - 879 check-ints-equal x, 4, "F - test-render-gap-buffer-with-cursor-at-start: result" - 880 # abc - 881 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "| ", "F - test-render-gap-buffer-with-cursor-at-start: bg" - 882 } - 883 - 884 fn test-render-gap-buffer-highlight-matching-close-paren { - 885 var gap-storage: gap-buffer - 886 var gap/esi: (addr gap-buffer) <- address gap-storage - 887 initialize-gap-buffer-with gap, "(a)" - 888 gap-to-start gap - 889 # setup: screen - 890 var screen-on-stack: screen - 891 var screen/edi: (addr screen) <- address screen-on-stack - 892 initialize-screen screen, 5, 4, 0/no-pixel-graphics - 893 # - 894 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg - 895 check-screen-row screen, 0/y, "(a) ", "F - test-render-gap-buffer-highlight-matching-close-paren" - 896 check-ints-equal x, 4, "F - test-render-gap-buffer-highlight-matching-close-paren: result" - 897 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "| ", "F - test-render-gap-buffer-highlight-matching-close-paren: cursor" - 898 check-screen-row-in-color screen, 0xf/fg=highlight, 0/y, " ) ", "F - test-render-gap-buffer-highlight-matching-close-paren: matching paren" - 899 } - 900 - 901 fn test-render-gap-buffer-highlight-matching-open-paren { - 902 var gap-storage: gap-buffer - 903 var gap/esi: (addr gap-buffer) <- address gap-storage - 904 initialize-gap-buffer-with gap, "(a)" - 905 gap-to-end gap - 906 var dummy/eax: grapheme <- gap-left gap - 907 # setup: screen - 908 var screen-on-stack: screen - 909 var screen/edi: (addr screen) <- address screen-on-stack - 910 initialize-screen screen, 5, 4, 0/no-pixel-graphics - 911 # - 912 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg - 913 check-screen-row screen, 0/y, "(a) ", "F - test-render-gap-buffer-highlight-matching-open-paren" - 914 check-ints-equal x, 4, "F - test-render-gap-buffer-highlight-matching-open-paren: result" - 915 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-gap-buffer-highlight-matching-open-paren: cursor" - 916 check-screen-row-in-color screen, 0xf/fg=highlight, 0/y, "( ", "F - test-render-gap-buffer-highlight-matching-open-paren: matching paren" - 917 } - 918 - 919 fn test-render-gap-buffer-highlight-matching-open-paren-of-end { - 920 var gap-storage: gap-buffer - 921 var gap/esi: (addr gap-buffer) <- address gap-storage - 922 initialize-gap-buffer-with gap, "(a)" - 923 gap-to-end gap - 924 # setup: screen - 925 var screen-on-stack: screen - 926 var screen/edi: (addr screen) <- address screen-on-stack - 927 initialize-screen screen, 5, 4, 0/no-pixel-graphics - 928 # - 929 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg - 930 check-screen-row screen, 0/y, "(a) ", "F - test-render-gap-buffer-highlight-matching-open-paren-of-end" - 931 check-ints-equal x, 4, "F - test-render-gap-buffer-highlight-matching-open-paren-of-end: result" - 932 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " |", "F - test-render-gap-buffer-highlight-matching-open-paren-of-end: cursor" - 933 check-screen-row-in-color screen, 0xf/fg=highlight, 0/y, "( ", "F - test-render-gap-buffer-highlight-matching-open-paren-of-end: matching paren" - 934 } - 935 - 936 # should I highlight a matching open paren? And if so, at what depth from top of left? - 937 # basically there are two cases to disambiguate here: - 938 # Usually the cursor is at top of right. Highlight first '(' at depth 0 from top of left. - 939 # If right is empty, match the ')' _before_ cursor. Highlight first '(' at depth _1_ from top of left. - 940 fn highlight-matching-open-paren? _gap: (addr gap-buffer), render-cursor?: boolean -> _/ebx: boolean, _/edi: int { - 941 # if not rendering cursor, return - 942 compare render-cursor?, 0/false - 943 { - 944 break-if-!= - 945 return 0/false, 0 - 946 } - 947 var gap/esi: (addr gap-buffer) <- copy _gap - 948 var stack/edi: (addr grapheme-stack) <- get gap, right - 949 var top-addr/eax: (addr int) <- get stack, top - 950 var top-index/ecx: int <- copy *top-addr - 951 compare top-index, 0 - 952 { - 953 break-if-> - 954 # if cursor at end, return (char before cursor == ')', 1) - 955 stack <- get gap, left - 956 top-addr <- get stack, top - 957 top-index <- copy *top-addr - 958 compare top-index, 0 - 959 { - 960 break-if-> - 961 return 0/false, 0 - 962 } - 963 top-index <- decrement - 964 var data-ah/eax: (addr handle array grapheme) <- get stack, data - 965 var data/eax: (addr array grapheme) <- lookup *data-ah - 966 var g/eax: (addr grapheme) <- index data, top-index - 967 compare *g, 0x29/close-paren - 968 { - 969 break-if-= - 970 return 0/false, 0 - 971 } - 972 return 1/true, 1 - 973 } - 974 # cursor is not at end; return (char at cursor == ')') - 975 top-index <- decrement - 976 var data-ah/eax: (addr handle array grapheme) <- get stack, data - 977 var data/eax: (addr array grapheme) <- lookup *data-ah - 978 var g/eax: (addr grapheme) <- index data, top-index - 979 compare *g, 0x29/close-paren - 980 { - 981 break-if-= - 982 return 0/false, 0 - 983 } - 984 return 1/true, 0 - 985 } - 986 - 987 fn test-highlight-matching-open-paren { - 988 var gap-storage: gap-buffer - 989 var gap/esi: (addr gap-buffer) <- address gap-storage - 990 initialize-gap-buffer-with gap, "(a)" - 991 gap-to-end gap - 992 var highlight-matching-open-paren?/ebx: boolean <- copy 0/false - 993 var open-paren-depth/edi: int <- copy 0 - 994 highlight-matching-open-paren?, open-paren-depth <- highlight-matching-open-paren? gap, 0/no-cursor - 995 check-not highlight-matching-open-paren?, "F - test-highlight-matching-open-paren: no cursor" - 996 highlight-matching-open-paren?, open-paren-depth <- highlight-matching-open-paren? gap, 1/render-cursor - 997 check highlight-matching-open-paren?, "F - test-highlight-matching-open-paren: at end immediately after ')'" - 998 check-ints-equal open-paren-depth, 1, "F - test-highlight-matching-open-paren: depth at end immediately after ')'" - 999 var dummy/eax: grapheme <- gap-left gap -1000 highlight-matching-open-paren?, open-paren-depth <- highlight-matching-open-paren? gap, 1/render-cursor -1001 check highlight-matching-open-paren?, "F - test-highlight-matching-open-paren: on ')'" -1002 dummy <- gap-left gap -1003 highlight-matching-open-paren?, open-paren-depth <- highlight-matching-open-paren? gap, 1/render-cursor -1004 check-not highlight-matching-open-paren?, "F - test-highlight-matching-open-paren: not on ')'" -1005 } -1006 -1007 ## some primitives for scanning through a gap buffer -1008 # don't modify the gap buffer while scanning -1009 # this includes moving the cursor around -1010 -1011 # restart scan without affecting gap-buffer contents -1012 fn rewind-gap-buffer _self: (addr gap-buffer) { -1013 var self/esi: (addr gap-buffer) <- copy _self -1014 var dest/eax: (addr int) <- get self, left-read-index -1015 copy-to *dest, 0 -1016 dest <- get self, right-read-index -1017 copy-to *dest, 0 -1018 } -1019 -1020 fn gap-buffer-scan-done? _self: (addr gap-buffer) -> _/eax: boolean { -1021 var self/esi: (addr gap-buffer) <- copy _self -1022 # more in left? -1023 var left/eax: (addr grapheme-stack) <- get self, left -1024 var left-size/eax: int <- grapheme-stack-length left -1025 var left-read-index/ecx: (addr int) <- get self, left-read-index -1026 compare *left-read-index, left-size -1027 { -1028 break-if->= -1029 return 0/false -1030 } -1031 # more in right? -1032 var right/eax: (addr grapheme-stack) <- get self, right -1033 var right-size/eax: int <- grapheme-stack-length right -1034 var right-read-index/ecx: (addr int) <- get self, right-read-index -1035 compare *right-read-index, right-size -1036 { -1037 break-if->= -1038 return 0/false -1039 } -1040 # -1041 return 1/true -1042 } -1043 -1044 fn peek-from-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme { -1045 var self/esi: (addr gap-buffer) <- copy _self -1046 # more in left? -1047 var left/ecx: (addr grapheme-stack) <- get self, left -1048 var left-size/eax: int <- grapheme-stack-length left -1049 var left-read-index-a/edx: (addr int) <- get self, left-read-index -1050 compare *left-read-index-a, left-size -1051 { -1052 break-if->= -1053 var left-data-ah/eax: (addr handle array grapheme) <- get left, data -1054 var left-data/eax: (addr array grapheme) <- lookup *left-data-ah -1055 var left-read-index/ecx: int <- copy *left-read-index-a -1056 var result/eax: (addr grapheme) <- index left-data, left-read-index -1057 return *result -1058 } -1059 # more in right? -1060 var right/ecx: (addr grapheme-stack) <- get self, right -1061 var _right-size/eax: int <- grapheme-stack-length right -1062 var right-size/ebx: int <- copy _right-size -1063 var right-read-index-a/edx: (addr int) <- get self, right-read-index -1064 compare *right-read-index-a, right-size -1065 { -1066 break-if->= -1067 # read the right from reverse -1068 var right-data-ah/eax: (addr handle array grapheme) <- get right, data -1069 var right-data/eax: (addr array grapheme) <- lookup *right-data-ah -1070 var right-read-index/ebx: int <- copy right-size -1071 right-read-index <- subtract *right-read-index-a -1072 right-read-index <- subtract 1 -1073 var result/eax: (addr grapheme) <- index right-data, right-read-index -1074 return *result -1075 } -1076 # if we get here there's nothing left -1077 return 0/nul -1078 } -1079 -1080 fn read-from-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme { -1081 var self/esi: (addr gap-buffer) <- copy _self -1082 # more in left? -1083 var left/ecx: (addr grapheme-stack) <- get self, left -1084 var left-size/eax: int <- grapheme-stack-length left -1085 var left-read-index-a/edx: (addr int) <- get self, left-read-index -1086 compare *left-read-index-a, left-size -1087 { -1088 break-if->= -1089 var left-data-ah/eax: (addr handle array grapheme) <- get left, data -1090 var left-data/eax: (addr array grapheme) <- lookup *left-data-ah -1091 var left-read-index/ecx: int <- copy *left-read-index-a -1092 var result/eax: (addr grapheme) <- index left-data, left-read-index -1093 increment *left-read-index-a -1094 return *result -1095 } -1096 # more in right? -1097 var right/ecx: (addr grapheme-stack) <- get self, right -1098 var _right-size/eax: int <- grapheme-stack-length right -1099 var right-size/ebx: int <- copy _right-size -1100 var right-read-index-a/edx: (addr int) <- get self, right-read-index -1101 compare *right-read-index-a, right-size -1102 { -1103 break-if->= -1104 # read the right from reverse -1105 var right-data-ah/eax: (addr handle array grapheme) <- get right, data -1106 var right-data/eax: (addr array grapheme) <- lookup *right-data-ah -1107 var right-read-index/ebx: int <- copy right-size -1108 right-read-index <- subtract *right-read-index-a -1109 right-read-index <- subtract 1 -1110 var result/eax: (addr grapheme) <- index right-data, right-read-index -1111 increment *right-read-index-a -1112 return *result -1113 } -1114 # if we get here there's nothing left -1115 return 0/nul -1116 } -1117 -1118 fn test-read-from-gap-buffer { -1119 var gap-storage: gap-buffer -1120 var gap/esi: (addr gap-buffer) <- address gap-storage -1121 initialize-gap-buffer-with gap, "abc" -1122 # gap is at end, all contents are in left -1123 var done?/eax: boolean <- gap-buffer-scan-done? gap -1124 check-not done?, "F - test-read-from-gap-buffer/left-1/done" -1125 var g/eax: grapheme <- read-from-gap-buffer gap -1126 var x/ecx: int <- copy g -1127 check-ints-equal x, 0x61/a, "F - test-read-from-gap-buffer/left-1" -1128 var done?/eax: boolean <- gap-buffer-scan-done? gap -1129 check-not done?, "F - test-read-from-gap-buffer/left-2/done" -1130 var g/eax: grapheme <- read-from-gap-buffer gap -1131 var x/ecx: int <- copy g -1132 check-ints-equal x, 0x62/b, "F - test-read-from-gap-buffer/left-2" -1133 var done?/eax: boolean <- gap-buffer-scan-done? gap -1134 check-not done?, "F - test-read-from-gap-buffer/left-3/done" -1135 var g/eax: grapheme <- read-from-gap-buffer gap -1136 var x/ecx: int <- copy g -1137 check-ints-equal x, 0x63/c, "F - test-read-from-gap-buffer/left-3" -1138 var done?/eax: boolean <- gap-buffer-scan-done? gap -1139 check done?, "F - test-read-from-gap-buffer/left-4/done" -1140 var g/eax: grapheme <- read-from-gap-buffer gap -1141 var x/ecx: int <- copy g -1142 check-ints-equal x, 0/nul, "F - test-read-from-gap-buffer/left-4" -1143 # now check when everything is to the right -1144 gap-to-start gap -1145 rewind-gap-buffer gap -1146 var done?/eax: boolean <- gap-buffer-scan-done? gap -1147 check-not done?, "F - test-read-from-gap-buffer/right-1/done" -1148 var g/eax: grapheme <- read-from-gap-buffer gap -1149 var x/ecx: int <- copy g -1150 check-ints-equal x, 0x61/a, "F - test-read-from-gap-buffer/right-1" -1151 var done?/eax: boolean <- gap-buffer-scan-done? gap -1152 check-not done?, "F - test-read-from-gap-buffer/right-2/done" -1153 var g/eax: grapheme <- read-from-gap-buffer gap -1154 var x/ecx: int <- copy g -1155 check-ints-equal x, 0x62/b, "F - test-read-from-gap-buffer/right-2" -1156 var done?/eax: boolean <- gap-buffer-scan-done? gap -1157 check-not done?, "F - test-read-from-gap-buffer/right-3/done" -1158 var g/eax: grapheme <- read-from-gap-buffer gap -1159 var x/ecx: int <- copy g -1160 check-ints-equal x, 0x63/c, "F - test-read-from-gap-buffer/right-3" -1161 var done?/eax: boolean <- gap-buffer-scan-done? gap -1162 check done?, "F - test-read-from-gap-buffer/right-4/done" -1163 var g/eax: grapheme <- read-from-gap-buffer gap -1164 var x/ecx: int <- copy g -1165 check-ints-equal x, 0/nul, "F - test-read-from-gap-buffer/right-4" -1166 } -1167 -1168 fn skip-whitespace-from-gap-buffer self: (addr gap-buffer) { -1169 var done?/eax: boolean <- gap-buffer-scan-done? self -1170 compare done?, 0/false -1171 break-if-!= -1172 var g/eax: grapheme <- peek-from-gap-buffer self -1173 { -1174 compare g, 0x20/space -1175 break-if-= -1176 compare g, 0xa/newline -1177 break-if-= -1178 return -1179 } -1180 g <- read-from-gap-buffer self -1181 loop -1182 } -1183 -1184 fn edit-gap-buffer self: (addr gap-buffer), key: grapheme { -1185 var g/edx: grapheme <- copy key -1186 { -1187 compare g, 8/backspace -1188 break-if-!= -1189 delete-before-gap self -1190 return -1191 } -1192 { -1193 compare g, 0x80/left-arrow -1194 break-if-!= -1195 var dummy/eax: grapheme <- gap-left self -1196 return -1197 } -1198 { -1199 compare g, 0x83/right-arrow -1200 break-if-!= -1201 var dummy/eax: grapheme <- gap-right self -1202 return -1203 } -1204 { -1205 compare g, 6/ctrl-f -1206 break-if-!= -1207 gap-to-start-of-next-word self -1208 return -1209 } -1210 { -1211 compare g, 2/ctrl-b -1212 break-if-!= -1213 gap-to-end-of-previous-word self -1214 return -1215 } -1216 { -1217 compare g, 1/ctrl-a -1218 break-if-!= -1219 gap-to-previous-start-of-line self -1220 return -1221 } -1222 { -1223 compare g, 5/ctrl-e -1224 break-if-!= -1225 gap-to-next-end-of-line self -1226 return -1227 } -1228 { -1229 compare g, 0x81/down-arrow -1230 break-if-!= -1231 gap-down self -1232 return -1233 } -1234 { -1235 compare g, 0x82/up-arrow -1236 break-if-!= -1237 gap-up self -1238 return -1239 } -1240 { -1241 compare g, 0x15/ctrl-u -1242 break-if-!= -1243 clear-gap-buffer self -1244 return -1245 } -1246 { -1247 compare g, 9/tab -1248 break-if-!= -1249 # tab = 2 spaces -1250 add-code-point-at-gap self, 0x20/space -1251 add-code-point-at-gap self, 0x20/space -1252 return -1253 } -1254 # default: insert character -1255 add-grapheme-at-gap self, g -1256 } -1257 -1258 fn gap-to-start-of-next-word self: (addr gap-buffer) { -1259 var curr/eax: grapheme <- copy 0 -1260 # skip to next space -1261 { -1262 curr <- gap-right self -1263 compare curr, -1 -1264 break-if-= -1265 compare curr, 0x20/space -1266 break-if-= -1267 compare curr, 0xa/newline -1268 break-if-= -1269 loop -1270 } -1271 # skip past spaces -1272 { -1273 curr <- gap-right self -1274 compare curr, -1 -1275 break-if-= -1276 compare curr, 0x20/space -1277 loop-if-= -1278 compare curr, 0xa/space -1279 loop-if-= -1280 curr <- gap-left self -1281 break -1282 } -1283 } -1284 -1285 fn gap-to-end-of-previous-word self: (addr gap-buffer) { -1286 var curr/eax: grapheme <- copy 0 -1287 # skip to previous space -1288 { -1289 curr <- gap-left self -1290 compare curr, -1 -1291 break-if-= -1292 compare curr, 0x20/space -1293 break-if-= -1294 compare curr, 0xa/newline -1295 break-if-= -1296 loop -1297 } -1298 # skip past all spaces but one -1299 { -1300 curr <- gap-left self -1301 compare curr, -1 -1302 break-if-= -1303 compare curr, 0x20/space -1304 loop-if-= -1305 compare curr, 0xa/space -1306 loop-if-= -1307 curr <- gap-right self -1308 break -1309 } -1310 } -1311 -1312 fn gap-to-previous-start-of-line self: (addr gap-buffer) { -1313 # skip past immediate newline -1314 var dummy/eax: grapheme <- gap-left self -1315 # skip to previous newline -1316 { -1317 dummy <- gap-left self -1318 { -1319 compare dummy, -1 -1320 break-if-!= -1321 return -1322 } -1323 { -1324 compare dummy, 0xa/newline -1325 break-if-!= -1326 dummy <- gap-right self -1327 return -1328 } -1329 loop -1330 } -1331 } -1332 -1333 fn gap-to-next-end-of-line self: (addr gap-buffer) { -1334 # skip past immediate newline -1335 var dummy/eax: grapheme <- gap-right self -1336 # skip to next newline -1337 { -1338 dummy <- gap-right self -1339 { -1340 compare dummy, -1 -1341 break-if-!= -1342 return -1343 } -1344 { -1345 compare dummy, 0xa/newline -1346 break-if-!= -1347 dummy <- gap-left self -1348 return -1349 } -1350 loop -1351 } -1352 } -1353 -1354 fn gap-up self: (addr gap-buffer) { -1355 # compute column -1356 var col/edx: int <- count-columns-to-start-of-line self -1357 # -1358 gap-to-previous-start-of-line self -1359 # skip ahead by up to col on previous line -1360 var i/ecx: int <- copy 0 -1361 { -1362 compare i, col -1363 break-if->= -1364 var curr/eax: grapheme <- gap-right self -1365 { -1366 compare curr, -1 -1367 break-if-!= -1368 return -1369 } -1370 compare curr, 0xa/newline -1371 { -1372 break-if-!= -1373 curr <- gap-left self -1374 return -1375 } -1376 i <- increment -1377 loop -1378 } -1379 } -1380 -1381 fn gap-down self: (addr gap-buffer) { -1382 # compute column -1383 var col/edx: int <- count-columns-to-start-of-line self -1384 # skip to start of next line -1385 gap-to-end-of-line self -1386 var dummy/eax: grapheme <- gap-right self -1387 # skip ahead by up to col on previous line -1388 var i/ecx: int <- copy 0 -1389 { -1390 compare i, col -1391 break-if->= -1392 var curr/eax: grapheme <- gap-right self + 778 check-ints-equal x, 0x62/b, "F - test-gap-index/right-2" + 779 var g/eax: grapheme <- gap-index gap, 2 + 780 var x/ecx: int <- copy g + 781 check-ints-equal x, 0x63/c, "F - test-gap-index/right-3" + 782 } + 783 + 784 fn copy-gap-buffer _src-ah: (addr handle gap-buffer), _dest-ah: (addr handle gap-buffer) { + 785 # obtain src-a, dest-a + 786 var src-ah/eax: (addr handle gap-buffer) <- copy _src-ah + 787 var _src-a/eax: (addr gap-buffer) <- lookup *src-ah + 788 var src-a/esi: (addr gap-buffer) <- copy _src-a + 789 var dest-ah/eax: (addr handle gap-buffer) <- copy _dest-ah + 790 var _dest-a/eax: (addr gap-buffer) <- lookup *dest-ah + 791 var dest-a/edi: (addr gap-buffer) <- copy _dest-a + 792 # copy left grapheme-stack + 793 var src/ecx: (addr grapheme-stack) <- get src-a, left + 794 var dest/edx: (addr grapheme-stack) <- get dest-a, left + 795 copy-grapheme-stack src, dest + 796 # copy right grapheme-stack + 797 src <- get src-a, right + 798 dest <- get dest-a, right + 799 copy-grapheme-stack src, dest + 800 } + 801 + 802 fn gap-buffer-is-decimal-integer? _self: (addr gap-buffer) -> _/eax: boolean { + 803 var self/esi: (addr gap-buffer) <- copy _self + 804 var curr/ecx: (addr grapheme-stack) <- get self, left + 805 var result/eax: boolean <- grapheme-stack-is-decimal-integer? curr + 806 { + 807 compare result, 0/false + 808 break-if-= + 809 curr <- get self, right + 810 result <- grapheme-stack-is-decimal-integer? curr + 811 } + 812 return result + 813 } + 814 + 815 fn test-render-gap-buffer-without-cursor { + 816 # setup + 817 var gap-storage: gap-buffer + 818 var gap/esi: (addr gap-buffer) <- address gap-storage + 819 initialize-gap-buffer-with gap, "abc" + 820 # setup: screen + 821 var screen-on-stack: screen + 822 var screen/edi: (addr screen) <- address screen-on-stack + 823 initialize-screen screen, 5, 4, 0/no-pixel-graphics + 824 # + 825 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 0/no-cursor, 3/fg, 0xc5/bg=blue-bg + 826 check-screen-row screen, 0/y, "abc ", "F - test-render-gap-buffer-without-cursor" + 827 check-ints-equal x, 4, "F - test-render-gap-buffer-without-cursor: result" + 828 # abc + 829 check-background-color-in-screen-row screen, 3/bg=reverse, 0/y, " ", "F - test-render-gap-buffer-without-cursor: bg" + 830 } + 831 + 832 fn test-render-gap-buffer-with-cursor-at-end { + 833 # setup + 834 var gap-storage: gap-buffer + 835 var gap/esi: (addr gap-buffer) <- address gap-storage + 836 initialize-gap-buffer-with gap, "abc" + 837 gap-to-end gap + 838 # setup: screen + 839 var screen-on-stack: screen + 840 var screen/edi: (addr screen) <- address screen-on-stack + 841 initialize-screen screen, 5, 4, 0/no-pixel-graphics + 842 # + 843 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg + 844 check-screen-row screen, 0/y, "abc ", "F - test-render-gap-buffer-with-cursor-at-end" + 845 # we've drawn one extra grapheme for the cursor + 846 check-ints-equal x, 4, "F - test-render-gap-buffer-with-cursor-at-end: result" + 847 # abc + 848 check-background-color-in-screen-row screen, 3/bg=reverse, 0/y, " |", "F - test-render-gap-buffer-with-cursor-at-end: bg" + 849 } + 850 + 851 fn test-render-gap-buffer-with-cursor-in-middle { + 852 # setup + 853 var gap-storage: gap-buffer + 854 var gap/esi: (addr gap-buffer) <- address gap-storage + 855 initialize-gap-buffer-with gap, "abc" + 856 gap-to-end gap + 857 var dummy/eax: grapheme <- gap-left gap + 858 # setup: screen + 859 var screen-on-stack: screen + 860 var screen/edi: (addr screen) <- address screen-on-stack + 861 initialize-screen screen, 5, 4, 0/no-pixel-graphics + 862 # + 863 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg + 864 check-screen-row screen, 0/y, "abc ", "F - test-render-gap-buffer-with-cursor-in-middle" + 865 check-ints-equal x, 4, "F - test-render-gap-buffer-with-cursor-in-middle: result" + 866 # abc + 867 check-background-color-in-screen-row screen, 3/bg=reverse, 0/y, " | ", "F - test-render-gap-buffer-with-cursor-in-middle: bg" + 868 } + 869 + 870 fn test-render-gap-buffer-with-cursor-at-start { + 871 var gap-storage: gap-buffer + 872 var gap/esi: (addr gap-buffer) <- address gap-storage + 873 initialize-gap-buffer-with gap, "abc" + 874 gap-to-start gap + 875 # setup: screen + 876 var screen-on-stack: screen + 877 var screen/edi: (addr screen) <- address screen-on-stack + 878 initialize-screen screen, 5, 4, 0/no-pixel-graphics + 879 # + 880 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg + 881 check-screen-row screen, 0/y, "abc ", "F - test-render-gap-buffer-with-cursor-at-start" + 882 check-ints-equal x, 4, "F - test-render-gap-buffer-with-cursor-at-start: result" + 883 # abc + 884 check-background-color-in-screen-row screen, 3/bg=reverse, 0/y, "| ", "F - test-render-gap-buffer-with-cursor-at-start: bg" + 885 } + 886 + 887 fn test-render-gap-buffer-highlight-matching-close-paren { + 888 var gap-storage: gap-buffer + 889 var gap/esi: (addr gap-buffer) <- address gap-storage + 890 initialize-gap-buffer-with gap, "(a)" + 891 gap-to-start gap + 892 # setup: screen + 893 var screen-on-stack: screen + 894 var screen/edi: (addr screen) <- address screen-on-stack + 895 initialize-screen screen, 5, 4, 0/no-pixel-graphics + 896 # + 897 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg + 898 check-screen-row screen, 0/y, "(a) ", "F - test-render-gap-buffer-highlight-matching-close-paren" + 899 check-ints-equal x, 4, "F - test-render-gap-buffer-highlight-matching-close-paren: result" + 900 check-background-color-in-screen-row screen, 3/bg=reverse, 0/y, "| ", "F - test-render-gap-buffer-highlight-matching-close-paren: cursor" + 901 check-screen-row-in-color screen, 0xf/fg=highlight, 0/y, " ) ", "F - test-render-gap-buffer-highlight-matching-close-paren: matching paren" + 902 } + 903 + 904 fn test-render-gap-buffer-highlight-matching-open-paren { + 905 var gap-storage: gap-buffer + 906 var gap/esi: (addr gap-buffer) <- address gap-storage + 907 initialize-gap-buffer-with gap, "(a)" + 908 gap-to-end gap + 909 var dummy/eax: grapheme <- gap-left gap + 910 # setup: screen + 911 var screen-on-stack: screen + 912 var screen/edi: (addr screen) <- address screen-on-stack + 913 initialize-screen screen, 5, 4, 0/no-pixel-graphics + 914 # + 915 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg + 916 check-screen-row screen, 0/y, "(a) ", "F - test-render-gap-buffer-highlight-matching-open-paren" + 917 check-ints-equal x, 4, "F - test-render-gap-buffer-highlight-matching-open-paren: result" + 918 check-background-color-in-screen-row screen, 3/bg=reverse, 0/y, " | ", "F - test-render-gap-buffer-highlight-matching-open-paren: cursor" + 919 check-screen-row-in-color screen, 0xf/fg=highlight, 0/y, "( ", "F - test-render-gap-buffer-highlight-matching-open-paren: matching paren" + 920 } + 921 + 922 fn test-render-gap-buffer-highlight-matching-open-paren-of-end { + 923 var gap-storage: gap-buffer + 924 var gap/esi: (addr gap-buffer) <- address gap-storage + 925 initialize-gap-buffer-with gap, "(a)" + 926 gap-to-end gap + 927 # setup: screen + 928 var screen-on-stack: screen + 929 var screen/edi: (addr screen) <- address screen-on-stack + 930 initialize-screen screen, 5, 4, 0/no-pixel-graphics + 931 # + 932 var x/eax: int <- render-gap-buffer screen, gap, 0/x, 0/y, 1/show-cursor, 3/fg, 0xc5/bg=blue-bg + 933 check-screen-row screen, 0/y, "(a) ", "F - test-render-gap-buffer-highlight-matching-open-paren-of-end" + 934 check-ints-equal x, 4, "F - test-render-gap-buffer-highlight-matching-open-paren-of-end: result" + 935 check-background-color-in-screen-row screen, 3/bg=reverse, 0/y, " |", "F - test-render-gap-buffer-highlight-matching-open-paren-of-end: cursor" + 936 check-screen-row-in-color screen, 0xf/fg=highlight, 0/y, "( ", "F - test-render-gap-buffer-highlight-matching-open-paren-of-end: matching paren" + 937 } + 938 + 939 # should I highlight a matching open paren? And if so, at what depth from top of left? + 940 # basically there are two cases to disambiguate here: + 941 # Usually the cursor is at top of right. Highlight first '(' at depth 0 from top of left. + 942 # If right is empty, match the ')' _before_ cursor. Highlight first '(' at depth _1_ from top of left. + 943 fn highlight-matching-open-paren? _gap: (addr gap-buffer), render-cursor?: boolean -> _/ebx: boolean, _/edi: int { + 944 # if not rendering cursor, return + 945 compare render-cursor?, 0/false + 946 { + 947 break-if-!= + 948 return 0/false, 0 + 949 } + 950 var gap/esi: (addr gap-buffer) <- copy _gap + 951 var stack/edi: (addr grapheme-stack) <- get gap, right + 952 var top-addr/eax: (addr int) <- get stack, top + 953 var top-index/ecx: int <- copy *top-addr + 954 compare top-index, 0 + 955 { + 956 break-if-> + 957 # if cursor at end, return (char before cursor == ')', 1) + 958 stack <- get gap, left + 959 top-addr <- get stack, top + 960 top-index <- copy *top-addr + 961 compare top-index, 0 + 962 { + 963 break-if-> + 964 return 0/false, 0 + 965 } + 966 top-index <- decrement + 967 var data-ah/eax: (addr handle array grapheme) <- get stack, data + 968 var data/eax: (addr array grapheme) <- lookup *data-ah + 969 var g/eax: (addr grapheme) <- index data, top-index + 970 compare *g, 0x29/close-paren + 971 { + 972 break-if-= + 973 return 0/false, 0 + 974 } + 975 return 1/true, 1 + 976 } + 977 # cursor is not at end; return (char at cursor == ')') + 978 top-index <- decrement + 979 var data-ah/eax: (addr handle array grapheme) <- get stack, data + 980 var data/eax: (addr array grapheme) <- lookup *data-ah + 981 var g/eax: (addr grapheme) <- index data, top-index + 982 compare *g, 0x29/close-paren + 983 { + 984 break-if-= + 985 return 0/false, 0 + 986 } + 987 return 1/true, 0 + 988 } + 989 + 990 fn test-highlight-matching-open-paren { + 991 var gap-storage: gap-buffer + 992 var gap/esi: (addr gap-buffer) <- address gap-storage + 993 initialize-gap-buffer-with gap, "(a)" + 994 gap-to-end gap + 995 var highlight-matching-open-paren?/ebx: boolean <- copy 0/false + 996 var open-paren-depth/edi: int <- copy 0 + 997 highlight-matching-open-paren?, open-paren-depth <- highlight-matching-open-paren? gap, 0/no-cursor + 998 check-not highlight-matching-open-paren?, "F - test-highlight-matching-open-paren: no cursor" + 999 highlight-matching-open-paren?, open-paren-depth <- highlight-matching-open-paren? gap, 1/render-cursor +1000 check highlight-matching-open-paren?, "F - test-highlight-matching-open-paren: at end immediately after ')'" +1001 check-ints-equal open-paren-depth, 1, "F - test-highlight-matching-open-paren: depth at end immediately after ')'" +1002 var dummy/eax: grapheme <- gap-left gap +1003 highlight-matching-open-paren?, open-paren-depth <- highlight-matching-open-paren? gap, 1/render-cursor +1004 check highlight-matching-open-paren?, "F - test-highlight-matching-open-paren: on ')'" +1005 dummy <- gap-left gap +1006 highlight-matching-open-paren?, open-paren-depth <- highlight-matching-open-paren? gap, 1/render-cursor +1007 check-not highlight-matching-open-paren?, "F - test-highlight-matching-open-paren: not on ')'" +1008 } +1009 +1010 ## some primitives for scanning through a gap buffer +1011 # don't modify the gap buffer while scanning +1012 # this includes moving the cursor around +1013 +1014 # restart scan without affecting gap-buffer contents +1015 fn rewind-gap-buffer _self: (addr gap-buffer) { +1016 var self/esi: (addr gap-buffer) <- copy _self +1017 var dest/eax: (addr int) <- get self, left-read-index +1018 copy-to *dest, 0 +1019 dest <- get self, right-read-index +1020 copy-to *dest, 0 +1021 } +1022 +1023 fn gap-buffer-scan-done? _self: (addr gap-buffer) -> _/eax: boolean { +1024 var self/esi: (addr gap-buffer) <- copy _self +1025 # more in left? +1026 var left/eax: (addr grapheme-stack) <- get self, left +1027 var left-size/eax: int <- grapheme-stack-length left +1028 var left-read-index/ecx: (addr int) <- get self, left-read-index +1029 compare *left-read-index, left-size +1030 { +1031 break-if->= +1032 return 0/false +1033 } +1034 # more in right? +1035 var right/eax: (addr grapheme-stack) <- get self, right +1036 var right-size/eax: int <- grapheme-stack-length right +1037 var right-read-index/ecx: (addr int) <- get self, right-read-index +1038 compare *right-read-index, right-size +1039 { +1040 break-if->= +1041 return 0/false +1042 } +1043 # +1044 return 1/true +1045 } +1046 +1047 fn peek-from-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme { +1048 var self/esi: (addr gap-buffer) <- copy _self +1049 # more in left? +1050 var left/ecx: (addr grapheme-stack) <- get self, left +1051 var left-size/eax: int <- grapheme-stack-length left +1052 var left-read-index-a/edx: (addr int) <- get self, left-read-index +1053 compare *left-read-index-a, left-size +1054 { +1055 break-if->= +1056 var left-data-ah/eax: (addr handle array grapheme) <- get left, data +1057 var left-data/eax: (addr array grapheme) <- lookup *left-data-ah +1058 var left-read-index/ecx: int <- copy *left-read-index-a +1059 var result/eax: (addr grapheme) <- index left-data, left-read-index +1060 return *result +1061 } +1062 # more in right? +1063 var right/ecx: (addr grapheme-stack) <- get self, right +1064 var _right-size/eax: int <- grapheme-stack-length right +1065 var right-size/ebx: int <- copy _right-size +1066 var right-read-index-a/edx: (addr int) <- get self, right-read-index +1067 compare *right-read-index-a, right-size +1068 { +1069 break-if->= +1070 # read the right from reverse +1071 var right-data-ah/eax: (addr handle array grapheme) <- get right, data +1072 var right-data/eax: (addr array grapheme) <- lookup *right-data-ah +1073 var right-read-index/ebx: int <- copy right-size +1074 right-read-index <- subtract *right-read-index-a +1075 right-read-index <- subtract 1 +1076 var result/eax: (addr grapheme) <- index right-data, right-read-index +1077 return *result +1078 } +1079 # if we get here there's nothing left +1080 return 0/nul +1081 } +1082 +1083 fn read-from-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme { +1084 var self/esi: (addr gap-buffer) <- copy _self +1085 # more in left? +1086 var left/ecx: (addr grapheme-stack) <- get self, left +1087 var left-size/eax: int <- grapheme-stack-length left +1088 var left-read-index-a/edx: (addr int) <- get self, left-read-index +1089 compare *left-read-index-a, left-size +1090 { +1091 break-if->= +1092 var left-data-ah/eax: (addr handle array grapheme) <- get left, data +1093 var left-data/eax: (addr array grapheme) <- lookup *left-data-ah +1094 var left-read-index/ecx: int <- copy *left-read-index-a +1095 var result/eax: (addr grapheme) <- index left-data, left-read-index +1096 increment *left-read-index-a +1097 return *result +1098 } +1099 # more in right? +1100 var right/ecx: (addr grapheme-stack) <- get self, right +1101 var _right-size/eax: int <- grapheme-stack-length right +1102 var right-size/ebx: int <- copy _right-size +1103 var right-read-index-a/edx: (addr int) <- get self, right-read-index +1104 compare *right-read-index-a, right-size +1105 { +1106 break-if->= +1107 # read the right from reverse +1108 var right-data-ah/eax: (addr handle array grapheme) <- get right, data +1109 var right-data/eax: (addr array grapheme) <- lookup *right-data-ah +1110 var right-read-index/ebx: int <- copy right-size +1111 right-read-index <- subtract *right-read-index-a +1112 right-read-index <- subtract 1 +1113 var result/eax: (addr grapheme) <- index right-data, right-read-index +1114 increment *right-read-index-a +1115 return *result +1116 } +1117 # if we get here there's nothing left +1118 return 0/nul +1119 } +1120 +1121 fn put-back-from-gap-buffer _self: (addr gap-buffer) { +1122 var self/esi: (addr gap-buffer) <- copy _self +1123 # more in right? +1124 var right/eax: (addr grapheme-stack) <- get self, right +1125 var right-size/eax: int <- grapheme-stack-length right +1126 var right-read-index-a/eax: (addr int) <- get self, right-read-index +1127 compare *right-read-index-a, 0 +1128 { +1129 break-if-<= +1130 decrement *right-read-index-a +1131 return +1132 } +1133 # more in left? +1134 var left/eax: (addr grapheme-stack) <- get self, left +1135 var left-size/eax: int <- grapheme-stack-length left +1136 var left-read-index-a/eax: (addr int) <- get self, left-read-index +1137 decrement *left-read-index-a +1138 } +1139 +1140 fn test-read-from-gap-buffer { +1141 var gap-storage: gap-buffer +1142 var gap/esi: (addr gap-buffer) <- address gap-storage +1143 initialize-gap-buffer-with gap, "abc" +1144 # gap is at end, all contents are in left +1145 var done?/eax: boolean <- gap-buffer-scan-done? gap +1146 check-not done?, "F - test-read-from-gap-buffer/left-1/done" +1147 var g/eax: grapheme <- read-from-gap-buffer gap +1148 var x/ecx: int <- copy g +1149 check-ints-equal x, 0x61/a, "F - test-read-from-gap-buffer/left-1" +1150 var done?/eax: boolean <- gap-buffer-scan-done? gap +1151 check-not done?, "F - test-read-from-gap-buffer/left-2/done" +1152 var g/eax: grapheme <- read-from-gap-buffer gap +1153 var x/ecx: int <- copy g +1154 check-ints-equal x, 0x62/b, "F - test-read-from-gap-buffer/left-2" +1155 var done?/eax: boolean <- gap-buffer-scan-done? gap +1156 check-not done?, "F - test-read-from-gap-buffer/left-3/done" +1157 var g/eax: grapheme <- read-from-gap-buffer gap +1158 var x/ecx: int <- copy g +1159 check-ints-equal x, 0x63/c, "F - test-read-from-gap-buffer/left-3" +1160 var done?/eax: boolean <- gap-buffer-scan-done? gap +1161 check done?, "F - test-read-from-gap-buffer/left-4/done" +1162 var g/eax: grapheme <- read-from-gap-buffer gap +1163 var x/ecx: int <- copy g +1164 check-ints-equal x, 0/nul, "F - test-read-from-gap-buffer/left-4" +1165 # now check when everything is to the right +1166 gap-to-start gap +1167 rewind-gap-buffer gap +1168 var done?/eax: boolean <- gap-buffer-scan-done? gap +1169 check-not done?, "F - test-read-from-gap-buffer/right-1/done" +1170 var g/eax: grapheme <- read-from-gap-buffer gap +1171 var x/ecx: int <- copy g +1172 check-ints-equal x, 0x61/a, "F - test-read-from-gap-buffer/right-1" +1173 var done?/eax: boolean <- gap-buffer-scan-done? gap +1174 check-not done?, "F - test-read-from-gap-buffer/right-2/done" +1175 var g/eax: grapheme <- read-from-gap-buffer gap +1176 var x/ecx: int <- copy g +1177 check-ints-equal x, 0x62/b, "F - test-read-from-gap-buffer/right-2" +1178 var done?/eax: boolean <- gap-buffer-scan-done? gap +1179 check-not done?, "F - test-read-from-gap-buffer/right-3/done" +1180 var g/eax: grapheme <- read-from-gap-buffer gap +1181 var x/ecx: int <- copy g +1182 check-ints-equal x, 0x63/c, "F - test-read-from-gap-buffer/right-3" +1183 var done?/eax: boolean <- gap-buffer-scan-done? gap +1184 check done?, "F - test-read-from-gap-buffer/right-4/done" +1185 var g/eax: grapheme <- read-from-gap-buffer gap +1186 var x/ecx: int <- copy g +1187 check-ints-equal x, 0/nul, "F - test-read-from-gap-buffer/right-4" +1188 } +1189 +1190 fn skip-whitespace-from-gap-buffer self: (addr gap-buffer) { +1191 var done?/eax: boolean <- gap-buffer-scan-done? self +1192 compare done?, 0/false +1193 break-if-!= +1194 var g/eax: grapheme <- peek-from-gap-buffer self +1195 { +1196 compare g, 0x20/space +1197 break-if-= +1198 compare g, 0xa/newline +1199 break-if-= +1200 return +1201 } +1202 g <- read-from-gap-buffer self +1203 loop +1204 } +1205 +1206 fn edit-gap-buffer self: (addr gap-buffer), key: grapheme { +1207 var g/edx: grapheme <- copy key +1208 { +1209 compare g, 8/backspace +1210 break-if-!= +1211 delete-before-gap self +1212 return +1213 } +1214 { +1215 compare g, 0x80/left-arrow +1216 break-if-!= +1217 var dummy/eax: grapheme <- gap-left self +1218 return +1219 } +1220 { +1221 compare g, 0x83/right-arrow +1222 break-if-!= +1223 var dummy/eax: grapheme <- gap-right self +1224 return +1225 } +1226 { +1227 compare g, 6/ctrl-f +1228 break-if-!= +1229 gap-to-start-of-next-word self +1230 return +1231 } +1232 { +1233 compare g, 2/ctrl-b +1234 break-if-!= +1235 gap-to-end-of-previous-word self +1236 return +1237 } +1238 { +1239 compare g, 1/ctrl-a +1240 break-if-!= +1241 gap-to-previous-start-of-line self +1242 return +1243 } +1244 { +1245 compare g, 5/ctrl-e +1246 break-if-!= +1247 gap-to-next-end-of-line self +1248 return +1249 } +1250 { +1251 compare g, 0x81/down-arrow +1252 break-if-!= +1253 gap-down self +1254 return +1255 } +1256 { +1257 compare g, 0x82/up-arrow +1258 break-if-!= +1259 gap-up self +1260 return +1261 } +1262 { +1263 compare g, 0x15/ctrl-u +1264 break-if-!= +1265 clear-gap-buffer self +1266 return +1267 } +1268 { +1269 compare g, 9/tab +1270 break-if-!= +1271 # tab = 2 spaces +1272 add-code-point-at-gap self, 0x20/space +1273 add-code-point-at-gap self, 0x20/space +1274 return +1275 } +1276 # default: insert character +1277 add-grapheme-at-gap self, g +1278 } +1279 +1280 fn gap-to-start-of-next-word self: (addr gap-buffer) { +1281 var curr/eax: grapheme <- copy 0 +1282 # skip to next space +1283 { +1284 curr <- gap-right self +1285 compare curr, -1 +1286 break-if-= +1287 compare curr, 0x20/space +1288 break-if-= +1289 compare curr, 0xa/newline +1290 break-if-= +1291 loop +1292 } +1293 # skip past spaces +1294 { +1295 curr <- gap-right self +1296 compare curr, -1 +1297 break-if-= +1298 compare curr, 0x20/space +1299 loop-if-= +1300 compare curr, 0xa/space +1301 loop-if-= +1302 curr <- gap-left self +1303 break +1304 } +1305 } +1306 +1307 fn gap-to-end-of-previous-word self: (addr gap-buffer) { +1308 var curr/eax: grapheme <- copy 0 +1309 # skip to previous space +1310 { +1311 curr <- gap-left self +1312 compare curr, -1 +1313 break-if-= +1314 compare curr, 0x20/space +1315 break-if-= +1316 compare curr, 0xa/newline +1317 break-if-= +1318 loop +1319 } +1320 # skip past all spaces but one +1321 { +1322 curr <- gap-left self +1323 compare curr, -1 +1324 break-if-= +1325 compare curr, 0x20/space +1326 loop-if-= +1327 compare curr, 0xa/space +1328 loop-if-= +1329 curr <- gap-right self +1330 break +1331 } +1332 } +1333 +1334 fn gap-to-previous-start-of-line self: (addr gap-buffer) { +1335 # skip past immediate newline +1336 var dummy/eax: grapheme <- gap-left self +1337 # skip to previous newline +1338 { +1339 dummy <- gap-left self +1340 { +1341 compare dummy, -1 +1342 break-if-!= +1343 return +1344 } +1345 { +1346 compare dummy, 0xa/newline +1347 break-if-!= +1348 dummy <- gap-right self +1349 return +1350 } +1351 loop +1352 } +1353 } +1354 +1355 fn gap-to-next-end-of-line self: (addr gap-buffer) { +1356 # skip past immediate newline +1357 var dummy/eax: grapheme <- gap-right self +1358 # skip to next newline +1359 { +1360 dummy <- gap-right self +1361 { +1362 compare dummy, -1 +1363 break-if-!= +1364 return +1365 } +1366 { +1367 compare dummy, 0xa/newline +1368 break-if-!= +1369 dummy <- gap-left self +1370 return +1371 } +1372 loop +1373 } +1374 } +1375 +1376 fn gap-up self: (addr gap-buffer) { +1377 # compute column +1378 var col/edx: int <- count-columns-to-start-of-line self +1379 # +1380 gap-to-previous-start-of-line self +1381 # skip ahead by up to col on previous line +1382 var i/ecx: int <- copy 0 +1383 { +1384 compare i, col +1385 break-if->= +1386 var curr/eax: grapheme <- gap-right self +1387 { +1388 compare curr, -1 +1389 break-if-!= +1390 return +1391 } +1392 compare curr, 0xa/newline 1393 { -1394 compare curr, -1 -1395 break-if-!= +1394 break-if-!= +1395 curr <- gap-left self 1396 return 1397 } -1398 compare curr, 0xa/newline -1399 { -1400 break-if-!= -1401 curr <- gap-left self -1402 return -1403 } -1404 i <- increment -1405 loop -1406 } -1407 } -1408 -1409 fn count-columns-to-start-of-line self: (addr gap-buffer) -> _/edx: int { -1410 var count/edx: int <- copy 0 -1411 var dummy/eax: grapheme <- copy 0 -1412 # skip to previous newline -1413 { -1414 dummy <- gap-left self +1398 i <- increment +1399 loop +1400 } +1401 } +1402 +1403 fn gap-down self: (addr gap-buffer) { +1404 # compute column +1405 var col/edx: int <- count-columns-to-start-of-line self +1406 # skip to start of next line +1407 gap-to-end-of-line self +1408 var dummy/eax: grapheme <- gap-right self +1409 # skip ahead by up to col on previous line +1410 var i/ecx: int <- copy 0 +1411 { +1412 compare i, col +1413 break-if->= +1414 var curr/eax: grapheme <- gap-right self 1415 { -1416 compare dummy, -1 +1416 compare curr, -1 1417 break-if-!= -1418 return count +1418 return 1419 } -1420 { -1421 compare dummy, 0xa/newline +1420 compare curr, 0xa/newline +1421 { 1422 break-if-!= -1423 dummy <- gap-right self -1424 return count +1423 curr <- gap-left self +1424 return 1425 } -1426 count <- increment +1426 i <- increment 1427 loop 1428 } -1429 return count -1430 } -1431 -1432 fn gap-to-end-of-line self: (addr gap-buffer) { +1429 } +1430 +1431 fn count-columns-to-start-of-line self: (addr gap-buffer) -> _/edx: int { +1432 var count/edx: int <- copy 0 1433 var dummy/eax: grapheme <- copy 0 -1434 # skip to next newline +1434 # skip to previous newline 1435 { -1436 dummy <- gap-right self +1436 dummy <- gap-left self 1437 { 1438 compare dummy, -1 1439 break-if-!= -1440 return +1440 return count 1441 } 1442 { 1443 compare dummy, 0xa/newline 1444 break-if-!= -1445 dummy <- gap-left self -1446 return +1445 dummy <- gap-right self +1446 return count 1447 } -1448 loop -1449 } -1450 } +1448 count <- increment +1449 loop +1450 } +1451 return count +1452 } +1453 +1454 fn gap-to-end-of-line self: (addr gap-buffer) { +1455 var dummy/eax: grapheme <- copy 0 +1456 # skip to next newline +1457 { +1458 dummy <- gap-right self +1459 { +1460 compare dummy, -1 +1461 break-if-!= +1462 return +1463 } +1464 { +1465 compare dummy, 0xa/newline +1466 break-if-!= +1467 dummy <- gap-left self +1468 return +1469 } +1470 loop +1471 } +1472 } diff --git a/html/shell/global.mu.html b/html/shell/global.mu.html index e1472c81..01cdd2cc 100644 --- a/html/shell/global.mu.html +++ b/html/shell/global.mu.html @@ -14,20 +14,19 @@ pre { white-space: pre-wrap; font-family: monospace; color: #000000; background- body { font-size:12pt; font-family: monospace; color: #000000; background-color: #a8a8a8; } a { color:inherit; } * { font-size:12pt; font-size: 1em; } +.PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .LineNr { } -.Delimiter { color: #c000c0; } -.muFunction { color: #af5f00; text-decoration: underline; } -.muRegEbx { color: #8787af; } -.muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } +.muRegEbx { color: #8787af; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } -.Special { color: #ff6060; } -.PreProc { color: #c000c0; } -.CommentedCode { color: #8a8a8a; } -.muComment { color: #005faf; } +.muRegEsi { color: #87d787; } .muRegEax { color: #875f00; } -.muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } +.Delimiter { color: #c000c0; } +.muFunction { color: #af5f00; text-decoration: underline; } +.muComment { color: #005faf; } +.Special { color: #ff6060; } --> @@ -73,31 +72,31 @@ if ('onhashchange' in window) { 8 name: (handle array byte) 9 input: (handle gap-buffer) 10 value: (handle cell) - 11 } - 12 - 13 fn initialize-globals _self: (addr global-table) { - 14 var self/esi: (addr global-table) <- copy _self - 15 compare self, 0 - 16 { - 17 break-if-!= - 18 abort "initialize globals" - 19 return - 20 } - 21 var data-ah/eax: (addr handle array global) <- get self, data - 22 populate data-ah, 0x40 - 23 initialize-primitives self - 24 } - 25 - 26 fn load-globals in: (addr handle cell), self: (addr global-table) { - 27 draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "loading globals:", 3/fg, 0/bg - 28 var remaining-ah/esi: (addr handle cell) <- copy in - 29 { - 30 var _remaining/eax: (addr cell) <- lookup *remaining-ah - 31 var remaining/ebx: (addr cell) <- copy _remaining - 32 var done?/eax: boolean <- nil? remaining - 33 compare done?, 0/false - 34 break-if-!= - 35 #? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "b", 2/fg 0/bg + 11 trace: (handle trace) + 12 } + 13 + 14 fn initialize-globals _self: (addr global-table) { + 15 var self/esi: (addr global-table) <- copy _self + 16 compare self, 0 + 17 { + 18 break-if-!= + 19 abort "initialize globals" + 20 return + 21 } + 22 var data-ah/eax: (addr handle array global) <- get self, data + 23 populate data-ah, 0x80 + 24 initialize-primitives self + 25 } + 26 + 27 fn load-globals in: (addr handle cell), self: (addr global-table) { + 28 draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "loading globals:", 3/fg, 0/bg + 29 var remaining-ah/esi: (addr handle cell) <- copy in + 30 { + 31 var _remaining/eax: (addr cell) <- lookup *remaining-ah + 32 var remaining/ebx: (addr cell) <- copy _remaining + 33 var done?/eax: boolean <- nil? remaining + 34 compare done?, 0/false + 35 break-if-!= 36 var curr-ah/eax: (addr handle cell) <- get remaining, left 37 var _curr/eax: (addr cell) <- lookup *curr-ah 38 var curr/ecx: (addr cell) <- copy _curr @@ -120,538 +119,529 @@ if ('onhashchange' in window) { 55 allocate value-gap-buffer-ah 56 var value-gap-buffer/eax: (addr gap-buffer) <- lookup *value-gap-buffer-ah 57 initialize-gap-buffer value-gap-buffer, 0x1000/4KB - 58 #? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "w", 2/fg 0/bg - 59 load-gap-buffer-from-stream value-gap-buffer, value-data - 60 #? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "x", 2/fg 0/bg - 61 read-evaluate-and-move-to-globals value-gap-buffer-ah, self, name-data - 62 #? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "y", 2/fg 0/bg - 63 loop - 64 } - 65 move-cursor-to-left-margin-of-next-line 0/screen - 66 #? abort "zz" - 67 } - 68 - 69 fn write-globals out: (addr stream byte), _self: (addr global-table) { - 70 var self/esi: (addr global-table) <- copy _self - 71 compare self, 0 - 72 { - 73 break-if-!= - 74 abort "write globals" - 75 return - 76 } - 77 write out, " (globals . (\n" - 78 var data-ah/eax: (addr handle array global) <- get self, data - 79 var data/eax: (addr array global) <- lookup *data-ah - 80 var final-index/edx: (addr int) <- get self, final-index - 81 var curr-index/ecx: int <- copy 1/skip-0 - 82 { - 83 compare curr-index, *final-index - 84 break-if-> - 85 var curr-offset/ebx: (offset global) <- compute-offset data, curr-index - 86 var curr/ebx: (addr global) <- index data, curr-offset - 87 var curr-value-ah/edx: (addr handle cell) <- get curr, value - 88 var curr-value/eax: (addr cell) <- lookup *curr-value-ah - 89 var curr-type/eax: (addr int) <- get curr-value, type - 90 { - 91 compare *curr-type, 4/primitive-function + 58 load-gap-buffer-from-stream value-gap-buffer, value-data + 59 load-lexical-scope value-gap-buffer-ah, self + 60 loop + 61 } + 62 move-cursor-to-left-margin-of-next-line 0/screen + 63 } + 64 + 65 fn write-globals out: (addr stream byte), _self: (addr global-table) { + 66 var self/esi: (addr global-table) <- copy _self + 67 compare self, 0 + 68 { + 69 break-if-!= + 70 abort "write globals" + 71 return + 72 } + 73 write out, " (globals . (\n" + 74 var data-ah/eax: (addr handle array global) <- get self, data + 75 var data/eax: (addr array global) <- lookup *data-ah + 76 var final-index/edx: (addr int) <- get self, final-index + 77 var curr-index/ecx: int <- copy 1/skip-0 + 78 { + 79 compare curr-index, *final-index + 80 break-if-> + 81 var curr-offset/ebx: (offset global) <- compute-offset data, curr-index + 82 var curr/ebx: (addr global) <- index data, curr-offset + 83 var curr-value-ah/edx: (addr handle cell) <- get curr, value + 84 var curr-value/eax: (addr cell) <- lookup *curr-value-ah + 85 var curr-type/eax: (addr int) <- get curr-value, type + 86 { + 87 compare *curr-type, 4/primitive-function + 88 break-if-= + 89 compare *curr-type, 5/screen + 90 break-if-= + 91 compare *curr-type, 6/keyboard 92 break-if-= - 93 compare *curr-type, 5/screen + 93 compare *curr-type, 3/stream # not implemented yet 94 break-if-= - 95 compare *curr-type, 6/keyboard - 96 break-if-= - 97 compare *curr-type, 3/stream # not implemented yet - 98 break-if-= - 99 write out, " (" -100 var curr-name-ah/eax: (addr handle array byte) <- get curr, name -101 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah -102 write out, curr-name -103 write out, " . [" -104 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr, input -105 var curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah -106 append-gap-buffer curr-input, out -107 write out, "])\n" -108 } -109 curr-index <- increment -110 loop -111 } -112 write out, " ))\n" -113 } -114 -115 # globals layout: 1 char padding, 41 code, 1 padding, 41 code, 1 padding = 85 chars -116 fn render-globals screen: (addr screen), _self: (addr global-table), show-cursor?: boolean { -117 clear-rect screen, 0/xmin, 0/ymin, 0x55/xmax, 0x2f/ymax=screen-height-without-menu, 0xdc/bg=green-bg -118 var self/esi: (addr global-table) <- copy _self -119 compare self, 0 -120 { -121 break-if-!= -122 abort "render globals" -123 return -124 } -125 var data-ah/eax: (addr handle array global) <- get self, data -126 var data/eax: (addr array global) <- lookup *data-ah -127 var curr-index/edx: int <- copy 1 -128 { -129 var curr-offset/ebx: (offset global) <- compute-offset data, curr-index -130 var curr/ebx: (addr global) <- index data, curr-offset -131 var continue?/eax: boolean <- primitive-global? curr -132 compare continue?, 0/false -133 break-if-= -134 curr-index <- increment -135 loop -136 } -137 var lowest-index/edi: int <- copy curr-index -138 var cursor-index/edx: (addr int) <- get self, cursor-index -139 var curr-index/edx: int <- copy *cursor-index -140 var y1: int -141 copy-to y1, 1/padding-top -142 var y2: int -143 copy-to y2, 1/padding-top -144 $render-globals:loop: { -145 compare curr-index, lowest-index -146 break-if-< -147 { -148 compare y1, 0x2f/ymax -149 break-if-< -150 compare y2, 0x2f/ymax -151 break-if-< -152 break $render-globals:loop -153 } -154 { -155 var show-cursor?/edi: boolean <- copy show-cursor? -156 { -157 compare show-cursor?, 0/false -158 break-if-= -159 var cursor-index/eax: (addr int) <- get self, cursor-index -160 compare *cursor-index, curr-index -161 break-if-= -162 show-cursor? <- copy 0/false -163 } -164 var curr-offset/edx: (offset global) <- compute-offset data, curr-index -165 var curr/edx: (addr global) <- index data, curr-offset -166 var curr-input-ah/edx: (addr handle gap-buffer) <- get curr, input -167 var _curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah -168 var curr-input/ebx: (addr gap-buffer) <- copy _curr-input -169 compare curr-input, 0 -170 break-if-= -171 $render-globals:render-global: { -172 var x/eax: int <- copy 0 -173 var y/ecx: int <- copy y1 -174 compare y, y2 -175 { -176 break-if->= -177 x, y <- render-gap-buffer-wrapping-right-then-down screen, curr-input, 1/padding-left, y1, 0x2a/xmax, 0x2f/ymax, show-cursor?, 7/fg=definition, 0xc5/bg=blue-bg -178 y <- add 2 -179 copy-to y1, y -180 break $render-globals:render-global -181 } -182 x, y <- render-gap-buffer-wrapping-right-then-down screen, curr-input, 0x2b/xmin, y2, 0x54/xmax, 0x2f/ymax, show-cursor?, 7/fg=definition, 0xc5/bg=blue-bg -183 y <- add 2 -184 copy-to y2, y -185 } -186 } -187 curr-index <- decrement -188 loop -189 } -190 # render primitives on top -191 render-primitives screen, 1/xmin=padding-left, 0x55/xmax, 0x2f/ymax -192 } -193 -194 fn render-globals-menu screen: (addr screen), _self: (addr global-table) { -195 var _width/eax: int <- copy 0 -196 var height/ecx: int <- copy 0 -197 _width, height <- screen-size screen -198 var width/edx: int <- copy _width -199 var y/ecx: int <- copy height -200 y <- decrement -201 var height/ebx: int <- copy y -202 height <- increment -203 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg -204 set-cursor-position screen, 0/x, y -205 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight -206 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg -207 draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight -208 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0xc5/bg=blue-bg -209 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight -210 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg -211 draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight -212 draw-text-rightward-from-cursor screen, " << ", width, 7/fg, 0xc5/bg=blue-bg -213 draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight -214 draw-text-rightward-from-cursor screen, " <word ", width, 7/fg, 0xc5/bg=blue-bg -215 draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight -216 draw-text-rightward-from-cursor screen, " word> ", width, 7/fg, 0xc5/bg=blue-bg -217 draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight -218 draw-text-rightward-from-cursor screen, " >> ", width, 7/fg, 0xc5/bg=blue-bg -219 } -220 -221 fn edit-globals _self: (addr global-table), key: grapheme { -222 var self/esi: (addr global-table) <- copy _self -223 # ctrl-s -224 { -225 compare key, 0x13/ctrl-s -226 break-if-!= -227 # -228 refresh-cursor-definition self -229 return -230 } -231 var cursor-index-addr/ecx: (addr int) <- get self, cursor-index -232 var cursor-index/ecx: int <- copy *cursor-index-addr -233 var data-ah/eax: (addr handle array global) <- get self, data -234 var data/eax: (addr array global) <- lookup *data-ah -235 var cursor-offset/ecx: (offset global) <- compute-offset data, cursor-index -236 var curr-global/eax: (addr global) <- index data, cursor-offset -237 var curr-editor-ah/eax: (addr handle gap-buffer) <- get curr-global, input -238 var curr-editor/eax: (addr gap-buffer) <- lookup *curr-editor-ah -239 edit-gap-buffer curr-editor, key -240 } -241 -242 fn refresh-cursor-definition _self: (addr global-table) { -243 var self/esi: (addr global-table) <- copy _self -244 var cursor-index/edx: (addr int) <- get self, cursor-index -245 refresh-definition self, *cursor-index -246 } -247 -248 fn refresh-definition _self: (addr global-table), _index: int { -249 var self/esi: (addr global-table) <- copy _self -250 var data-ah/eax: (addr handle array global) <- get self, data -251 var data/eax: (addr array global) <- lookup *data-ah -252 var index/ecx: int <- copy _index -253 var offset/ecx: (offset global) <- compute-offset data, index -254 var curr-global/ecx: (addr global) <- index data, offset -255 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr-global, input -256 var curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah -257 var read-result-h: (handle cell) -258 var read-result-ah/edx: (addr handle cell) <- address read-result-h -259 var trace-storage: trace -260 var trace/ebx: (addr trace) <- address trace-storage -261 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible -262 read-cell curr-input, read-result-ah, trace -263 macroexpand read-result-ah, self, trace -264 var nil-h: (handle cell) -265 { -266 var nil-ah/eax: (addr handle cell) <- address nil-h -267 allocate-pair nil-ah -268 } -269 var curr-value-ah/eax: (addr handle cell) <- get curr-global, value -270 debug-print "GL", 4/fg, 0/bg -271 evaluate read-result-ah, curr-value-ah, nil-h, self, trace, 0/no-screen-cell, 0/no-keyboard-cell, 1/call-number -272 debug-print "GZ", 4/fg, 0/bg -273 } -274 -275 fn assign-or-create-global _self: (addr global-table), name: (addr array byte), value: (handle cell), trace: (addr trace) { -276 var self/esi: (addr global-table) <- copy _self -277 compare self, 0 -278 { -279 break-if-!= -280 abort "assign global" -281 return -282 } -283 var curr-index/ecx: int <- find-symbol-name-in-globals self, name -284 { -285 compare curr-index, -1/not-found -286 break-if-!= -287 var final-index-addr/eax: (addr int) <- get self, final-index -288 increment *final-index-addr -289 curr-index <- copy *final-index-addr -290 var cursor-index-addr/eax: (addr int) <- get self, cursor-index -291 copy-to *cursor-index-addr, curr-index -292 } -293 var data-ah/eax: (addr handle array global) <- get self, data -294 var data/eax: (addr array global) <- lookup *data-ah -295 var curr-offset/esi: (offset global) <- compute-offset data, curr-index -296 var curr/esi: (addr global) <- index data, curr-offset -297 var curr-name-ah/eax: (addr handle array byte) <- get curr, name -298 copy-array-object name, curr-name-ah -299 var curr-value-ah/eax: (addr handle cell) <- get curr, value -300 copy-handle value, curr-value-ah -301 } -302 -303 fn lookup-symbol-in-globals _sym: (addr cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) { -304 var sym/eax: (addr cell) <- copy _sym -305 var sym-name-ah/eax: (addr handle stream byte) <- get sym, text-data -306 var _sym-name/eax: (addr stream byte) <- lookup *sym-name-ah -307 var sym-name/edx: (addr stream byte) <- copy _sym-name -308 var globals/esi: (addr global-table) <- copy _globals -309 { -310 compare globals, 0 -311 break-if-= -312 var curr-index/ecx: int <- find-symbol-in-globals globals, sym-name -313 compare curr-index, -1/not-found -314 break-if-= -315 var global-data-ah/eax: (addr handle array global) <- get globals, data -316 var global-data/eax: (addr array global) <- lookup *global-data-ah -317 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index -318 var curr/ebx: (addr global) <- index global-data, curr-offset -319 var curr-value/eax: (addr handle cell) <- get curr, value -320 copy-object curr-value, out -321 return -322 } -323 # if sym is "screen" and screen-cell exists, return it -324 { -325 var sym-is-screen?/eax: boolean <- stream-data-equal? sym-name, "screen" -326 compare sym-is-screen?, 0/false -327 break-if-= -328 compare screen-cell, 0 -329 break-if-= -330 copy-object screen-cell, out -331 return -332 } -333 # if sym is "keyboard" and keyboard-cell exists, return it -334 { -335 var sym-is-keyboard?/eax: boolean <- stream-data-equal? sym-name, "keyboard" -336 compare sym-is-keyboard?, 0/false + 95 write out, " (" + 96 var curr-name-ah/eax: (addr handle array byte) <- get curr, name + 97 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah + 98 write out, curr-name + 99 write out, " . [" +100 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr, input +101 var curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah +102 { +103 compare curr-input, 0 +104 break-if-!= +105 abort "null gap buffer" +106 } +107 append-gap-buffer curr-input, out +108 write out, "])\n" +109 } +110 curr-index <- increment +111 loop +112 } +113 write out, " ))\n" +114 } +115 +116 # globals layout: 1 char padding, 41 code, 1 padding, 41 code, 1 padding = 85 chars +117 fn render-globals screen: (addr screen), _self: (addr global-table), show-cursor?: boolean { +118 clear-rect screen, 0/xmin, 0/ymin, 0x55/xmax, 0x2f/ymax=screen-height-without-menu, 0xdc/bg=green-bg +119 var self/esi: (addr global-table) <- copy _self +120 compare self, 0 +121 { +122 break-if-!= +123 abort "render globals" +124 return +125 } +126 var data-ah/eax: (addr handle array global) <- get self, data +127 var data/eax: (addr array global) <- lookup *data-ah +128 var curr-index/edx: int <- copy 1 +129 { +130 var curr-offset/ebx: (offset global) <- compute-offset data, curr-index +131 var curr/ebx: (addr global) <- index data, curr-offset +132 var continue?/eax: boolean <- primitive-global? curr +133 compare continue?, 0/false +134 break-if-= +135 curr-index <- increment +136 loop +137 } +138 var lowest-index/edi: int <- copy curr-index +139 var cursor-index/edx: (addr int) <- get self, cursor-index +140 var curr-index/edx: int <- copy *cursor-index +141 var y1: int +142 copy-to y1, 1/padding-top +143 var y2: int +144 copy-to y2, 1/padding-top +145 $render-globals:loop: { +146 compare curr-index, lowest-index +147 break-if-< +148 { +149 compare y1, 0x2f/ymax +150 break-if-< +151 compare y2, 0x2f/ymax +152 break-if-< +153 break $render-globals:loop +154 } +155 { +156 var cursor-in-current-line?: boolean +157 { +158 compare show-cursor?, 0/false +159 break-if-= +160 var cursor-index/eax: (addr int) <- get self, cursor-index +161 compare *cursor-index, curr-index +162 break-if-!= +163 copy-to cursor-in-current-line?, 1/true +164 } +165 var curr-offset/edx: (offset global) <- compute-offset data, curr-index +166 var curr/edx: (addr global) <- index data, curr-offset +167 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr, input +168 var _curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah +169 var curr-input/ebx: (addr gap-buffer) <- copy _curr-input +170 compare curr-input, 0 +171 break-if-= +172 var curr-trace-ah/eax: (addr handle trace) <- get curr, trace +173 var _curr-trace/eax: (addr trace) <- lookup *curr-trace-ah +174 var curr-trace/edx: (addr trace) <- copy _curr-trace +175 $render-globals:render-global: { +176 var x/eax: int <- copy 0 +177 var y/ecx: int <- copy y1 +178 compare y, y2 +179 { +180 break-if->= +181 x, y <- render-gap-buffer-wrapping-right-then-down screen, curr-input, 1/padding-left, y1, 0x2a/xmax, 0x2f/ymax, cursor-in-current-line?, 7/fg=definition, 0xc5/bg=blue-bg +182 y <- increment +183 y <- render-trace screen, curr-trace, 1/padding-left, y, 0x2a/xmax, 0x2f/ymax, 0/no-cursor +184 y <- increment +185 copy-to y1, y +186 break $render-globals:render-global +187 } +188 x, y <- render-gap-buffer-wrapping-right-then-down screen, curr-input, 0x2b/xmin, y2, 0x54/xmax, 0x2f/ymax, cursor-in-current-line?, 7/fg=definition, 0xc5/bg=blue-bg +189 y <- increment +190 y <- render-trace screen, curr-trace, 0x2b/xmin, y, 0x54/xmax, 0x2f/ymax, 0/no-cursor +191 y <- increment +192 copy-to y2, y +193 } +194 } +195 curr-index <- decrement +196 loop +197 } +198 # render primitives on top +199 render-primitives screen, 1/xmin=padding-left, 0x55/xmax, 0x2f/ymax +200 } +201 +202 fn render-globals-menu screen: (addr screen), _self: (addr global-table) { +203 var _width/eax: int <- copy 0 +204 var height/ecx: int <- copy 0 +205 _width, height <- screen-size screen +206 var width/edx: int <- copy _width +207 var y/ecx: int <- copy height +208 y <- decrement +209 var height/ebx: int <- copy y +210 height <- increment +211 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg +212 set-cursor-position screen, 0/x, y +213 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight +214 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg +215 draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight +216 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0xc5/bg=blue-bg +217 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight +218 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg +219 draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight +220 draw-text-rightward-from-cursor screen, " << ", width, 7/fg, 0xc5/bg=blue-bg +221 draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight +222 draw-text-rightward-from-cursor screen, " <word ", width, 7/fg, 0xc5/bg=blue-bg +223 draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight +224 draw-text-rightward-from-cursor screen, " word> ", width, 7/fg, 0xc5/bg=blue-bg +225 draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight +226 draw-text-rightward-from-cursor screen, " >> ", width, 7/fg, 0xc5/bg=blue-bg +227 } +228 +229 fn edit-globals _self: (addr global-table), key: grapheme { +230 var self/esi: (addr global-table) <- copy _self +231 # ctrl-s +232 { +233 compare key, 0x13/ctrl-s +234 break-if-!= +235 # +236 refresh-cursor-definition self +237 return +238 } +239 var cursor-index-addr/ecx: (addr int) <- get self, cursor-index +240 var cursor-index/ecx: int <- copy *cursor-index-addr +241 var data-ah/eax: (addr handle array global) <- get self, data +242 var data/eax: (addr array global) <- lookup *data-ah +243 var cursor-offset/ecx: (offset global) <- compute-offset data, cursor-index +244 var curr-global/eax: (addr global) <- index data, cursor-offset +245 var curr-editor-ah/eax: (addr handle gap-buffer) <- get curr-global, input +246 var curr-editor/eax: (addr gap-buffer) <- lookup *curr-editor-ah +247 edit-gap-buffer curr-editor, key +248 } +249 +250 fn create-empty-global _self: (addr global-table), name-stream: (addr stream byte), capacity: int { +251 var self/esi: (addr global-table) <- copy _self +252 var final-index-addr/ecx: (addr int) <- get self, final-index +253 increment *final-index-addr +254 var curr-index/ecx: int <- copy *final-index-addr +255 var cursor-index-addr/eax: (addr int) <- get self, cursor-index +256 copy-to *cursor-index-addr, curr-index +257 var data-ah/eax: (addr handle array global) <- get self, data +258 var data/eax: (addr array global) <- lookup *data-ah +259 var curr-offset/ecx: (offset global) <- compute-offset data, curr-index +260 var curr/esi: (addr global) <- index data, curr-offset +261 var curr-name-ah/eax: (addr handle array byte) <- get curr, name +262 stream-to-array name-stream, curr-name-ah +263 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr, input +264 allocate curr-input-ah +265 var curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah +266 initialize-gap-buffer curr-input, capacity +267 var trace-ah/eax: (addr handle trace) <- get curr, trace +268 allocate trace-ah +269 var trace/eax: (addr trace) <- lookup *trace-ah +270 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +271 } +272 +273 fn refresh-cursor-definition _self: (addr global-table) { +274 var self/esi: (addr global-table) <- copy _self +275 var cursor-index/edx: (addr int) <- get self, cursor-index +276 refresh-definition self, *cursor-index +277 } +278 +279 fn refresh-definition _self: (addr global-table), _index: int { +280 var self/esi: (addr global-table) <- copy _self +281 var data-ah/eax: (addr handle array global) <- get self, data +282 var data/eax: (addr array global) <- lookup *data-ah +283 var index/ebx: int <- copy _index +284 var offset/ebx: (offset global) <- compute-offset data, index +285 var curr-global/ebx: (addr global) <- index data, offset +286 var curr-input-ah/edx: (addr handle gap-buffer) <- get curr-global, input +287 var curr-trace-ah/eax: (addr handle trace) <- get curr-global, trace +288 var curr-trace/eax: (addr trace) <- lookup *curr-trace-ah +289 clear-trace curr-trace +290 var curr-value-ah/edi: (addr handle cell) <- get curr-global, value +291 var definitions-created-storage: (stream int 0x10) +292 var definitions-created/ecx: (addr stream int) <- address definitions-created-storage +293 read-and-evaluate-and-save-gap-buffer-to-globals curr-input-ah, curr-value-ah, self, definitions-created, curr-trace, 0/no-screen, 0/no-keyboard +294 } +295 +296 fn assign-or-create-global _self: (addr global-table), name: (addr array byte), value: (handle cell), index-updated: (addr int), trace: (addr trace) { +297 var self/esi: (addr global-table) <- copy _self +298 compare self, 0 +299 { +300 break-if-!= +301 abort "assign global" +302 } +303 var curr-index/ecx: int <- find-symbol-name-in-globals self, name +304 { +305 compare curr-index, -1/not-found +306 break-if-!= +307 var final-index-addr/eax: (addr int) <- get self, final-index +308 increment *final-index-addr +309 curr-index <- copy *final-index-addr +310 var cursor-index-addr/eax: (addr int) <- get self, cursor-index +311 copy-to *cursor-index-addr, curr-index +312 } +313 var data-ah/eax: (addr handle array global) <- get self, data +314 var data/eax: (addr array global) <- lookup *data-ah +315 var curr-offset/esi: (offset global) <- compute-offset data, curr-index +316 var curr/esi: (addr global) <- index data, curr-offset +317 var curr-name-ah/eax: (addr handle array byte) <- get curr, name +318 copy-array-object name, curr-name-ah +319 var curr-value-ah/eax: (addr handle cell) <- get curr, value +320 copy-handle value, curr-value-ah +321 var index-updated/edi: (addr int) <- copy index-updated +322 copy-to *index-updated, curr-index +323 var trace-ah/eax: (addr handle trace) <- get curr, trace +324 allocate trace-ah +325 var trace/eax: (addr trace) <- lookup *trace-ah +326 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +327 } +328 +329 fn lookup-symbol-in-globals _sym: (addr cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell) { +330 var sym/eax: (addr cell) <- copy _sym +331 var sym-name-ah/eax: (addr handle stream byte) <- get sym, text-data +332 var _sym-name/eax: (addr stream byte) <- lookup *sym-name-ah +333 var sym-name/edx: (addr stream byte) <- copy _sym-name +334 var globals/esi: (addr global-table) <- copy _globals +335 { +336 compare globals, 0 337 break-if-= -338 compare keyboard-cell, 0 -339 break-if-= -340 copy-object keyboard-cell, out -341 return -342 } -343 # otherwise error "unbound symbol: ", sym -344 var stream-storage: (stream byte 0x40) -345 var stream/ecx: (addr stream byte) <- address stream-storage -346 write stream, "unbound symbol: " -347 rewind-stream sym-name -348 write-stream stream, sym-name -349 error-stream trace, stream -350 } -351 -352 fn maybe-lookup-symbol-in-globals _sym: (addr cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace) { -353 var sym/eax: (addr cell) <- copy _sym -354 var sym-name-ah/eax: (addr handle stream byte) <- get sym, text-data -355 var _sym-name/eax: (addr stream byte) <- lookup *sym-name-ah -356 var sym-name/edx: (addr stream byte) <- copy _sym-name -357 var globals/esi: (addr global-table) <- copy _globals -358 { -359 compare globals, 0 -360 break-if-= -361 var curr-index/ecx: int <- find-symbol-in-globals globals, sym-name -362 compare curr-index, -1/not-found +338 var curr-index/ecx: int <- find-symbol-in-globals globals, sym-name +339 compare curr-index, -1/not-found +340 break-if-= +341 var global-data-ah/eax: (addr handle array global) <- get globals, data +342 var global-data/eax: (addr array global) <- lookup *global-data-ah +343 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index +344 var curr/ebx: (addr global) <- index global-data, curr-offset +345 var curr-value/eax: (addr handle cell) <- get curr, value +346 copy-object curr-value, out +347 return +348 } +349 # if sym is "screen" and inner-screen-var exists, return it +350 { +351 var sym-is-screen?/eax: boolean <- stream-data-equal? sym-name, "screen" +352 compare sym-is-screen?, 0/false +353 break-if-= +354 compare inner-screen-var, 0 +355 break-if-= +356 copy-object inner-screen-var, out +357 return +358 } +359 # if sym is "keyboard" and inner-keyboard-var exists, return it +360 { +361 var sym-is-keyboard?/eax: boolean <- stream-data-equal? sym-name, "keyboard" +362 compare sym-is-keyboard?, 0/false 363 break-if-= -364 var global-data-ah/eax: (addr handle array global) <- get globals, data -365 var global-data/eax: (addr array global) <- lookup *global-data-ah -366 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index -367 var curr/ebx: (addr global) <- index global-data, curr-offset -368 var curr-value/eax: (addr handle cell) <- get curr, value -369 copy-object curr-value, out -370 return -371 } -372 } -373 -374 # return the index in globals containing 'sym' -375 # or -1 if not found -376 fn find-symbol-in-globals _globals: (addr global-table), sym-name: (addr stream byte) -> _/ecx: int { -377 var globals/esi: (addr global-table) <- copy _globals -378 compare globals, 0 -379 { -380 break-if-!= -381 return -1/not-found -382 } -383 var global-data-ah/eax: (addr handle array global) <- get globals, data -384 var global-data/eax: (addr array global) <- lookup *global-data-ah -385 var final-index/ecx: (addr int) <- get globals, final-index -386 var curr-index/ecx: int <- copy *final-index -387 { -388 compare curr-index, 0 -389 break-if-< -390 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index -391 var curr/ebx: (addr global) <- index global-data, curr-offset -392 var curr-name-ah/eax: (addr handle array byte) <- get curr, name -393 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah -394 var found?/eax: boolean <- stream-data-equal? sym-name, curr-name -395 compare found?, 0/false -396 { -397 break-if-= -398 return curr-index -399 } -400 curr-index <- decrement -401 loop -402 } -403 return -1/not-found -404 } -405 -406 # return the index in globals containing 'sym' -407 # or -1 if not found -408 fn find-symbol-name-in-globals _globals: (addr global-table), sym-name: (addr array byte) -> _/ecx: int { -409 var globals/esi: (addr global-table) <- copy _globals -410 compare globals, 0 -411 { -412 break-if-!= -413 return -1/not-found -414 } -415 var global-data-ah/eax: (addr handle array global) <- get globals, data -416 var global-data/eax: (addr array global) <- lookup *global-data-ah -417 var final-index/ecx: (addr int) <- get globals, final-index -418 var curr-index/ecx: int <- copy *final-index -419 { -420 compare curr-index, 0 -421 break-if-< -422 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index -423 var curr/ebx: (addr global) <- index global-data, curr-offset -424 var curr-name-ah/eax: (addr handle array byte) <- get curr, name -425 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah -426 var found?/eax: boolean <- string-equal? sym-name, curr-name -427 compare found?, 0/false -428 { -429 break-if-= -430 return curr-index -431 } -432 curr-index <- decrement -433 loop -434 } -435 return -1/not-found -436 } -437 -438 fn mutate-binding-in-globals name: (addr stream byte), val: (addr handle cell), _globals: (addr global-table), trace: (addr trace) { -439 var globals/esi: (addr global-table) <- copy _globals -440 { -441 compare globals, 0 -442 break-if-= -443 var curr-index/ecx: int <- find-symbol-in-globals globals, name -444 compare curr-index, -1/not-found -445 break-if-= -446 var global-data-ah/eax: (addr handle array global) <- get globals, data -447 var global-data/eax: (addr array global) <- lookup *global-data-ah +364 compare inner-keyboard-var, 0 +365 break-if-= +366 copy-object inner-keyboard-var, out +367 return +368 } +369 # otherwise error "unbound symbol: ", sym +370 var stream-storage: (stream byte 0x40) +371 var stream/ecx: (addr stream byte) <- address stream-storage +372 write stream, "unbound symbol: " +373 rewind-stream sym-name +374 write-stream stream, sym-name +375 error-stream trace, stream +376 } +377 +378 fn maybe-lookup-symbol-in-globals _sym: (addr cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace) { +379 var sym/eax: (addr cell) <- copy _sym +380 var sym-name-ah/eax: (addr handle stream byte) <- get sym, text-data +381 var _sym-name/eax: (addr stream byte) <- lookup *sym-name-ah +382 var sym-name/edx: (addr stream byte) <- copy _sym-name +383 var globals/esi: (addr global-table) <- copy _globals +384 { +385 compare globals, 0 +386 break-if-= +387 var curr-index/ecx: int <- find-symbol-in-globals globals, sym-name +388 compare curr-index, -1/not-found +389 break-if-= +390 var global-data-ah/eax: (addr handle array global) <- get globals, data +391 var global-data/eax: (addr array global) <- lookup *global-data-ah +392 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index +393 var curr/ebx: (addr global) <- index global-data, curr-offset +394 var curr-value/eax: (addr handle cell) <- get curr, value +395 copy-object curr-value, out +396 return +397 } +398 } +399 +400 # return the index in globals containing 'sym' +401 # or -1 if not found +402 fn find-symbol-in-globals _globals: (addr global-table), sym-name: (addr stream byte) -> _/ecx: int { +403 var globals/esi: (addr global-table) <- copy _globals +404 compare globals, 0 +405 { +406 break-if-!= +407 return -1/not-found +408 } +409 var global-data-ah/eax: (addr handle array global) <- get globals, data +410 var global-data/eax: (addr array global) <- lookup *global-data-ah +411 var final-index/ecx: (addr int) <- get globals, final-index +412 var curr-index/ecx: int <- copy *final-index +413 { +414 compare curr-index, 0 +415 break-if-< +416 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index +417 var curr/ebx: (addr global) <- index global-data, curr-offset +418 var curr-name-ah/eax: (addr handle array byte) <- get curr, name +419 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah +420 var found?/eax: boolean <- stream-data-equal? sym-name, curr-name +421 compare found?, 0/false +422 { +423 break-if-= +424 return curr-index +425 } +426 curr-index <- decrement +427 loop +428 } +429 return -1/not-found +430 } +431 +432 # return the index in globals containing 'sym' +433 # or -1 if not found +434 fn find-symbol-name-in-globals _globals: (addr global-table), sym-name: (addr array byte) -> _/ecx: int { +435 var globals/esi: (addr global-table) <- copy _globals +436 compare globals, 0 +437 { +438 break-if-!= +439 return -1/not-found +440 } +441 var global-data-ah/eax: (addr handle array global) <- get globals, data +442 var global-data/eax: (addr array global) <- lookup *global-data-ah +443 var final-index/ecx: (addr int) <- get globals, final-index +444 var curr-index/ecx: int <- copy *final-index +445 { +446 compare curr-index, 0 +447 break-if-< 448 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index 449 var curr/ebx: (addr global) <- index global-data, curr-offset -450 var dest/eax: (addr handle cell) <- get curr, value -451 copy-object val, dest -452 return -453 } -454 # otherwise error "unbound symbol: ", sym -455 var stream-storage: (stream byte 0x40) -456 var stream/ecx: (addr stream byte) <- address stream-storage -457 write stream, "unbound symbol: " -458 rewind-stream name -459 write-stream stream, name -460 error-stream trace, stream -461 } -462 -463 # Accepts an input s-expression, naively checks if it is a definition, and if -464 # so saves the gap-buffer to the appropriate global, spinning up a new empty -465 # one to replace it with. -466 fn maybe-stash-gap-buffer-to-global _globals: (addr global-table), _definition-ah: (addr handle cell), gap: (addr handle gap-buffer) { -467 # if 'definition' is not a pair, return -468 var definition-ah/eax: (addr handle cell) <- copy _definition-ah -469 var _definition/eax: (addr cell) <- lookup *definition-ah -470 var definition/esi: (addr cell) <- copy _definition -471 var definition-type/eax: (addr int) <- get definition, type -472 compare *definition-type, 0/pair -473 { -474 break-if-= -475 return -476 } -477 # if definition->left is neither "define" nor "set", return -478 var left-ah/eax: (addr handle cell) <- get definition, left -479 var _left/eax: (addr cell) <- lookup *left-ah -480 var left/ecx: (addr cell) <- copy _left -481 { -482 var def?/eax: boolean <- symbol-equal? left, "define" -483 compare def?, 0/false -484 break-if-!= -485 var set?/eax: boolean <- symbol-equal? left, "set" -486 compare set?, 0/false -487 break-if-!= -488 return -489 } -490 # locate the global for definition->right->left -491 var right-ah/eax: (addr handle cell) <- get definition, right -492 var right/eax: (addr cell) <- lookup *right-ah -493 var defined-symbol-ah/eax: (addr handle cell) <- get right, left -494 var defined-symbol/eax: (addr cell) <- lookup *defined-symbol-ah -495 var defined-symbol-name-ah/eax: (addr handle stream byte) <- get defined-symbol, text-data -496 var defined-symbol-name/eax: (addr stream byte) <- lookup *defined-symbol-name-ah -497 var index/ecx: int <- find-symbol-in-globals _globals, defined-symbol-name -498 { -499 compare index, -1/not-found -500 break-if-!= -501 return -502 } -503 # stash 'gap' to it -504 var globals/eax: (addr global-table) <- copy _globals -505 compare globals, 0 -506 { -507 break-if-!= -508 abort "stash to globals" -509 return -510 } -511 var global-data-ah/eax: (addr handle array global) <- get globals, data -512 var global-data/eax: (addr array global) <- lookup *global-data-ah -513 var offset/ebx: (offset global) <- compute-offset global-data, index -514 var dest-global/eax: (addr global) <- index global-data, offset -515 var dest-ah/eax: (addr handle gap-buffer) <- get dest-global, input -516 copy-object gap, dest-ah -517 # initialize a new gap-buffer in 'gap' -518 var dest/eax: (addr gap-buffer) <- lookup *dest-ah -519 var capacity/ecx: int <- gap-buffer-capacity dest -520 var gap2/eax: (addr handle gap-buffer) <- copy gap -521 allocate gap2 -522 var gap-addr/eax: (addr gap-buffer) <- lookup *gap2 -523 initialize-gap-buffer gap-addr, capacity -524 } -525 -526 # Accepts an input s-expression, naively checks if it is a definition, and if -527 # so saves the gap-buffer to the appropriate global. -528 fn move-gap-buffer-to-global _globals: (addr global-table), _definition-ah: (addr handle cell), gap: (addr handle gap-buffer) { -529 # if 'definition' is not a pair, return -530 var definition-ah/eax: (addr handle cell) <- copy _definition-ah -531 var _definition/eax: (addr cell) <- lookup *definition-ah -532 var definition/esi: (addr cell) <- copy _definition -533 var definition-type/eax: (addr int) <- get definition, type -534 compare *definition-type, 0/pair -535 { -536 break-if-= -537 return -538 } -539 # if definition->left is neither "define" nor "set", return -540 var left-ah/eax: (addr handle cell) <- get definition, left -541 var _left/eax: (addr cell) <- lookup *left-ah -542 var left/ecx: (addr cell) <- copy _left -543 { -544 var def?/eax: boolean <- symbol-equal? left, "define" -545 compare def?, 0/false -546 break-if-!= -547 var set?/eax: boolean <- symbol-equal? left, "set" -548 compare set?, 0/false -549 break-if-!= -550 return -551 } -552 # locate the global for definition->right->left -553 var right-ah/eax: (addr handle cell) <- get definition, right -554 var right/eax: (addr cell) <- lookup *right-ah -555 var defined-symbol-ah/eax: (addr handle cell) <- get right, left -556 var defined-symbol/eax: (addr cell) <- lookup *defined-symbol-ah -557 var defined-symbol-name-ah/eax: (addr handle stream byte) <- get defined-symbol, text-data -558 var defined-symbol-name/eax: (addr stream byte) <- lookup *defined-symbol-name-ah -559 var index/ecx: int <- find-symbol-in-globals _globals, defined-symbol-name -560 { -561 compare index, -1/not-found -562 break-if-!= -563 return -564 } -565 # move 'gap' to it -566 var globals/eax: (addr global-table) <- copy _globals -567 compare globals, 0 -568 { -569 break-if-!= -570 abort "move to globals" -571 return -572 } -573 var global-data-ah/eax: (addr handle array global) <- get globals, data -574 var global-data/eax: (addr array global) <- lookup *global-data-ah -575 var offset/ebx: (offset global) <- compute-offset global-data, index -576 var dest-global/eax: (addr global) <- index global-data, offset -577 var dest-ah/eax: (addr handle gap-buffer) <- get dest-global, input -578 copy-object gap, dest-ah -579 } -580 -581 fn set-global-cursor-index _globals: (addr global-table), name-gap: (addr gap-buffer) { -582 var globals/esi: (addr global-table) <- copy _globals -583 var name-storage: (stream byte 0x40) -584 var name/ecx: (addr stream byte) <- address name-storage -585 emit-gap-buffer name-gap, name -586 var index/ecx: int <- find-symbol-in-globals globals, name -587 var dest/edi: (addr int) <- get globals, cursor-index -588 copy-to *dest, index -589 } +450 var curr-name-ah/eax: (addr handle array byte) <- get curr, name +451 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah +452 var found?/eax: boolean <- string-equal? sym-name, curr-name +453 compare found?, 0/false +454 { +455 break-if-= +456 return curr-index +457 } +458 curr-index <- decrement +459 loop +460 } +461 return -1/not-found +462 } +463 +464 fn mutate-binding-in-globals name: (addr stream byte), val: (addr handle cell), _globals: (addr global-table), trace: (addr trace) { +465 var globals/esi: (addr global-table) <- copy _globals +466 { +467 compare globals, 0 +468 break-if-= +469 var curr-index/ecx: int <- find-symbol-in-globals globals, name +470 compare curr-index, -1/not-found +471 break-if-= +472 var global-data-ah/eax: (addr handle array global) <- get globals, data +473 var global-data/eax: (addr array global) <- lookup *global-data-ah +474 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index +475 var curr/ebx: (addr global) <- index global-data, curr-offset +476 var dest/eax: (addr handle cell) <- get curr, value +477 copy-object val, dest +478 return +479 } +480 # otherwise error "unbound symbol: ", sym +481 var stream-storage: (stream byte 0x40) +482 var stream/ecx: (addr stream byte) <- address stream-storage +483 write stream, "unbound symbol: " +484 rewind-stream name +485 write-stream stream, name +486 error-stream trace, stream +487 } +488 +489 fn stash-gap-buffer-to-globals _globals: (addr global-table), definitions: (addr stream int), gap: (addr handle gap-buffer) { +490 var globals/eax: (addr global-table) <- copy _globals +491 compare globals, 0 +492 { +493 break-if-!= +494 return +495 } +496 var global-data-ah/eax: (addr handle array global) <- get globals, data +497 var global-data/eax: (addr array global) <- lookup *global-data-ah +498 rewind-stream definitions +499 { +500 { +501 var done?/eax: boolean <- stream-empty? definitions +502 compare done?, 0/false +503 } +504 break-if-!= +505 var index: int +506 var index-addr/ecx: (addr int) <- address index +507 read-from-stream definitions, index-addr +508 var index/ecx: int <- copy *index-addr +509 var offset/ebx: (offset global) <- compute-offset global-data, index +510 var dest-global/eax: (addr global) <- index global-data, offset +511 var dest-ah/eax: (addr handle gap-buffer) <- get dest-global, input +512 copy-object gap, dest-ah +513 loop +514 } +515 } +516 +517 fn is-definition? _expr: (addr cell) -> _/eax: boolean { +518 var expr/eax: (addr cell) <- copy _expr +519 # if expr->left is neither "define" nor "set", return +520 var left-ah/eax: (addr handle cell) <- get expr, left +521 var _left/eax: (addr cell) <- lookup *left-ah +522 var left/ecx: (addr cell) <- copy _left +523 { +524 var def?/eax: boolean <- symbol-equal? left, "define" +525 compare def?, 0/false +526 break-if-= +527 return 1/true +528 } +529 { +530 var set?/eax: boolean <- symbol-equal? left, "set" +531 compare set?, 0/false +532 break-if-= +533 return 1/true +534 } +535 return 0/false +536 } +537 +538 # load all bindings in a single lexical scope, aka gap buffer of the environment, aka file of the file system +539 fn load-lexical-scope in-ah: (addr handle gap-buffer), _globals: (addr global-table) { +540 var globals/esi: (addr global-table) <- copy _globals +541 var definitions-created-storage: (stream int 0x10) +542 var definitions-created/ebx: (addr stream int) <- address definitions-created-storage +543 var trace-h: (handle trace) +544 var trace-ah/edx: (addr handle trace) <- address trace-h +545 allocate trace-ah +546 var trace/eax: (addr trace) <- lookup *trace-ah +547 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible +548 var dummy-result-h: (handle cell) +549 var dummy-result-ah/ecx: (addr handle cell) <- address dummy-result-h +550 read-and-evaluate-and-save-gap-buffer-to-globals in-ah, dummy-result-ah, globals, definitions-created, trace, 0/no-inner-screen-var, 0/no-inner-keyboard-var +551 # +552 # save trace to all needed globals as well +553 rewind-stream definitions-created +554 var globals-data-ah/eax: (addr handle array global) <- get globals, data +555 var _globals-data/eax: (addr array global) <- lookup *globals-data-ah +556 var globals-data/edi: (addr array global) <- copy _globals-data +557 { +558 var no-definitions?/eax: boolean <- stream-empty? definitions-created +559 compare no-definitions?, 0/false +560 break-if-!= +561 var curr-index: int +562 var curr-index-a/eax: (addr int) <- address curr-index +563 read-from-stream definitions-created, curr-index-a +564 var curr-offset/eax: (offset global) <- compute-offset globals-data, curr-index +565 var curr-global/ecx: (addr global) <- index globals-data, curr-offset +566 var curr-trace-ah/eax: (addr handle trace) <- get curr-global, trace +567 copy-object trace-ah, curr-trace-ah +568 loop +569 } +570 } +571 +572 fn set-global-cursor-index _globals: (addr global-table), name-gap: (addr gap-buffer) { +573 var globals/esi: (addr global-table) <- copy _globals +574 var name-storage: (stream byte 0x40) +575 var name/ecx: (addr stream byte) <- address name-storage +576 emit-gap-buffer name-gap, name +577 var index/ecx: int <- find-symbol-in-globals globals, name +578 var dest/edi: (addr int) <- get globals, cursor-index +579 copy-to *dest, index +580 } diff --git a/html/shell/grapheme-stack.mu.html b/html/shell/grapheme-stack.mu.html index 139f2f4b..4e5905fb 100644 --- a/html/shell/grapheme-stack.mu.html +++ b/html/shell/grapheme-stack.mu.html @@ -16,6 +16,7 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } .Delimiter { color: #c000c0; } +.muRegEdx { color: #878700; } .muRegEbx { color: #8787af; } .muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } @@ -27,7 +28,6 @@ a { color:inherit; } .muComment { color: #005faf; } .muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } --> @@ -149,9 +149,9 @@ if ('onhashchange' in window) { 84 # dump stack to screen from bottom to top 85 # hardcoded colors: 86 # matching paren - 87 fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _self: (addr grapheme-stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, highlight-matching-open-paren?: boolean, open-paren-depth: int, color: int, background-color: int -> _/eax: int, _/ecx: int { + 87 fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _self: (addr grapheme-stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, highlight-matching-open-paren?: boolean, open-paren-depth: int, color: int, background-color: int -> _/eax: int, _/ecx: int { 88 var self/esi: (addr grapheme-stack) <- copy _self - 89 var matching-open-paren-index/edx: int <- get-matching-open-paren-index self, highlight-matching-open-paren?, open-paren-depth + 89 var matching-open-paren-index/edx: int <- get-matching-open-paren-index self, highlight-matching-open-paren?, open-paren-depth 90 var data-ah/edi: (addr handle array grapheme) <- get self, data 91 var _data/eax: (addr array grapheme) <- lookup *data-ah 92 var data/edi: (addr array grapheme) <- copy _data @@ -183,15 +183,15 @@ if ('onhashchange' in window) { 118 } 119 120 # helper for small words -121 fn render-stack-from-bottom screen: (addr screen), self: (addr grapheme-stack), x: int, y: int, highlight-matching-open-paren?: boolean, open-paren-depth: int -> _/eax: int { +121 fn render-stack-from-bottom screen: (addr screen), self: (addr grapheme-stack), x: int, y: int, highlight-matching-open-paren?: boolean, open-paren-depth: int -> _/eax: int { 122 var _width/eax: int <- copy 0 123 var _height/ecx: int <- copy 0 -124 _width, _height <- screen-size screen +124 _width, _height <- screen-size screen 125 var width/edx: int <- copy _width 126 var height/ebx: int <- copy _height 127 var x2/eax: int <- copy 0 128 var y2/ecx: int <- copy 0 -129 x2, y2 <- render-stack-from-bottom-wrapping-right-then-down screen, self, x, y, width, height, x, y, highlight-matching-open-paren?, open-paren-depth, 3/fg=cyan, 0xc5/bg=blue-bg +129 x2, y2 <- render-stack-from-bottom-wrapping-right-then-down screen, self, x, y, width, height, x, y, highlight-matching-open-paren?, open-paren-depth, 3/fg=cyan, 0xc5/bg=blue-bg 130 return x2 # y2? yolo 131 } 132 @@ -218,7 +218,7 @@ if ('onhashchange' in window) { 153 compare i, 0 154 break-if-< 155 var g/esi: (addr grapheme) <- index data, i -156 x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, color, 7/bg=cursor +156 x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, background-color, color 157 i <- decrement 158 } 159 # remaining iterations @@ -249,7 +249,7 @@ if ('onhashchange' in window) { 184 fn render-stack-from-top screen: (addr screen), self: (addr grapheme-stack), x: int, y: int, render-cursor?: boolean -> _/eax: int { 185 var _width/eax: int <- copy 0 186 var _height/ecx: int <- copy 0 -187 _width, _height <- screen-size screen +187 _width, _height <- screen-size screen 188 var width/edx: int <- copy _width 189 var height/ebx: int <- copy _height 190 var x2/eax: int <- copy 0 @@ -272,22 +272,22 @@ if ('onhashchange' in window) { 207 # setup: screen 208 var screen-on-stack: screen 209 var screen/esi: (addr screen) <- address screen-on-stack -210 initialize-screen screen, 5, 4, 0/no-pixel-graphics +210 initialize-screen screen, 5, 4, 0/no-pixel-graphics 211 # 212 var x/eax: int <- render-stack-from-bottom screen, gs, 0/x, 0/y, 0/no-highlight-matching-open-paren, 0/open-paren-depth 213 check-screen-row screen, 0/y, "abc ", "F - test-render-grapheme-stack from bottom" 214 check-ints-equal x, 3, "F - test-render-grapheme-stack from bottom: result" -215 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-render-grapheme-stack from bottom: bg" +215 check-background-color-in-screen-row screen, 3/bg=reverse, 0/y, " ", "F - test-render-grapheme-stack from bottom: bg" 216 # 217 var x/eax: int <- render-stack-from-top screen, gs, 0/x, 1/y, 0/cursor=false 218 check-screen-row screen, 1/y, "cba ", "F - test-render-grapheme-stack from top without cursor" 219 check-ints-equal x, 3, "F - test-render-grapheme-stack from top without cursor: result" -220 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-render-grapheme-stack from top without cursor: bg" +220 check-background-color-in-screen-row screen, 3/bg=reverse, 1/y, " ", "F - test-render-grapheme-stack from top without cursor: bg" 221 # 222 var x/eax: int <- render-stack-from-top screen, gs, 0/x, 2/y, 1/cursor=true 223 check-screen-row screen, 2/y, "cba ", "F - test-render-grapheme-stack from top with cursor" 224 check-ints-equal x, 3, "F - test-render-grapheme-stack from top with cursor: result" -225 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "| ", "F - test-render-grapheme-stack from top with cursor: bg" +225 check-background-color-in-screen-row screen, 3/bg=reverse, 2/y, "| ", "F - test-render-grapheme-stack from top with cursor: bg" 226 } 227 228 fn test-render-grapheme-stack-while-highlighting-matching-close-paren { @@ -304,12 +304,12 @@ if ('onhashchange' in window) { 239 # setup: screen 240 var screen-on-stack: screen 241 var screen/esi: (addr screen) <- address screen-on-stack -242 initialize-screen screen, 5, 4, 0/no-pixel-graphics +242 initialize-screen screen, 5, 4, 0/no-pixel-graphics 243 # 244 var x/eax: int <- render-stack-from-top screen, gs, 0/x, 2/y, 1/cursor=true 245 check-screen-row screen, 2/y, "(b) ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren" -246 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "| ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren: cursor" -247 check-screen-row-in-color screen, 0xf/fg=white, 2/y, " ) ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren: matching paren" +246 check-background-color-in-screen-row screen, 3/bg=reverse, 2/y, "| ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren: cursor" +247 check-screen-row-in-color screen, 0xf/fg=white, 2/y, " ) ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren: matching paren" 248 } 249 250 fn test-render-grapheme-stack-while-highlighting-matching-close-paren-2 { @@ -338,12 +338,12 @@ if ('onhashchange' in window) { 273 # setup: screen 274 var screen-on-stack: screen 275 var screen/esi: (addr screen) <- address screen-on-stack -276 initialize-screen screen, 5, 4, 0/no-pixel-graphics +276 initialize-screen screen, 5, 4, 0/no-pixel-graphics 277 # 278 var x/eax: int <- render-stack-from-top screen, gs, 0/x, 2/y, 1/cursor=true 279 check-screen-row screen, 2/y, "(a (b)) c ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren-2" -280 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "| ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren-2: cursor" -281 check-screen-row-in-color screen, 0xf/fg=white, 2/y, " ) ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren-2: matching paren" +280 check-background-color-in-screen-row screen, 3/bg=reverse, 2/y, "| ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren-2: cursor" +281 check-screen-row-in-color screen, 0xf/fg=white, 2/y, " ) ", "F - test-render-grapheme-stack-while-highlighting-matching-close-paren-2: matching paren" 282 } 283 284 fn test-render-grapheme-stack-while-highlighting-matching-open-paren-with-close-paren-at-end { @@ -360,11 +360,11 @@ if ('onhashchange' in window) { 295 # setup: screen 296 var screen-on-stack: screen 297 var screen/esi: (addr screen) <- address screen-on-stack -298 initialize-screen screen, 5, 4, 0/no-pixel-graphics +298 initialize-screen screen, 5, 4, 0/no-pixel-graphics 299 # 300 var x/eax: int <- render-stack-from-bottom screen, gs, 0/x, 2/y, 1/highlight-matching-open-paren, 1/open-paren-depth 301 check-screen-row screen, 2/y, "(b) ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-with-close-paren-at-end" -302 check-screen-row-in-color screen, 0xf/fg=white, 2/y, "( ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-with-close-paren-at-end: matching paren" +302 check-screen-row-in-color screen, 0xf/fg=white, 2/y, "( ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-with-close-paren-at-end: matching paren" 303 } 304 305 fn test-render-grapheme-stack-while-highlighting-matching-open-paren-with-close-paren-at-end-2 { @@ -387,11 +387,11 @@ if ('onhashchange' in window) { 322 # setup: screen 323 var screen-on-stack: screen 324 var screen/esi: (addr screen) <- address screen-on-stack -325 initialize-screen screen, 5, 4, 0/no-pixel-graphics +325 initialize-screen screen, 5, 4, 0/no-pixel-graphics 326 # 327 var x/eax: int <- render-stack-from-bottom screen, gs, 0/x, 2/y, 1/highlight-matching-open-paren, 1/open-paren-depth 328 check-screen-row screen, 2/y, "a((b)) ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-with-close-paren-at-end-2" -329 check-screen-row-in-color screen, 0xf/fg=white, 2/y, " ( ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-with-close-paren-at-end-2: matching paren" +329 check-screen-row-in-color screen, 0xf/fg=white, 2/y, " ( ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-with-close-paren-at-end-2: matching paren" 330 } 331 332 fn test-render-grapheme-stack-while-highlighting-matching-open-paren { @@ -406,11 +406,11 @@ if ('onhashchange' in window) { 341 # setup: screen 342 var screen-on-stack: screen 343 var screen/esi: (addr screen) <- address screen-on-stack -344 initialize-screen screen, 5, 4, 0/no-pixel-graphics +344 initialize-screen screen, 5, 4, 0/no-pixel-graphics 345 # 346 var x/eax: int <- render-stack-from-bottom screen, gs, 0/x, 2/y, 1/highlight-matching-open-paren, 0/open-paren-depth 347 check-screen-row screen, 2/y, "(b ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren" -348 check-screen-row-in-color screen, 0xf/fg=white, 2/y, "( ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren: matching paren" +348 check-screen-row-in-color screen, 0xf/fg=white, 2/y, "( ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren: matching paren" 349 } 350 351 fn test-render-grapheme-stack-while-highlighting-matching-open-paren-2 { @@ -431,11 +431,11 @@ if ('onhashchange' in window) { 366 # setup: screen 367 var screen-on-stack: screen 368 var screen/esi: (addr screen) <- address screen-on-stack -369 initialize-screen screen, 5, 4, 0/no-pixel-graphics +369 initialize-screen screen, 5, 4, 0/no-pixel-graphics 370 # 371 var x/eax: int <- render-stack-from-bottom screen, gs, 0/x, 2/y, 1/highlight-matching-open-paren, 0/open-paren-depth 372 check-screen-row screen, 2/y, "a((b) ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-2" -373 check-screen-row-in-color screen, 0xf/fg=white, 2/y, " ( ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-2: matching paren" +373 check-screen-row-in-color screen, 0xf/fg=white, 2/y, " ( ", "F - test-render-grapheme-stack-while-highlighting-matching-open-paren-2: matching paren" 374 } 375 376 # return the index of the matching close-paren of the grapheme at cursor (top of stack) diff --git a/html/shell/macroexpand.mu.html b/html/shell/macroexpand.mu.html index 6aa63bf1..6abe8101 100644 --- a/html/shell/macroexpand.mu.html +++ b/html/shell/macroexpand.mu.html @@ -16,7 +16,8 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } .Delimiter { color: #c000c0; } -.CommentedCode { color: #8a8a8a; } +.muFunction { color: #af5f00; text-decoration: underline; } +.muRegEdx { color: #878700; } .muRegEbx { color: #8787af; } .muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } @@ -24,12 +25,11 @@ a { color:inherit; } .Special { color: #ff6060; } .PreProc { color: #c000c0; } .Folded { color: #080808; background-color: #949494; } -.muFunction { color: #af5f00; text-decoration: underline; } +.CommentedCode { color: #8a8a8a; } .muTest { color: #5f8700; } .muComment { color: #005faf; } .muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } --> @@ -111,8 +111,8 @@ if ('onhashchange' in window) { 86 var rest-ah/ecx: (addr handle cell) <- get expr, right 87 var first/eax: (addr cell) <- lookup *first-ah 88 { - 89 var litfn?/eax: boolean <- litfn? first - 90 compare litfn?, 0/false + 89 var litfn?/eax: boolean <- litfn? first + 90 compare litfn?, 0/false 91 break-if-= 92 # litfn is a literal 93 trace-text trace, "mac", "literal function" @@ -120,8 +120,8 @@ if ('onhashchange' in window) { 95 return 0/false 96 } 97 { - 98 var litmac?/eax: boolean <- litmac? first - 99 compare litmac?, 0/false + 98 var litmac?/eax: boolean <- litmac? first + 99 compare litmac?, 0/false 100 break-if-= 101 # litmac is a literal 102 trace-text trace, "mac", "literal macro" @@ -131,8 +131,8 @@ if ('onhashchange' in window) { 106 var result/edi: boolean <- copy 0/false 107 # for each builtin, expand only what will later be evaluated 108 $macroexpand-iter:anonymous-function: { -109 var fn?/eax: boolean <- fn? first -110 compare fn?, 0/false +109 var fn?/eax: boolean <- fn? first +110 compare fn?, 0/false 111 break-if-= 112 # fn: expand every expression in the body 113 trace-text trace, "mac", "anonymous function" @@ -230,7 +230,7 @@ if ('onhashchange' in window) { 247 { 248 var definition-h: (handle cell) 249 var definition-ah/edx: (addr handle cell) <- address definition-h -250 maybe-lookup-symbol-in-globals first, definition-ah, globals, trace +250 maybe-lookup-symbol-in-globals first, definition-ah, globals, trace 251 var definition/eax: (addr cell) <- lookup *definition-ah 252 compare definition, 0 253 break-if-= @@ -244,7 +244,7 @@ if ('onhashchange' in window) { 261 { 262 var definition-car-ah/eax: (addr handle cell) <- get definition, left 263 var definition-car/eax: (addr cell) <- lookup *definition-car-ah -264 var macro?/eax: boolean <- litmac? definition-car +264 var macro?/eax: boolean <- litmac? definition-car 265 compare macro?, 0/false 266 } 267 break-if-= @@ -252,7 +252,7 @@ if ('onhashchange' in window) { 269 var macro-definition-ah/eax: (addr handle cell) <- get definition, right 270 # TODO: check car(macro-definition) is litfn 271 #? turn-on-debug-print -272 apply macro-definition-ah, rest-ah, expr-ah, globals, trace, 0/no-screen, 0/no-keyboard, 0/call-number +272 apply macro-definition-ah, rest-ah, expr-ah, globals, trace, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number 273 trace-higher trace 274 +-- 15 lines: # trace "1=> " _expr-ah --------------------------------------------------------------------------------------------------------------------------------------------------- 289 return 1/true @@ -301,29 +301,29 @@ if ('onhashchange' in window) { 346 } 347 var cdr-ah/ecx: (addr handle cell) <- get expr, right 348 var car-ah/ebx: (addr handle cell) <- get expr, left -349 var car/eax: (addr cell) <- lookup *car-ah +349 var car/eax: (addr cell) <- lookup *car-ah 350 # if car is unquote or unquote-splice, check if cadr is unquote or 351 # unquote-splice. 352 $look-for-double-unquote:check: { 353 # if car is not an unquote, break 354 { 355 { -356 var unquote?/eax: boolean <- symbol-equal? car, "," +356 var unquote?/eax: boolean <- symbol-equal? car, "," 357 compare unquote?, 0/false 358 } 359 break-if-!= -360 var unquote-splice?/eax: boolean <- symbol-equal? car, ",@" +360 var unquote-splice?/eax: boolean <- symbol-equal? car, ",@" 361 compare unquote-splice?, 0/false 362 break-if-!= 363 break $look-for-double-unquote:check 364 } 365 # if cdr is not a pair, break -366 var cdr/eax: (addr cell) <- lookup *cdr-ah -367 var cdr-type/ecx: (addr int) <- get cdr, type +366 var cdr/eax: (addr cell) <- lookup *cdr-ah +367 var cdr-type/ecx: (addr int) <- get cdr, type 368 compare *cdr-type, 0/pair 369 break-if-!= 370 # if cadr is not an unquote, break -371 var cadr-ah/eax: (addr handle cell) <- get cdr, left +371 var cadr-ah/eax: (addr handle cell) <- get cdr, left 372 var cadr/eax: (addr cell) <- lookup *cadr-ah 373 { 374 { @@ -352,12 +352,12 @@ if ('onhashchange' in window) { 397 fn test-macroexpand { 398 var globals-storage: global-table 399 var globals/edx: (addr global-table) <- address globals-storage -400 initialize-globals globals +400 initialize-globals globals 401 # new macro: m 402 var sandbox-storage: sandbox 403 var sandbox/esi: (addr sandbox) <- address sandbox-storage 404 initialize-sandbox-with sandbox, "(define m (litmac litfn () (a b) `(+ ,a ,b)))" -405 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk, 0/no-tweak-screen +405 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk 406 # invoke macro 407 initialize-sandbox-with sandbox, "(m 3 4)" 408 var gap-ah/ecx: (addr handle gap-buffer) <- get sandbox, data @@ -384,19 +384,19 @@ if ('onhashchange' in window) { 429 #? dump-cell-from-cursor-over-full-screen expected-ah 430 var expected/eax: (addr cell) <- lookup *expected-ah 431 # -432 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace +432 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace 433 check assertion, "F - test-macroexpand" 434 } 435 436 fn test-macroexpand-inside-anonymous-fn { 437 var globals-storage: global-table 438 var globals/edx: (addr global-table) <- address globals-storage -439 initialize-globals globals +439 initialize-globals globals 440 # new macro: m 441 var sandbox-storage: sandbox 442 var sandbox/esi: (addr sandbox) <- address sandbox-storage 443 initialize-sandbox-with sandbox, "(define m (litmac litfn () (a b) `(+ ,a ,b)))" -444 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk, 0/no-tweak-screen +444 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk 445 # invoke macro 446 initialize-sandbox-with sandbox, "(fn() (m 3 4))" 447 var gap-ah/ecx: (addr handle gap-buffer) <- get sandbox, data @@ -422,19 +422,19 @@ if ('onhashchange' in window) { 467 read-cell expected-gap, expected-ah, trace 468 var expected/eax: (addr cell) <- lookup *expected-ah 469 # -470 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace +470 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace 471 check assertion, "F - test-macroexpand-inside-anonymous-fn" 472 } 473 474 fn test-macroexpand-inside-fn-call { 475 var globals-storage: global-table 476 var globals/edx: (addr global-table) <- address globals-storage -477 initialize-globals globals +477 initialize-globals globals 478 # new macro: m 479 var sandbox-storage: sandbox 480 var sandbox/esi: (addr sandbox) <- address sandbox-storage 481 initialize-sandbox-with sandbox, "(define m (litmac litfn () (a b) `(+ ,a ,b)))" -482 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk, 0/no-tweak-screen +482 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk 483 # invoke macro 484 initialize-sandbox-with sandbox, "((fn() (m 3 4)))" 485 var gap-ah/ecx: (addr handle gap-buffer) <- get sandbox, data @@ -461,14 +461,14 @@ if ('onhashchange' in window) { 506 #? dump-cell-from-cursor-over-full-screen expected-ah 507 var expected/eax: (addr cell) <- lookup *expected-ah 508 # -509 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace +509 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace 510 check assertion, "F - test-macroexpand-inside-fn-call" 511 } 512 513 fn test-macroexpand-repeatedly-with-backquoted-arg { 514 var globals-storage: global-table 515 var globals/edx: (addr global-table) <- address globals-storage -516 initialize-globals globals +516 initialize-globals globals 517 # macroexpand an expression with a backquote but no macro 518 var sandbox-storage: sandbox 519 var sandbox/esi: (addr sandbox) <- address sandbox-storage @@ -498,12 +498,12 @@ if ('onhashchange' in window) { 543 fn pending-test-macroexpand-inside-backquote-unquote { 544 var globals-storage: global-table 545 var globals/edx: (addr global-table) <- address globals-storage -546 initialize-globals globals +546 initialize-globals globals 547 # new macro: m 548 var sandbox-storage: sandbox 549 var sandbox/esi: (addr sandbox) <- address sandbox-storage 550 initialize-sandbox-with sandbox, "(define m (litmac litfn () (a b) `(+ ,a ,b)))" -551 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk, 0/no-tweak-screen +551 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk 552 # invoke macro 553 initialize-sandbox-with sandbox, "`(print [result is ] ,(m 3 4)))" 554 var gap-ah/ecx: (addr handle gap-buffer) <- get sandbox, data @@ -529,19 +529,19 @@ if ('onhashchange' in window) { 574 read-cell expected-gap, expected-ah, trace 575 var expected/eax: (addr cell) <- lookup *expected-ah 576 # -577 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace +577 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace 578 check assertion, "F - test-macroexpand-inside-backquote-unquote" 579 } 580 581 fn pending-test-macroexpand-inside-nested-backquote-unquote { 582 var globals-storage: global-table 583 var globals/edx: (addr global-table) <- address globals-storage -584 initialize-globals globals +584 initialize-globals globals 585 # new macro: m 586 var sandbox-storage: sandbox 587 var sandbox/esi: (addr sandbox) <- address sandbox-storage 588 initialize-sandbox-with sandbox, "(define m (litmac litfn () (a b) `(+ ,a ,b)))" -589 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk, 0/no-tweak-screen +589 edit-sandbox sandbox, 0x13/ctrl-s, globals, 0/no-disk 590 # invoke macro 591 initialize-sandbox-with sandbox, "`(a ,(m 3 4) `(b ,(m 3 4) ,,(m 3 4)))" 592 var gap-ah/ecx: (addr handle gap-buffer) <- get sandbox, data @@ -568,7 +568,7 @@ if ('onhashchange' in window) { 613 dump-cell-from-cursor-over-full-screen expected-ah 614 var expected/eax: (addr cell) <- lookup *expected-ah 615 # -616 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace +616 var assertion/eax: boolean <- cell-isomorphic? result, expected, trace 617 check assertion, "F - test-macroexpand-inside-nested-backquote-unquote" 618 } 619 diff --git a/html/shell/main.mu.html b/html/shell/main.mu.html index 581fe0cf..d1b6b559 100644 --- a/html/shell/main.mu.html +++ b/html/shell/main.mu.html @@ -59,22 +59,22 @@ if ('onhashchange' in window) { https://github.com/akkartik/mu/blob/main/shell/main.mu
  1 # Experimental Mu shell
- 2 # A Lisp with indent-sensitivity and infix.
+ 2 # Currently based on Lisp.
  3 
  4 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
- 5   var env-storage: environment
- 6   var env/esi: (addr environment) <- address env-storage
- 7   initialize-environment env
- 8   load-state env, data-disk
+ 5   var env-storage: environment
+ 6   var env/esi: (addr environment) <- address env-storage
+ 7   initialize-environment env, 0x20/fake-screen-width, 8/fake-screen-height
+ 8   load-state env, data-disk
  9   $main:loop: {
-10     render-environment screen, env
+10     render-environment screen, env
 11     # no way to quit right now; just reboot
 12     {
 13       var key/eax: byte <- read-key keyboard
 14       compare key, 0
 15       loop-if-=
 16       var key/eax: grapheme <- copy key
-17       edit-environment env, key, data-disk
+17       edit-environment env, key, data-disk
 18     }
 19     loop
 20   }
diff --git a/html/shell/parse.mu.html b/html/shell/parse.mu.html
index f59031b4..e61f4c23 100644
--- a/html/shell/parse.mu.html
+++ b/html/shell/parse.mu.html
@@ -15,16 +15,16 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color:
 a { color:inherit; }
 * { font-size:12pt; font-size: 1em; }
 .PreProc { color: #c000c0; }
-.muRegEdx { color: #878700; }
+.muRegEcx { color: #af875f; }
 .LineNr { }
 .muRegEdi { color: #87ffd7; }
-.muRegEsi { color: #87d787; }
 .muComment { color: #005faf; }
 .Constant { color: #008787; }
+.muRegEdx { color: #878700; }
 .muRegEax { color: #875f00; }
-.muRegEcx { color: #af875f; }
 .Delimiter { color: #c000c0; }
 .muFunction { color: #af5f00; text-decoration: underline; }
+.muRegEsi { color: #87d787; }
 .Special { color: #ff6060; }
 -->
 
@@ -106,8 +106,8 @@ if ('onhashchange' in window) {
  43   read-from-stream tokens, curr-token
  44   $parse-sexpression:type-check: {
  45     # single quote -> parse as list with a special car
- 46     var quote-token?/eax: boolean <- quote-token? curr-token
- 47     compare quote-token?, 0/false
+ 46     var quote-token?/eax: boolean <- quote-token? curr-token
+ 47     compare quote-token?, 0/false
  48     {
  49       break-if-=
  50       var out/edi: (addr handle cell) <- copy _out
@@ -123,8 +123,8 @@ if ('onhashchange' in window) {
  60       return close-paren?, dot?
  61     }
  62     # backquote quote -> parse as list with a special car
- 63     var backquote-token?/eax: boolean <- backquote-token? curr-token
- 64     compare backquote-token?, 0/false
+ 63     var backquote-token?/eax: boolean <- backquote-token? curr-token
+ 64     compare backquote-token?, 0/false
  65     {
  66       break-if-=
  67       var out/edi: (addr handle cell) <- copy _out
@@ -140,8 +140,8 @@ if ('onhashchange' in window) {
  77       return close-paren?, dot?
  78     }
  79     # unquote -> parse as list with a special car
- 80     var unquote-token?/eax: boolean <- unquote-token? curr-token
- 81     compare unquote-token?, 0/false
+ 80     var unquote-token?/eax: boolean <- unquote-token? curr-token
+ 81     compare unquote-token?, 0/false
  82     {
  83       break-if-=
  84       var out/edi: (addr handle cell) <- copy _out
@@ -157,8 +157,8 @@ if ('onhashchange' in window) {
  94       return close-paren?, dot?
  95     }
  96     # unquote-splice -> parse as list with a special car
- 97     var unquote-splice-token?/eax: boolean <- unquote-splice-token? curr-token
- 98     compare unquote-splice-token?, 0/false
+ 97     var unquote-splice-token?/eax: boolean <- unquote-splice-token? curr-token
+ 98     compare unquote-splice-token?, 0/false
  99     {
 100       break-if-=
 101       var out/edi: (addr handle cell) <- copy _out
@@ -174,7 +174,7 @@ if ('onhashchange' in window) {
 111       return close-paren?, dot?
 112     }
 113     # dot -> return
-114     var dot?/eax: boolean <- dot-token? curr-token
+114     var dot?/eax: boolean <- dot-token? curr-token
 115     compare dot?, 0/false
 116     {
 117       break-if-=
@@ -182,15 +182,15 @@ if ('onhashchange' in window) {
 119       return 0/false, 1/true
 120     }
 121     # not bracket -> parse atom
-122     var bracket-token?/eax: boolean <- bracket-token? curr-token
-123     compare bracket-token?, 0/false
+122     var bracket-token?/eax: boolean <- bracket-token? curr-token
+123     compare bracket-token?, 0/false
 124     {
 125       break-if-!=
 126       parse-atom curr-token, _out, trace
 127       break $parse-sexpression:type-check
 128     }
 129     # open paren -> parse list
-130     var open-paren?/eax: boolean <- open-paren-token? curr-token
+130     var open-paren?/eax: boolean <- open-paren-token? curr-token
 131     compare open-paren?, 0/false
 132     {
 133       break-if-=
@@ -240,7 +240,7 @@ if ('onhashchange' in window) {
 177       break $parse-sexpression:type-check
 178     }
 179     # close paren -> return
-180     var close-paren?/eax: boolean <- close-paren-token? curr-token
+180     var close-paren?/eax: boolean <- close-paren-token? curr-token
 181     compare close-paren?, 0/false
 182     {
 183       break-if-=
@@ -269,8 +269,8 @@ if ('onhashchange' in window) {
 206   var curr-token-data/esi: (addr stream byte) <- copy _curr-token-data
 207   trace trace, "parse", curr-token-data
 208   # number
-209   var number-token?/eax: boolean <- number-token? curr-token
-210   compare number-token?, 0/false
+209   var number-token?/eax: boolean <- number-token? curr-token
+210   compare number-token?, 0/false
 211   {
 212     break-if-=
 213     rewind-stream curr-token-data
@@ -301,13 +301,13 @@ if ('onhashchange' in window) {
 238   }
 239   # default: copy either to a symbol or a stream
 240   # stream token -> literal
-241   var stream-token?/eax: boolean <- stream-token? curr-token
-242   compare stream-token?, 0/false
+241   var stream-token?/eax: boolean <- stream-token? curr-token
+242   compare stream-token?, 0/false
 243   {
 244     break-if-=
 245     allocate-stream _out
 246   }
-247   compare stream-token?, 0/false
+247   compare stream-token?, 0/false
 248   {
 249     break-if-!=
 250     allocate-symbol _out
diff --git a/html/shell/primitives.mu.html b/html/shell/primitives.mu.html
index b050cfba..851a30c5 100644
--- a/html/shell/primitives.mu.html
+++ b/html/shell/primitives.mu.html
@@ -16,18 +16,19 @@ a { color:inherit; }
 * { font-size:12pt; font-size: 1em; }
 .LineNr { }
 .Delimiter { color: #c000c0; }
-.muFunction { color: #af5f00; text-decoration: underline; }
+.CommentedCode { color: #8a8a8a; }
+.muRegEdx { color: #878700; }
 .muRegEbx { color: #8787af; }
 .muRegEsi { color: #87d787; }
 .muRegEdi { color: #87ffd7; }
 .Constant { color: #008787; }
 .Special { color: #ff6060; }
 .PreProc { color: #c000c0; }
-.CommentedCode { color: #8a8a8a; }
+.muFunction { color: #af5f00; text-decoration: underline; }
+.muTest { color: #5f8700; }
 .muComment { color: #005faf; }
 .muRegEax { color: #875f00; }
 .muRegEcx { color: #af875f; }
-.muRegEdx { color: #878700; }
 -->
 
 
@@ -66,1603 +67,2110 @@ if ('onhashchange' in window) {
    1 fn initialize-primitives _self: (addr global-table) {
    2   var self/esi: (addr global-table) <- copy _self
    3   # for numbers
-   4   append-primitive self, "+"
-   5   append-primitive self, "-"
-   6   append-primitive self, "*"
-   7   append-primitive self, "/"
-   8   append-primitive self, "sqrt"
-   9   append-primitive self, "abs"
-  10   append-primitive self, "sgn"
-  11   append-primitive self, "<"
-  12   append-primitive self, ">"
-  13   append-primitive self, "<="
-  14   append-primitive self, ">="
-  15   # generic
-  16   append-primitive self, "="
-  17   append-primitive self, "no"
-  18   append-primitive self, "not"
-  19   append-primitive self, "dbg"
-  20   # for pairs
-  21   append-primitive self, "car"
-  22   append-primitive self, "cdr"
-  23   append-primitive self, "cons"
-  24   # for screens
-  25   append-primitive self, "print"
-  26   append-primitive self, "clear"
-  27   append-primitive self, "lines"
-  28   append-primitive self, "columns"
-  29   append-primitive self, "up"
-  30   append-primitive self, "down"
-  31   append-primitive self, "left"
-  32   append-primitive self, "right"
-  33   append-primitive self, "cr"
-  34   append-primitive self, "pixel"
-  35   append-primitive self, "width"
-  36   append-primitive self, "height"
-  37   # for keyboards
-  38   append-primitive self, "key"
-  39   # for streams
-  40   append-primitive self, "stream"
-  41   append-primitive self, "write"
-  42   # misc
-  43   append-primitive self, "abort"
-  44   # keep sync'd with render-primitives
-  45 }
-  46 
-  47 fn render-primitives screen: (addr screen), xmin: int, xmax: int, ymax: int {
-  48   var y/ecx: int <- copy ymax
-  49   y <- subtract 0x10
-  50   clear-rect screen, xmin, y, xmax, ymax, 0xdc/bg=green-bg
-  51   y <- increment
-  52   var tmpx/eax: int <- copy xmin
-  53   tmpx <- draw-text-rightward screen, "cursor graphics", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  54   y <- increment
-  55   var tmpx/eax: int <- copy xmin
-  56   tmpx <- draw-text-rightward screen, "  print", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  57   tmpx <- draw-text-rightward screen, ": screen a -> a", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  58   y <- increment
-  59   var tmpx/eax: int <- copy xmin
-  60   tmpx <- draw-text-rightward screen, "  lines columns", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  61   tmpx <- draw-text-rightward screen, ": screen -> number", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  62   y <- increment
-  63   var tmpx/eax: int <- copy xmin
-  64   tmpx <- draw-text-rightward screen, "  up down left right", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  65   tmpx <- draw-text-rightward screen, ": screen", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  66   y <- increment
-  67   var tmpx/eax: int <- copy xmin
-  68   tmpx <- draw-text-rightward screen, "  cr", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  69   tmpx <- draw-text-rightward screen, ": screen   ", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  70   tmpx <- draw-text-rightward screen, "# move cursor down and to left margin", tmpx, xmax, y, 0x38/fg=trace, 0xdc/bg=green-bg
-  71   y <- increment
-  72   var tmpx/eax: int <- copy xmin
-  73   tmpx <- draw-text-rightward screen, "pixel graphics", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  74   y <- increment
-  75   var tmpx/eax: int <- copy xmin
-  76   tmpx <- draw-text-rightward screen, "  width height", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  77   tmpx <- draw-text-rightward screen, ": screen -> number", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  78   y <- increment
-  79   var tmpx/eax: int <- copy xmin
-  80   tmpx <- draw-text-rightward screen, "  pixel", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  81   tmpx <- draw-text-rightward screen, ": screen x y color", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  82   y <- increment
-  83   var tmpx/eax: int <- copy xmin
-  84   tmpx <- draw-text-rightward screen, "screen/keyboard", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  85   y <- increment
-  86   var tmpx/eax: int <- copy xmin
-  87   tmpx <- draw-text-rightward screen, "  clear", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  88   tmpx <- draw-text-rightward screen, ": screen", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  89   y <- increment
-  90   var tmpx/eax: int <- copy xmin
-  91   tmpx <- draw-text-rightward screen, "  key", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  92   tmpx <- draw-text-rightward screen, ": () -> grapheme?", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  93   y <- increment
-  94   var tmpx/eax: int <- copy xmin
-  95   tmpx <- draw-text-rightward screen, "streams", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
-  96   y <- increment
-  97   var tmpx/eax: int <- copy xmin
-  98   tmpx <- draw-text-rightward screen, "  stream", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
-  99   tmpx <- draw-text-rightward screen, ": () -> stream ", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
- 100   y <- increment
- 101   var tmpx/eax: int <- copy xmin
- 102   tmpx <- draw-text-rightward screen, "  write", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
- 103   tmpx <- draw-text-rightward screen, ": stream grapheme -> stream", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
- 104   y <- increment
- 105   var tmpx/eax: int <- copy xmin
- 106   tmpx <- draw-text-rightward screen, "fn def set if while = no(t) car cdr cons  ", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
- 107   tmpx <- draw-text-rightward screen, "num: ", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
- 108   tmpx <- draw-text-rightward screen, "+ - * / sqrt abs sgn < > <= >=   ", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
- 109 }
- 110 
- 111 fn primitive-global? _x: (addr global) -> _/eax: boolean {
- 112   var x/eax: (addr global) <- copy _x
- 113   var value-ah/eax: (addr handle cell) <- get x, value
- 114   var value/eax: (addr cell) <- lookup *value-ah
- 115   compare value, 0/null
- 116   {
- 117     break-if-!=
- 118     return 0/false
- 119   }
- 120   var value-type/eax: (addr int) <- get value, type
- 121   compare *value-type, 4/primitive
- 122   {
- 123     break-if-=
- 124     return 0/false
- 125   }
- 126   return 1/true
- 127 }
- 128 
- 129 fn append-primitive _self: (addr global-table), name: (addr array byte) {
- 130   var self/esi: (addr global-table) <- copy _self
- 131   compare self, 0
- 132   {
- 133     break-if-!=
- 134     abort "append primitive"
- 135     return
- 136   }
- 137   var final-index-addr/ecx: (addr int) <- get self, final-index
- 138   increment *final-index-addr
- 139   var curr-index/ecx: int <- copy *final-index-addr
- 140   var data-ah/eax: (addr handle array global) <- get self, data
- 141   var data/eax: (addr array global) <- lookup *data-ah
- 142   var curr-offset/esi: (offset global) <- compute-offset data, curr-index
- 143   var curr/esi: (addr global) <- index data, curr-offset
- 144   var curr-name-ah/eax: (addr handle array byte) <- get curr, name
- 145   copy-array-object name, curr-name-ah
- 146   var curr-value-ah/eax: (addr handle cell) <- get curr, value
- 147   new-primitive-function curr-value-ah, curr-index
- 148 }
- 149 
- 150 # a little strange; goes from value to name and selects primitive based on name
- 151 fn apply-primitive _f: (addr cell), args-ah: (addr handle cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace) {
- 152   var f/esi: (addr cell) <- copy _f
- 153   var f-index-a/ecx: (addr int) <- get f, index-data
- 154   var f-index/ecx: int <- copy *f-index-a
- 155   var globals/eax: (addr global-table) <- copy _globals
- 156   compare globals, 0
- 157   {
- 158     break-if-!=
- 159     abort "apply primitive"
- 160     return
- 161   }
- 162   var global-data-ah/eax: (addr handle array global) <- get globals, data
- 163   var global-data/eax: (addr array global) <- lookup *global-data-ah
- 164   var f-offset/ecx: (offset global) <- compute-offset global-data, f-index
- 165   var f-value/ecx: (addr global) <- index global-data, f-offset
- 166   var f-name-ah/ecx: (addr handle array byte) <- get f-value, name
- 167   var f-name/eax: (addr array byte) <- lookup *f-name-ah
- 168   {
- 169     var add?/eax: boolean <- string-equal? f-name, "+"
- 170     compare add?, 0/false
- 171     break-if-=
- 172     apply-add args-ah, out, trace
- 173     return
- 174   }
- 175   {
- 176     var subtract?/eax: boolean <- string-equal? f-name, "-"
- 177     compare subtract?, 0/false
- 178     break-if-=
- 179     apply-subtract args-ah, out, trace
- 180     return
- 181   }
- 182   {
- 183     var multiply?/eax: boolean <- string-equal? f-name, "*"
- 184     compare multiply?, 0/false
- 185     break-if-=
- 186     apply-multiply args-ah, out, trace
- 187     return
- 188   }
- 189   {
- 190     var divide?/eax: boolean <- string-equal? f-name, "/"
- 191     compare divide?, 0/false
- 192     break-if-=
- 193     apply-divide args-ah, out, trace
- 194     return
- 195   }
- 196   {
- 197     var square-root?/eax: boolean <- string-equal? f-name, "sqrt"
- 198     compare square-root?, 0/false
- 199     break-if-=
- 200     apply-square-root args-ah, out, trace
- 201     return
- 202   }
+   4   append-primitive self, "+"
+   5   append-primitive self, "-"
+   6   append-primitive self, "*"
+   7   append-primitive self, "/"
+   8   append-primitive self, "%"
+   9   append-primitive self, "sqrt"
+  10   append-primitive self, "abs"
+  11   append-primitive self, "sgn"
+  12   append-primitive self, "<"
+  13   append-primitive self, ">"
+  14   append-primitive self, "<="
+  15   append-primitive self, ">="
+  16   # generic
+  17   append-primitive self, "="
+  18   append-primitive self, "no"
+  19   append-primitive self, "not"
+  20   append-primitive self, "dbg"
+  21   # for pairs
+  22   append-primitive self, "car"
+  23   append-primitive self, "cdr"
+  24   append-primitive self, "cons"
+  25   # for screens
+  26   append-primitive self, "print"
+  27   append-primitive self, "clear"
+  28   append-primitive self, "lines"
+  29   append-primitive self, "columns"
+  30   append-primitive self, "up"
+  31   append-primitive self, "down"
+  32   append-primitive self, "left"
+  33   append-primitive self, "right"
+  34   append-primitive self, "cr"
+  35   append-primitive self, "pixel"
+  36   append-primitive self, "width"
+  37   append-primitive self, "height"
+  38   # for keyboards
+  39   append-primitive self, "key"
+  40   # for streams
+  41   append-primitive self, "stream"
+  42   append-primitive self, "write"
+  43   # misc
+  44   append-primitive self, "abort"
+  45   # keep sync'd with render-primitives
+  46 }
+  47 
+  48 fn render-primitives screen: (addr screen), xmin: int, xmax: int, ymax: int {
+  49   var y/ecx: int <- copy ymax
+  50   y <- subtract 0x10
+  51   clear-rect screen, xmin, y, xmax, ymax, 0xdc/bg=green-bg
+  52   y <- increment
+  53   var tmpx/eax: int <- copy xmin
+  54   tmpx <- draw-text-rightward screen, "cursor graphics", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  55   y <- increment
+  56   var tmpx/eax: int <- copy xmin
+  57   tmpx <- draw-text-rightward screen, "  print", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+  58   tmpx <- draw-text-rightward screen, ": screen a -> a", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  59   y <- increment
+  60   var tmpx/eax: int <- copy xmin
+  61   tmpx <- draw-text-rightward screen, "  lines columns", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+  62   tmpx <- draw-text-rightward screen, ": screen -> number", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  63   y <- increment
+  64   var tmpx/eax: int <- copy xmin
+  65   tmpx <- draw-text-rightward screen, "  up down left right", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+  66   tmpx <- draw-text-rightward screen, ": screen", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  67   y <- increment
+  68   var tmpx/eax: int <- copy xmin
+  69   tmpx <- draw-text-rightward screen, "  cr", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+  70   tmpx <- draw-text-rightward screen, ": screen   ", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  71   tmpx <- draw-text-rightward screen, "# move cursor down and to left margin", tmpx, xmax, y, 0x38/fg=trace, 0xdc/bg=green-bg
+  72   y <- increment
+  73   var tmpx/eax: int <- copy xmin
+  74   tmpx <- draw-text-rightward screen, "pixel graphics", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  75   y <- increment
+  76   var tmpx/eax: int <- copy xmin
+  77   tmpx <- draw-text-rightward screen, "  width height", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+  78   tmpx <- draw-text-rightward screen, ": screen -> number", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  79   y <- increment
+  80   var tmpx/eax: int <- copy xmin
+  81   tmpx <- draw-text-rightward screen, "  pixel", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+  82   tmpx <- draw-text-rightward screen, ": screen x y color", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  83   y <- increment
+  84   var tmpx/eax: int <- copy xmin
+  85   tmpx <- draw-text-rightward screen, "screen/keyboard", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  86   y <- increment
+  87   var tmpx/eax: int <- copy xmin
+  88   tmpx <- draw-text-rightward screen, "  clear", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+  89   tmpx <- draw-text-rightward screen, ": screen", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  90   y <- increment
+  91   var tmpx/eax: int <- copy xmin
+  92   tmpx <- draw-text-rightward screen, "  key", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+  93   tmpx <- draw-text-rightward screen, ": () -> grapheme?", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  94   y <- increment
+  95   var tmpx/eax: int <- copy xmin
+  96   tmpx <- draw-text-rightward screen, "streams", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+  97   y <- increment
+  98   var tmpx/eax: int <- copy xmin
+  99   tmpx <- draw-text-rightward screen, "  stream", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+ 100   tmpx <- draw-text-rightward screen, ": () -> stream ", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+ 101   y <- increment
+ 102   var tmpx/eax: int <- copy xmin
+ 103   tmpx <- draw-text-rightward screen, "  write", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+ 104   tmpx <- draw-text-rightward screen, ": stream grapheme -> stream", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
+ 105   y <- increment
+ 106   var tmpx/eax: int <- copy xmin
+ 107   tmpx <- draw-text-rightward screen, "fn set if while cons car cdr no not and or = ", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+ 108   # numbers
+ 109   tmpx <- draw-text-rightward screen, "< > <= >= + - * / % sqrt abs sgn", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
+ 110 }
+ 111 
+ 112 fn primitive-global? _x: (addr global) -> _/eax: boolean {
+ 113   var x/eax: (addr global) <- copy _x
+ 114   var value-ah/eax: (addr handle cell) <- get x, value
+ 115   var value/eax: (addr cell) <- lookup *value-ah
+ 116   compare value, 0/null
+ 117   {
+ 118     break-if-!=
+ 119     return 0/false
+ 120   }
+ 121   var value-type/eax: (addr int) <- get value, type
+ 122   compare *value-type, 4/primitive
+ 123   {
+ 124     break-if-=
+ 125     return 0/false
+ 126   }
+ 127   return 1/true
+ 128 }
+ 129 
+ 130 fn append-primitive _self: (addr global-table), name: (addr array byte) {
+ 131   var self/esi: (addr global-table) <- copy _self
+ 132   compare self, 0
+ 133   {
+ 134     break-if-!=
+ 135     abort "append primitive"
+ 136     return
+ 137   }
+ 138   var final-index-addr/ecx: (addr int) <- get self, final-index
+ 139   increment *final-index-addr
+ 140   var curr-index/ecx: int <- copy *final-index-addr
+ 141   var data-ah/eax: (addr handle array global) <- get self, data
+ 142   var data/eax: (addr array global) <- lookup *data-ah
+ 143   var curr-offset/esi: (offset global) <- compute-offset data, curr-index
+ 144   var curr/esi: (addr global) <- index data, curr-offset
+ 145   var curr-name-ah/eax: (addr handle array byte) <- get curr, name
+ 146   copy-array-object name, curr-name-ah
+ 147   var curr-value-ah/eax: (addr handle cell) <- get curr, value
+ 148   new-primitive-function curr-value-ah, curr-index
+ 149 }
+ 150 
+ 151 # a little strange; goes from value to name and selects primitive based on name
+ 152 fn apply-primitive _f: (addr cell), args-ah: (addr handle cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace) {
+ 153   var f/esi: (addr cell) <- copy _f
+ 154   var f-index-a/ecx: (addr int) <- get f, index-data
+ 155   var f-index/ecx: int <- copy *f-index-a
+ 156   var globals/eax: (addr global-table) <- copy _globals
+ 157   compare globals, 0
+ 158   {
+ 159     break-if-!=
+ 160     abort "apply primitive"
+ 161     return
+ 162   }
+ 163   var global-data-ah/eax: (addr handle array global) <- get globals, data
+ 164   var global-data/eax: (addr array global) <- lookup *global-data-ah
+ 165   var f-offset/ecx: (offset global) <- compute-offset global-data, f-index
+ 166   var f-value/ecx: (addr global) <- index global-data, f-offset
+ 167   var f-name-ah/ecx: (addr handle array byte) <- get f-value, name
+ 168   var f-name/eax: (addr array byte) <- lookup *f-name-ah
+ 169   {
+ 170     var add?/eax: boolean <- string-equal? f-name, "+"
+ 171     compare add?, 0/false
+ 172     break-if-=
+ 173     apply-add args-ah, out, trace
+ 174     return
+ 175   }
+ 176   {
+ 177     var subtract?/eax: boolean <- string-equal? f-name, "-"
+ 178     compare subtract?, 0/false
+ 179     break-if-=
+ 180     apply-subtract args-ah, out, trace
+ 181     return
+ 182   }
+ 183   {
+ 184     var multiply?/eax: boolean <- string-equal? f-name, "*"
+ 185     compare multiply?, 0/false
+ 186     break-if-=
+ 187     apply-multiply args-ah, out, trace
+ 188     return
+ 189   }
+ 190   {
+ 191     var divide?/eax: boolean <- string-equal? f-name, "/"
+ 192     compare divide?, 0/false
+ 193     break-if-=
+ 194     apply-divide args-ah, out, trace
+ 195     return
+ 196   }
+ 197   # '%' is the remainder operator, because modulo isn't really meaningful for
+ 198   # non-integers
+ 199   #
+ 200   # I considered calling this operator 'rem', but I want to follow Arc in
+ 201   # using 'rem' for filtering out elements from lists.
+ 202   #   https://arclanguage.github.io/ref/list.html#rem
  203   {
- 204     var abs?/eax: boolean <- string-equal? f-name, "abs"
- 205     compare abs?, 0/false
+ 204     var remainder?/eax: boolean <- string-equal? f-name, "%"
+ 205     compare remainder?, 0/false
  206     break-if-=
- 207     apply-abs args-ah, out, trace
+ 207     apply-remainder args-ah, out, trace
  208     return
  209   }
  210   {
- 211     var sgn?/eax: boolean <- string-equal? f-name, "sgn"
- 212     compare sgn?, 0/false
+ 211     var square-root?/eax: boolean <- string-equal? f-name, "sqrt"
+ 212     compare square-root?, 0/false
  213     break-if-=
- 214     apply-sgn args-ah, out, trace
+ 214     apply-square-root args-ah, out, trace
  215     return
  216   }
  217   {
- 218     var car?/eax: boolean <- string-equal? f-name, "car"
- 219     compare car?, 0/false
+ 218     var abs?/eax: boolean <- string-equal? f-name, "abs"
+ 219     compare abs?, 0/false
  220     break-if-=
- 221     apply-car args-ah, out, trace
+ 221     apply-abs args-ah, out, trace
  222     return
  223   }
  224   {
- 225     var cdr?/eax: boolean <- string-equal? f-name, "cdr"
- 226     compare cdr?, 0/false
+ 225     var sgn?/eax: boolean <- string-equal? f-name, "sgn"
+ 226     compare sgn?, 0/false
  227     break-if-=
- 228     apply-cdr args-ah, out, trace
+ 228     apply-sgn args-ah, out, trace
  229     return
  230   }
  231   {
- 232     var cons?/eax: boolean <- string-equal? f-name, "cons"
- 233     compare cons?, 0/false
+ 232     var car?/eax: boolean <- string-equal? f-name, "car"
+ 233     compare car?, 0/false
  234     break-if-=
- 235     apply-cons args-ah, out, trace
+ 235     apply-car args-ah, out, trace
  236     return
  237   }
  238   {
- 239     var structurally-equal?/eax: boolean <- string-equal? f-name, "="
- 240     compare structurally-equal?, 0/false
+ 239     var cdr?/eax: boolean <- string-equal? f-name, "cdr"
+ 240     compare cdr?, 0/false
  241     break-if-=
- 242     apply-structurally-equal args-ah, out, trace
+ 242     apply-cdr args-ah, out, trace
  243     return
  244   }
  245   {
- 246     var not?/eax: boolean <- string-equal? f-name, "no"
- 247     compare not?, 0/false
+ 246     var cons?/eax: boolean <- string-equal? f-name, "cons"
+ 247     compare cons?, 0/false
  248     break-if-=
- 249     apply-not args-ah, out, trace
+ 249     apply-cons args-ah, out, trace
  250     return
  251   }
  252   {
- 253     var not?/eax: boolean <- string-equal? f-name, "not"
- 254     compare not?, 0/false
+ 253     var structurally-equal?/eax: boolean <- string-equal? f-name, "="
+ 254     compare structurally-equal?, 0/false
  255     break-if-=
- 256     apply-not args-ah, out, trace
+ 256     apply-structurally-equal args-ah, out, trace
  257     return
  258   }
  259   {
- 260     var debug?/eax: boolean <- string-equal? f-name, "dbg"
- 261     compare debug?, 0/false
+ 260     var not?/eax: boolean <- string-equal? f-name, "no"
+ 261     compare not?, 0/false
  262     break-if-=
- 263     apply-debug args-ah, out, trace
+ 263     apply-not args-ah, out, trace
  264     return
  265   }
  266   {
- 267     var lesser?/eax: boolean <- string-equal? f-name, "<"
- 268     compare lesser?, 0/false
+ 267     var not?/eax: boolean <- string-equal? f-name, "not"
+ 268     compare not?, 0/false
  269     break-if-=
- 270     apply-< args-ah, out, trace
+ 270     apply-not args-ah, out, trace
  271     return
  272   }
  273   {
- 274     var greater?/eax: boolean <- string-equal? f-name, ">"
- 275     compare greater?, 0/false
+ 274     var debug?/eax: boolean <- string-equal? f-name, "dbg"
+ 275     compare debug?, 0/false
  276     break-if-=
- 277     apply-> args-ah, out, trace
+ 277     apply-debug args-ah, out, trace
  278     return
  279   }
  280   {
- 281     var lesser-or-equal?/eax: boolean <- string-equal? f-name, "<="
- 282     compare lesser-or-equal?, 0/false
+ 281     var lesser?/eax: boolean <- string-equal? f-name, "<"
+ 282     compare lesser?, 0/false
  283     break-if-=
- 284     apply-<= args-ah, out, trace
+ 284     apply-< args-ah, out, trace
  285     return
  286   }
  287   {
- 288     var greater-or-equal?/eax: boolean <- string-equal? f-name, ">="
- 289     compare greater-or-equal?, 0/false
+ 288     var greater?/eax: boolean <- string-equal? f-name, ">"
+ 289     compare greater?, 0/false
  290     break-if-=
- 291     apply->= args-ah, out, trace
+ 291     apply-> args-ah, out, trace
  292     return
  293   }
  294   {
- 295     var print?/eax: boolean <- string-equal? f-name, "print"
- 296     compare print?, 0/false
+ 295     var lesser-or-equal?/eax: boolean <- string-equal? f-name, "<="
+ 296     compare lesser-or-equal?, 0/false
  297     break-if-=
- 298     apply-print args-ah, out, trace
+ 298     apply-<= args-ah, out, trace
  299     return
  300   }
  301   {
- 302     var clear?/eax: boolean <- string-equal? f-name, "clear"
- 303     compare clear?, 0/false
+ 302     var greater-or-equal?/eax: boolean <- string-equal? f-name, ">="
+ 303     compare greater-or-equal?, 0/false
  304     break-if-=
- 305     apply-clear args-ah, out, trace
+ 305     apply->= args-ah, out, trace
  306     return
  307   }
  308   {
- 309     var lines?/eax: boolean <- string-equal? f-name, "lines"
- 310     compare lines?, 0/false
+ 309     var print?/eax: boolean <- string-equal? f-name, "print"
+ 310     compare print?, 0/false
  311     break-if-=
- 312     apply-lines args-ah, out, trace
+ 312     apply-print args-ah, out, trace
  313     return
  314   }
  315   {
- 316     var columns?/eax: boolean <- string-equal? f-name, "columns"
- 317     compare columns?, 0/false
+ 316     var clear?/eax: boolean <- string-equal? f-name, "clear"
+ 317     compare clear?, 0/false
  318     break-if-=
- 319     apply-columns args-ah, out, trace
+ 319     apply-clear args-ah, out, trace
  320     return
  321   }
  322   {
- 323     var up?/eax: boolean <- string-equal? f-name, "up"
- 324     compare up?, 0/false
+ 323     var lines?/eax: boolean <- string-equal? f-name, "lines"
+ 324     compare lines?, 0/false
  325     break-if-=
- 326     apply-up args-ah, out, trace
+ 326     apply-lines args-ah, out, trace
  327     return
  328   }
  329   {
- 330     var down?/eax: boolean <- string-equal? f-name, "down"
- 331     compare down?, 0/false
+ 330     var columns?/eax: boolean <- string-equal? f-name, "columns"
+ 331     compare columns?, 0/false
  332     break-if-=
- 333     apply-down args-ah, out, trace
+ 333     apply-columns args-ah, out, trace
  334     return
  335   }
  336   {
- 337     var left?/eax: boolean <- string-equal? f-name, "left"
- 338     compare left?, 0/false
+ 337     var up?/eax: boolean <- string-equal? f-name, "up"
+ 338     compare up?, 0/false
  339     break-if-=
- 340     apply-left args-ah, out, trace
+ 340     apply-up args-ah, out, trace
  341     return
  342   }
  343   {
- 344     var right?/eax: boolean <- string-equal? f-name, "right"
- 345     compare right?, 0/false
+ 344     var down?/eax: boolean <- string-equal? f-name, "down"
+ 345     compare down?, 0/false
  346     break-if-=
- 347     apply-right args-ah, out, trace
+ 347     apply-down args-ah, out, trace
  348     return
  349   }
  350   {
- 351     var cr?/eax: boolean <- string-equal? f-name, "cr"
- 352     compare cr?, 0/false
+ 351     var left?/eax: boolean <- string-equal? f-name, "left"
+ 352     compare left?, 0/false
  353     break-if-=
- 354     apply-cr args-ah, out, trace
+ 354     apply-left args-ah, out, trace
  355     return
  356   }
  357   {
- 358     var pixel?/eax: boolean <- string-equal? f-name, "pixel"
- 359     compare pixel?, 0/false
+ 358     var right?/eax: boolean <- string-equal? f-name, "right"
+ 359     compare right?, 0/false
  360     break-if-=
- 361     apply-pixel args-ah, out, trace
+ 361     apply-right args-ah, out, trace
  362     return
  363   }
  364   {
- 365     var width?/eax: boolean <- string-equal? f-name, "width"
- 366     compare width?, 0/false
+ 365     var cr?/eax: boolean <- string-equal? f-name, "cr"
+ 366     compare cr?, 0/false
  367     break-if-=
- 368     apply-width args-ah, out, trace
+ 368     apply-cr args-ah, out, trace
  369     return
  370   }
  371   {
- 372     var height?/eax: boolean <- string-equal? f-name, "height"
- 373     compare height?, 0/false
+ 372     var pixel?/eax: boolean <- string-equal? f-name, "pixel"
+ 373     compare pixel?, 0/false
  374     break-if-=
- 375     apply-height args-ah, out, trace
+ 375     apply-pixel args-ah, out, trace
  376     return
  377   }
  378   {
- 379     var wait-for-key?/eax: boolean <- string-equal? f-name, "key"
- 380     compare wait-for-key?, 0/false
+ 379     var width?/eax: boolean <- string-equal? f-name, "width"
+ 380     compare width?, 0/false
  381     break-if-=
- 382     apply-wait-for-key args-ah, out, trace
+ 382     apply-width args-ah, out, trace
  383     return
  384   }
  385   {
- 386     var stream?/eax: boolean <- string-equal? f-name, "stream"
- 387     compare stream?, 0/false
+ 386     var height?/eax: boolean <- string-equal? f-name, "height"
+ 387     compare height?, 0/false
  388     break-if-=
- 389     apply-stream args-ah, out, trace
+ 389     apply-height args-ah, out, trace
  390     return
  391   }
  392   {
- 393     var write?/eax: boolean <- string-equal? f-name, "write"
- 394     compare write?, 0/false
+ 393     var wait-for-key?/eax: boolean <- string-equal? f-name, "key"
+ 394     compare wait-for-key?, 0/false
  395     break-if-=
- 396     apply-write args-ah, out, trace
+ 396     apply-wait-for-key args-ah, out, trace
  397     return
  398   }
  399   {
- 400     var abort?/eax: boolean <- string-equal? f-name, "abort"
- 401     compare abort?, 0/false
+ 400     var stream?/eax: boolean <- string-equal? f-name, "stream"
+ 401     compare stream?, 0/false
  402     break-if-=
- 403     apply-abort args-ah, out, trace
+ 403     apply-stream args-ah, out, trace
  404     return
  405   }
- 406   abort "unknown primitive function"
- 407 }
- 408 
- 409 fn apply-add _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 410   trace-text trace, "eval", "apply +"
- 411   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 412   var _args/eax: (addr cell) <- lookup *args-ah
- 413   var args/esi: (addr cell) <- copy _args
- 414   # TODO: check that args is a pair
- 415   var empty-args?/eax: boolean <- nil? args
- 416   compare empty-args?, 0/false
- 417   {
- 418     break-if-=
- 419     error trace, "+ needs 2 args but got 0"
- 420     return
- 421   }
- 422   # args->left->value
- 423   var first-ah/eax: (addr handle cell) <- get args, left
- 424   var first/eax: (addr cell) <- lookup *first-ah
- 425   var first-type/ecx: (addr int) <- get first, type
- 426   compare *first-type, 1/number
- 427   {
- 428     break-if-=
- 429     error trace, "first arg for + is not a number"
- 430     return
- 431   }
- 432   var first-value/ecx: (addr float) <- get first, number-data
- 433   # args->right->left->value
- 434   var right-ah/eax: (addr handle cell) <- get args, right
- 435 #?   dump-cell right-ah
- 436 #?   abort "aaa"
- 437   var right/eax: (addr cell) <- lookup *right-ah
- 438   # TODO: check that right is a pair
- 439   var second-ah/eax: (addr handle cell) <- get right, left
- 440   var second/eax: (addr cell) <- lookup *second-ah
- 441   var second-type/edx: (addr int) <- get second, type
- 442   compare *second-type, 1/number
- 443   {
- 444     break-if-=
- 445     error trace, "second arg for + is not a number"
- 446     return
- 447   }
- 448   var second-value/edx: (addr float) <- get second, number-data
- 449   # add
- 450   var result/xmm0: float <- copy *first-value
- 451   result <- add *second-value
- 452   new-float out, result
- 453 }
- 454 
- 455 fn apply-subtract _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 456   trace-text trace, "eval", "apply -"
- 457   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 458   var _args/eax: (addr cell) <- lookup *args-ah
- 459   var args/esi: (addr cell) <- copy _args
- 460   # TODO: check that args is a pair
- 461   var empty-args?/eax: boolean <- nil? args
- 462   compare empty-args?, 0/false
+ 406   {
+ 407     var write?/eax: boolean <- string-equal? f-name, "write"
+ 408     compare write?, 0/false
+ 409     break-if-=
+ 410     apply-write args-ah, out, trace
+ 411     return
+ 412   }
+ 413   {
+ 414     var abort?/eax: boolean <- string-equal? f-name, "abort"
+ 415     compare abort?, 0/false
+ 416     break-if-=
+ 417     apply-abort args-ah, out, trace
+ 418     return
+ 419   }
+ 420   abort "unknown primitive function"
+ 421 }
+ 422 
+ 423 fn apply-add _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 424   trace-text trace, "eval", "apply +"
+ 425   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 426   var _args/eax: (addr cell) <- lookup *args-ah
+ 427   var args/esi: (addr cell) <- copy _args
+ 428   {
+ 429     var args-type/ecx: (addr int) <- get args, type
+ 430     compare *args-type, 0/pair
+ 431     break-if-=
+ 432     error trace, "args to + are not a list"
+ 433     return
+ 434   }
+ 435   var empty-args?/eax: boolean <- nil? args
+ 436   compare empty-args?, 0/false
+ 437   {
+ 438     break-if-=
+ 439     error trace, "+ needs 2 args but got 0"
+ 440     return
+ 441   }
+ 442   # args->left->value
+ 443   var first-ah/eax: (addr handle cell) <- get args, left
+ 444   var first/eax: (addr cell) <- lookup *first-ah
+ 445   var first-type/ecx: (addr int) <- get first, type
+ 446   compare *first-type, 1/number
+ 447   {
+ 448     break-if-=
+ 449     error trace, "first arg for + is not a number"
+ 450     return
+ 451   }
+ 452   var first-value/ecx: (addr float) <- get first, number-data
+ 453   # args->right->left->value
+ 454   var right-ah/eax: (addr handle cell) <- get args, right
+ 455   var right/eax: (addr cell) <- lookup *right-ah
+ 456   {
+ 457     var right-type/ecx: (addr int) <- get right, type
+ 458     compare *right-type, 0/pair
+ 459     break-if-=
+ 460     error trace, "+ encountered non-pair"
+ 461     return
+ 462   }
  463   {
- 464     break-if-=
- 465     error trace, "- needs 2 args but got 0"
- 466     return
- 467   }
- 468   # args->left->value
- 469   var first-ah/eax: (addr handle cell) <- get args, left
- 470   var first/eax: (addr cell) <- lookup *first-ah
- 471   var first-type/ecx: (addr int) <- get first, type
- 472   compare *first-type, 1/number
- 473   {
- 474     break-if-=
- 475     error trace, "first arg for - is not a number"
- 476     return
- 477   }
- 478   var first-value/ecx: (addr float) <- get first, number-data
- 479   # args->right->left->value
- 480   var right-ah/eax: (addr handle cell) <- get args, right
- 481   var right/eax: (addr cell) <- lookup *right-ah
- 482   # TODO: check that right is a pair
- 483   var second-ah/eax: (addr handle cell) <- get right, left
- 484   var second/eax: (addr cell) <- lookup *second-ah
- 485   var second-type/edx: (addr int) <- get second, type
- 486   compare *second-type, 1/number
- 487   {
- 488     break-if-=
- 489     error trace, "second arg for - is not a number"
- 490     return
- 491   }
- 492   var second-value/edx: (addr float) <- get second, number-data
- 493   # subtract
- 494   var result/xmm0: float <- copy *first-value
- 495   result <- subtract *second-value
- 496   new-float out, result
- 497 }
- 498 
- 499 fn apply-multiply _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 500   trace-text trace, "eval", "apply *"
- 501   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 502   var _args/eax: (addr cell) <- lookup *args-ah
- 503   var args/esi: (addr cell) <- copy _args
- 504   # TODO: check that args is a pair
- 505   var empty-args?/eax: boolean <- nil? args
- 506   compare empty-args?, 0/false
- 507   {
- 508     break-if-=
- 509     error trace, "* needs 2 args but got 0"
- 510     return
- 511   }
- 512   # args->left->value
- 513   var first-ah/eax: (addr handle cell) <- get args, left
- 514   var first/eax: (addr cell) <- lookup *first-ah
- 515   var first-type/ecx: (addr int) <- get first, type
- 516   compare *first-type, 1/number
- 517   {
- 518     break-if-=
- 519     error trace, "first arg for * is not a number"
- 520     return
- 521   }
- 522   var first-value/ecx: (addr float) <- get first, number-data
- 523   # args->right->left->value
- 524   var right-ah/eax: (addr handle cell) <- get args, right
- 525   var right/eax: (addr cell) <- lookup *right-ah
- 526   # TODO: check that right is a pair
- 527   var second-ah/eax: (addr handle cell) <- get right, left
- 528   var second/eax: (addr cell) <- lookup *second-ah
- 529   var second-type/edx: (addr int) <- get second, type
- 530   compare *second-type, 1/number
- 531   {
- 532     break-if-=
- 533     error trace, "second arg for * is not a number"
- 534     return
- 535   }
- 536   var second-value/edx: (addr float) <- get second, number-data
- 537   # multiply
- 538   var result/xmm0: float <- copy *first-value
- 539   result <- multiply *second-value
- 540   new-float out, result
- 541 }
- 542 
- 543 fn apply-divide _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 544   trace-text trace, "eval", "apply /"
- 545   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 546   var _args/eax: (addr cell) <- lookup *args-ah
- 547   var args/esi: (addr cell) <- copy _args
- 548   # TODO: check that args is a pair
- 549   var empty-args?/eax: boolean <- nil? args
- 550   compare empty-args?, 0/false
- 551   {
- 552     break-if-=
- 553     error trace, "/ needs 2 args but got 0"
- 554     return
- 555   }
- 556   # args->left->value
- 557   var first-ah/eax: (addr handle cell) <- get args, left
- 558   var first/eax: (addr cell) <- lookup *first-ah
- 559   var first-type/ecx: (addr int) <- get first, type
- 560   compare *first-type, 1/number
- 561   {
- 562     break-if-=
- 563     error trace, "first arg for / is not a number"
- 564     return
- 565   }
- 566   var first-value/ecx: (addr float) <- get first, number-data
- 567   # args->right->left->value
- 568   var right-ah/eax: (addr handle cell) <- get args, right
- 569   var right/eax: (addr cell) <- lookup *right-ah
- 570   # TODO: check that right is a pair
- 571   var second-ah/eax: (addr handle cell) <- get right, left
- 572   var second/eax: (addr cell) <- lookup *second-ah
- 573   var second-type/edx: (addr int) <- get second, type
- 574   compare *second-type, 1/number
- 575   {
- 576     break-if-=
- 577     error trace, "second arg for / is not a number"
- 578     return
- 579   }
- 580   var second-value/edx: (addr float) <- get second, number-data
- 581   # divide
- 582   var result/xmm0: float <- copy *first-value
- 583   result <- divide *second-value
- 584   new-float out, result
- 585 }
- 586 
- 587 fn apply-square-root _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 588   trace-text trace, "eval", "apply sqrt"
- 589   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 590   var _args/eax: (addr cell) <- lookup *args-ah
- 591   var args/esi: (addr cell) <- copy _args
- 592   # TODO: check that args is a pair
- 593   var empty-args?/eax: boolean <- nil? args
- 594   compare empty-args?, 0/false
- 595   {
- 596     break-if-=
- 597     error trace, "sqrt needs 1 arg but got 0"
- 598     return
- 599   }
- 600   # args->left->value
- 601   var first-ah/eax: (addr handle cell) <- get args, left
- 602   var first/eax: (addr cell) <- lookup *first-ah
- 603   var first-type/ecx: (addr int) <- get first, type
- 604   compare *first-type, 1/number
- 605   {
- 606     break-if-=
- 607     error trace, "arg for sqrt is not a number"
- 608     return
- 609   }
- 610   var first-value/ecx: (addr float) <- get first, number-data
- 611   # square-root
- 612   var result/xmm0: float <- square-root *first-value
- 613   new-float out, result
- 614 }
- 615 
- 616 fn apply-abs _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 617   trace-text trace, "eval", "apply abs"
- 618   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 619   var _args/eax: (addr cell) <- lookup *args-ah
- 620   var args/esi: (addr cell) <- copy _args
- 621   # TODO: check that args is a pair
- 622   var empty-args?/eax: boolean <- nil? args
- 623   compare empty-args?, 0/false
- 624   {
- 625     break-if-=
- 626     error trace, "abs needs 1 arg but got 0"
- 627     return
- 628   }
- 629   # args->left->value
- 630   var first-ah/eax: (addr handle cell) <- get args, left
- 631   var first/eax: (addr cell) <- lookup *first-ah
- 632   var first-type/ecx: (addr int) <- get first, type
- 633   compare *first-type, 1/number
- 634   {
- 635     break-if-=
- 636     error trace, "arg for abs is not a number"
- 637     return
- 638   }
- 639   var first-value/ecx: (addr float) <- get first, number-data
- 640   #
- 641   var result/xmm0: float <- copy *first-value
- 642   var zero: float
- 643   compare result, zero
- 644   {
- 645     break-if-float>=
- 646     var neg1/eax: int <- copy -1
- 647     var neg1-f/xmm1: float <- convert neg1
- 648     result <- multiply neg1-f
- 649   }
- 650   new-float out, result
- 651 }
- 652 
- 653 fn apply-sgn _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 654   trace-text trace, "eval", "apply sgn"
- 655   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 656   var _args/eax: (addr cell) <- lookup *args-ah
- 657   var args/esi: (addr cell) <- copy _args
- 658   # TODO: check that args is a pair
- 659   var empty-args?/eax: boolean <- nil? args
- 660   compare empty-args?, 0/false
- 661   {
- 662     break-if-=
- 663     error trace, "sgn needs 1 arg but got 0"
- 664     return
- 665   }
- 666   # args->left->value
- 667   var first-ah/eax: (addr handle cell) <- get args, left
- 668   var first/eax: (addr cell) <- lookup *first-ah
- 669   var first-type/ecx: (addr int) <- get first, type
- 670   compare *first-type, 1/number
- 671   {
- 672     break-if-=
- 673     error trace, "arg for sgn is not a number"
- 674     return
- 675   }
- 676   var first-value/ecx: (addr float) <- get first, number-data
- 677   #
- 678   var result/xmm0: float <- copy *first-value
- 679   var zero: float
- 680   $apply-sgn:core: {
- 681     compare result, zero
- 682     break-if-=
- 683     {
- 684       break-if-float>
- 685       var neg1/eax: int <- copy -1
- 686       result <- convert neg1
- 687       break $apply-sgn:core
- 688     }
- 689     {
- 690       break-if-float<
- 691       var one/eax: int <- copy 1
- 692       result <- convert one
- 693       break $apply-sgn:core
- 694     }
- 695   }
- 696   new-float out, result
- 697 }
- 698 
- 699 fn apply-car _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 700   trace-text trace, "eval", "apply car"
- 701   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 702   var _args/eax: (addr cell) <- lookup *args-ah
- 703   var args/esi: (addr cell) <- copy _args
- 704   # TODO: check that args is a pair
- 705   var empty-args?/eax: boolean <- nil? args
- 706   compare empty-args?, 0/false
- 707   {
- 708     break-if-=
- 709     error trace, "car needs 1 arg but got 0"
- 710     return
- 711   }
- 712   # args->left
- 713   var first-ah/eax: (addr handle cell) <- get args, left
- 714   var first/eax: (addr cell) <- lookup *first-ah
- 715   var first-type/ecx: (addr int) <- get first, type
- 716   compare *first-type, 0/pair
- 717   {
- 718     break-if-=
- 719     error trace, "arg for car is not a pair"
- 720     return
- 721   }
- 722   # car
- 723   var result/eax: (addr handle cell) <- get first, left
- 724   copy-object result, out
- 725 }
- 726 
- 727 fn apply-cdr _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 728   trace-text trace, "eval", "apply cdr"
- 729   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 730   var _args/eax: (addr cell) <- lookup *args-ah
- 731   var args/esi: (addr cell) <- copy _args
- 732   # TODO: check that args is a pair
- 733   var empty-args?/eax: boolean <- nil? args
- 734   compare empty-args?, 0/false
- 735   {
- 736     break-if-=
- 737     error trace, "cdr needs 1 arg but got 0"
- 738     return
- 739   }
- 740   # args->left
- 741   var first-ah/eax: (addr handle cell) <- get args, left
- 742   var first/eax: (addr cell) <- lookup *first-ah
- 743   var first-type/ecx: (addr int) <- get first, type
- 744   compare *first-type, 0/pair
- 745   {
- 746     break-if-=
- 747     error trace, "arg for cdr is not a pair"
- 748     return
- 749   }
- 750   # cdr
- 751   var result/eax: (addr handle cell) <- get first, right
- 752   copy-object result, out
- 753 }
- 754 
- 755 fn apply-cons _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 756   trace-text trace, "eval", "apply cons"
- 757   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 758   var _args/eax: (addr cell) <- lookup *args-ah
- 759   var args/esi: (addr cell) <- copy _args
- 760   # TODO: check that args is a pair
- 761   var empty-args?/eax: boolean <- nil? args
- 762   compare empty-args?, 0/false
- 763   {
- 764     break-if-=
- 765     error trace, "cons needs 2 args but got 0"
- 766     return
- 767   }
- 768   # args->left
- 769   var first-ah/ecx: (addr handle cell) <- get args, left
- 770   # args->right->left
- 771   var right-ah/eax: (addr handle cell) <- get args, right
- 772   var right/eax: (addr cell) <- lookup *right-ah
- 773   # TODO: check that right is a pair
- 774   var second-ah/eax: (addr handle cell) <- get right, left
- 775   # cons
- 776   new-pair out, *first-ah, *second-ah
- 777 }
- 778 
- 779 fn apply-structurally-equal _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 780   trace-text trace, "eval", "apply '='"
- 781   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 782   var _args/eax: (addr cell) <- lookup *args-ah
- 783   var args/esi: (addr cell) <- copy _args
- 784   # TODO: check that args is a pair
+ 464     var nil?/eax: boolean <- nil? right
+ 465     compare nil?, 0/false
+ 466     break-if-=
+ 467     error trace, "+ needs 2 args but got 1"
+ 468     return
+ 469   }
+ 470   var second-ah/eax: (addr handle cell) <- get right, left
+ 471   var second/eax: (addr cell) <- lookup *second-ah
+ 472   var second-type/edx: (addr int) <- get second, type
+ 473   compare *second-type, 1/number
+ 474   {
+ 475     break-if-=
+ 476     error trace, "second arg for + is not a number"
+ 477     return
+ 478   }
+ 479   var second-value/edx: (addr float) <- get second, number-data
+ 480   # add
+ 481   var result/xmm0: float <- copy *first-value
+ 482   result <- add *second-value
+ 483   new-float out, result
+ 484 }
+ 485 
+ 486 fn test-evaluate-missing-arg-in-add {
+ 487   var t-storage: trace
+ 488   var t/edi: (addr trace) <- address t-storage
+ 489   initialize-trace t, 0x100/max-depth, 0x100/capacity, 0/visible  # we don't use trace UI
+ 490   #
+ 491   var nil-storage: (handle cell)
+ 492   var nil-ah/ecx: (addr handle cell) <- address nil-storage
+ 493   allocate-pair nil-ah
+ 494   var one-storage: (handle cell)
+ 495   var one-ah/edx: (addr handle cell) <- address one-storage
+ 496   new-integer one-ah, 1
+ 497   var add-storage: (handle cell)
+ 498   var add-ah/ebx: (addr handle cell) <- address add-storage
+ 499   new-symbol add-ah, "+"
+ 500   # input is (+ 1)
+ 501   var tmp-storage: (handle cell)
+ 502   var tmp-ah/esi: (addr handle cell) <- address tmp-storage
+ 503   new-pair tmp-ah, *one-ah, *nil-ah
+ 504   new-pair tmp-ah, *add-ah, *tmp-ah
+ 505 #?   dump-cell tmp-ah
+ 506   #
+ 507   var globals-storage: global-table
+ 508   var globals/edx: (addr global-table) <- address globals-storage
+ 509   initialize-globals globals
+ 510   #
+ 511   evaluate tmp-ah, tmp-ah, *nil-ah, globals, t, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number
+ 512   # no crash
+ 513 }
+ 514 
+ 515 fn apply-subtract _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 516   trace-text trace, "eval", "apply -"
+ 517   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 518   var _args/eax: (addr cell) <- lookup *args-ah
+ 519   var args/esi: (addr cell) <- copy _args
+ 520   {
+ 521     var args-type/ecx: (addr int) <- get args, type
+ 522     compare *args-type, 0/pair
+ 523     break-if-=
+ 524     error trace, "args to - are not a list"
+ 525     return
+ 526   }
+ 527   var empty-args?/eax: boolean <- nil? args
+ 528   compare empty-args?, 0/false
+ 529   {
+ 530     break-if-=
+ 531     error trace, "- needs 2 args but got 0"
+ 532     return
+ 533   }
+ 534   # args->left->value
+ 535   var first-ah/eax: (addr handle cell) <- get args, left
+ 536   var first/eax: (addr cell) <- lookup *first-ah
+ 537   var first-type/ecx: (addr int) <- get first, type
+ 538   compare *first-type, 1/number
+ 539   {
+ 540     break-if-=
+ 541     error trace, "first arg for - is not a number"
+ 542     return
+ 543   }
+ 544   var first-value/ecx: (addr float) <- get first, number-data
+ 545   # args->right->left->value
+ 546   var right-ah/eax: (addr handle cell) <- get args, right
+ 547   var right/eax: (addr cell) <- lookup *right-ah
+ 548   {
+ 549     var right-type/ecx: (addr int) <- get right, type
+ 550     compare *right-type, 0/pair
+ 551     break-if-=
+ 552     error trace, "- encountered non-pair"
+ 553     return
+ 554   }
+ 555   {
+ 556     var nil?/eax: boolean <- nil? right
+ 557     compare nil?, 0/false
+ 558     break-if-=
+ 559     error trace, "- needs 2 args but got 1"
+ 560     return
+ 561   }
+ 562   var second-ah/eax: (addr handle cell) <- get right, left
+ 563   var second/eax: (addr cell) <- lookup *second-ah
+ 564   var second-type/edx: (addr int) <- get second, type
+ 565   compare *second-type, 1/number
+ 566   {
+ 567     break-if-=
+ 568     error trace, "second arg for - is not a number"
+ 569     return
+ 570   }
+ 571   var second-value/edx: (addr float) <- get second, number-data
+ 572   # subtract
+ 573   var result/xmm0: float <- copy *first-value
+ 574   result <- subtract *second-value
+ 575   new-float out, result
+ 576 }
+ 577 
+ 578 fn apply-multiply _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 579   trace-text trace, "eval", "apply *"
+ 580   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 581   var _args/eax: (addr cell) <- lookup *args-ah
+ 582   var args/esi: (addr cell) <- copy _args
+ 583   {
+ 584     var args-type/ecx: (addr int) <- get args, type
+ 585     compare *args-type, 0/pair
+ 586     break-if-=
+ 587     error trace, "args to * are not a list"
+ 588     return
+ 589   }
+ 590   var empty-args?/eax: boolean <- nil? args
+ 591   compare empty-args?, 0/false
+ 592   {
+ 593     break-if-=
+ 594     error trace, "* needs 2 args but got 0"
+ 595     return
+ 596   }
+ 597   # args->left->value
+ 598   var first-ah/eax: (addr handle cell) <- get args, left
+ 599   var first/eax: (addr cell) <- lookup *first-ah
+ 600   var first-type/ecx: (addr int) <- get first, type
+ 601   compare *first-type, 1/number
+ 602   {
+ 603     break-if-=
+ 604     error trace, "first arg for * is not a number"
+ 605     return
+ 606   }
+ 607   var first-value/ecx: (addr float) <- get first, number-data
+ 608   # args->right->left->value
+ 609   var right-ah/eax: (addr handle cell) <- get args, right
+ 610   var right/eax: (addr cell) <- lookup *right-ah
+ 611   {
+ 612     var right-type/ecx: (addr int) <- get right, type
+ 613     compare *right-type, 0/pair
+ 614     break-if-=
+ 615     error trace, "* encountered non-pair"
+ 616     return
+ 617   }
+ 618   {
+ 619     var nil?/eax: boolean <- nil? right
+ 620     compare nil?, 0/false
+ 621     break-if-=
+ 622     error trace, "* needs 2 args but got 1"
+ 623     return
+ 624   }
+ 625   var second-ah/eax: (addr handle cell) <- get right, left
+ 626   var second/eax: (addr cell) <- lookup *second-ah
+ 627   var second-type/edx: (addr int) <- get second, type
+ 628   compare *second-type, 1/number
+ 629   {
+ 630     break-if-=
+ 631     error trace, "second arg for * is not a number"
+ 632     return
+ 633   }
+ 634   var second-value/edx: (addr float) <- get second, number-data
+ 635   # multiply
+ 636   var result/xmm0: float <- copy *first-value
+ 637   result <- multiply *second-value
+ 638   new-float out, result
+ 639 }
+ 640 
+ 641 fn apply-divide _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 642   trace-text trace, "eval", "apply /"
+ 643   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 644   var _args/eax: (addr cell) <- lookup *args-ah
+ 645   var args/esi: (addr cell) <- copy _args
+ 646   {
+ 647     var args-type/ecx: (addr int) <- get args, type
+ 648     compare *args-type, 0/pair
+ 649     break-if-=
+ 650     error trace, "args to / are not a list"
+ 651     return
+ 652   }
+ 653   var empty-args?/eax: boolean <- nil? args
+ 654   compare empty-args?, 0/false
+ 655   {
+ 656     break-if-=
+ 657     error trace, "/ needs 2 args but got 0"
+ 658     return
+ 659   }
+ 660   # args->left->value
+ 661   var first-ah/eax: (addr handle cell) <- get args, left
+ 662   var first/eax: (addr cell) <- lookup *first-ah
+ 663   var first-type/ecx: (addr int) <- get first, type
+ 664   compare *first-type, 1/number
+ 665   {
+ 666     break-if-=
+ 667     error trace, "first arg for / is not a number"
+ 668     return
+ 669   }
+ 670   var first-value/ecx: (addr float) <- get first, number-data
+ 671   # args->right->left->value
+ 672   var right-ah/eax: (addr handle cell) <- get args, right
+ 673   var right/eax: (addr cell) <- lookup *right-ah
+ 674   {
+ 675     var right-type/ecx: (addr int) <- get right, type
+ 676     compare *right-type, 0/pair
+ 677     break-if-=
+ 678     error trace, "/ encountered non-pair"
+ 679     return
+ 680   }
+ 681   {
+ 682     var nil?/eax: boolean <- nil? right
+ 683     compare nil?, 0/false
+ 684     break-if-=
+ 685     error trace, "/ needs 2 args but got 1"
+ 686     return
+ 687   }
+ 688   var second-ah/eax: (addr handle cell) <- get right, left
+ 689   var second/eax: (addr cell) <- lookup *second-ah
+ 690   var second-type/edx: (addr int) <- get second, type
+ 691   compare *second-type, 1/number
+ 692   {
+ 693     break-if-=
+ 694     error trace, "second arg for / is not a number"
+ 695     return
+ 696   }
+ 697   var second-value/edx: (addr float) <- get second, number-data
+ 698   # divide
+ 699   var result/xmm0: float <- copy *first-value
+ 700   result <- divide *second-value
+ 701   new-float out, result
+ 702 }
+ 703 
+ 704 fn apply-remainder _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 705   trace-text trace, "eval", "apply %"
+ 706   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 707   var _args/eax: (addr cell) <- lookup *args-ah
+ 708   var args/esi: (addr cell) <- copy _args
+ 709   {
+ 710     var args-type/ecx: (addr int) <- get args, type
+ 711     compare *args-type, 0/pair
+ 712     break-if-=
+ 713     error trace, "args to % are not a list"
+ 714     return
+ 715   }
+ 716   var empty-args?/eax: boolean <- nil? args
+ 717   compare empty-args?, 0/false
+ 718   {
+ 719     break-if-=
+ 720     error trace, "% needs 2 args but got 0"
+ 721     return
+ 722   }
+ 723   # args->left->value
+ 724   var first-ah/eax: (addr handle cell) <- get args, left
+ 725   var first/eax: (addr cell) <- lookup *first-ah
+ 726   var first-type/ecx: (addr int) <- get first, type
+ 727   compare *first-type, 1/number
+ 728   {
+ 729     break-if-=
+ 730     error trace, "first arg for % is not a number"
+ 731     return
+ 732   }
+ 733   var first-value/ecx: (addr float) <- get first, number-data
+ 734   # args->right->left->value
+ 735   var right-ah/eax: (addr handle cell) <- get args, right
+ 736   var right/eax: (addr cell) <- lookup *right-ah
+ 737   {
+ 738     var right-type/ecx: (addr int) <- get right, type
+ 739     compare *right-type, 0/pair
+ 740     break-if-=
+ 741     error trace, "% encountered non-pair"
+ 742     return
+ 743   }
+ 744   {
+ 745     var nil?/eax: boolean <- nil? right
+ 746     compare nil?, 0/false
+ 747     break-if-=
+ 748     error trace, "% needs 2 args but got 1"
+ 749     return
+ 750   }
+ 751   var second-ah/eax: (addr handle cell) <- get right, left
+ 752   var second/eax: (addr cell) <- lookup *second-ah
+ 753   var second-type/edx: (addr int) <- get second, type
+ 754   compare *second-type, 1/number
+ 755   {
+ 756     break-if-=
+ 757     error trace, "second arg for % is not a number"
+ 758     return
+ 759   }
+ 760   var second-value/edx: (addr float) <- get second, number-data
+ 761   # divide
+ 762   var quotient/xmm0: float <- copy *first-value
+ 763   quotient <- divide *second-value
+ 764   var quotient-int/eax: int <- truncate quotient
+ 765   quotient <- convert quotient-int
+ 766   var sub-result/xmm1: float <- copy quotient
+ 767   sub-result <- multiply *second-value
+ 768   var result/xmm0: float <- copy *first-value
+ 769   result <- subtract sub-result
+ 770   new-float out, result
+ 771 }
+ 772 
+ 773 fn apply-square-root _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 774   trace-text trace, "eval", "apply sqrt"
+ 775   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 776   var _args/eax: (addr cell) <- lookup *args-ah
+ 777   var args/esi: (addr cell) <- copy _args
+ 778   {
+ 779     var args-type/ecx: (addr int) <- get args, type
+ 780     compare *args-type, 0/pair
+ 781     break-if-=
+ 782     error trace, "args to sqrt are not a list"
+ 783     return
+ 784   }
  785   var empty-args?/eax: boolean <- nil? args
  786   compare empty-args?, 0/false
  787   {
  788     break-if-=
- 789     error trace, "'=' needs 2 args but got 0"
+ 789     error trace, "sqrt needs 1 arg but got 0"
  790     return
  791   }
- 792   # args->left
- 793   var first-ah/ecx: (addr handle cell) <- get args, left
- 794   # args->right->left
- 795   var right-ah/eax: (addr handle cell) <- get args, right
- 796   var right/eax: (addr cell) <- lookup *right-ah
- 797   # TODO: check that right is a pair
- 798   var second-ah/edx: (addr handle cell) <- get right, left
- 799   # compare
- 800   var _first/eax: (addr cell) <- lookup *first-ah
- 801   var first/ecx: (addr cell) <- copy _first
- 802   var second/eax: (addr cell) <- lookup *second-ah
- 803   var match?/eax: boolean <- cell-isomorphic? first, second, trace
- 804   compare match?, 0/false
- 805   {
- 806     break-if-!=
- 807     nil out
- 808     return
- 809   }
- 810   new-integer out, 1/true
- 811 }
- 812 
- 813 fn apply-not _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 814   trace-text trace, "eval", "apply not"
- 815   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 816   var _args/eax: (addr cell) <- lookup *args-ah
- 817   var args/esi: (addr cell) <- copy _args
- 818   # TODO: check that args is a pair
- 819   var empty-args?/eax: boolean <- nil? args
- 820   compare empty-args?, 0/false
- 821   {
- 822     break-if-=
- 823     error trace, "not needs 1 arg but got 0"
- 824     return
- 825   }
- 826   # args->left
- 827   var first-ah/eax: (addr handle cell) <- get args, left
- 828   var first/eax: (addr cell) <- lookup *first-ah
- 829   # not
- 830   var nil?/eax: boolean <- nil? first
- 831   compare nil?, 0/false
+ 792   # args->left->value
+ 793   var first-ah/eax: (addr handle cell) <- get args, left
+ 794   var first/eax: (addr cell) <- lookup *first-ah
+ 795   var first-type/ecx: (addr int) <- get first, type
+ 796   compare *first-type, 1/number
+ 797   {
+ 798     break-if-=
+ 799     error trace, "arg for sqrt is not a number"
+ 800     return
+ 801   }
+ 802   var first-value/ecx: (addr float) <- get first, number-data
+ 803   # square-root
+ 804   var result/xmm0: float <- square-root *first-value
+ 805   new-float out, result
+ 806 }
+ 807 
+ 808 fn apply-abs _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 809   trace-text trace, "eval", "apply abs"
+ 810   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 811   var _args/eax: (addr cell) <- lookup *args-ah
+ 812   var args/esi: (addr cell) <- copy _args
+ 813   {
+ 814     var args-type/ecx: (addr int) <- get args, type
+ 815     compare *args-type, 0/pair
+ 816     break-if-=
+ 817     error trace, "args to abs are not a list"
+ 818     return
+ 819   }
+ 820   var empty-args?/eax: boolean <- nil? args
+ 821   compare empty-args?, 0/false
+ 822   {
+ 823     break-if-=
+ 824     error trace, "abs needs 1 arg but got 0"
+ 825     return
+ 826   }
+ 827   # args->left->value
+ 828   var first-ah/eax: (addr handle cell) <- get args, left
+ 829   var first/eax: (addr cell) <- lookup *first-ah
+ 830   var first-type/ecx: (addr int) <- get first, type
+ 831   compare *first-type, 1/number
  832   {
- 833     break-if-!=
- 834     nil out
+ 833     break-if-=
+ 834     error trace, "arg for abs is not a number"
  835     return
  836   }
- 837   new-integer out, 1
- 838 }
- 839 
- 840 fn apply-debug _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 841   trace-text trace, "eval", "apply debug"
- 842   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 843   var _args/eax: (addr cell) <- lookup *args-ah
- 844   var args/esi: (addr cell) <- copy _args
- 845   # TODO: check that args is a pair
- 846   var empty-args?/eax: boolean <- nil? args
- 847   compare empty-args?, 0/false
- 848   {
- 849     break-if-=
- 850     error trace, "not needs 1 arg but got 0"
- 851     return
- 852   }
- 853   # dump args->left uglily to screen and wait for a keypress
- 854   var first-ah/eax: (addr handle cell) <- get args, left
- 855   dump-cell-from-cursor-over-full-screen first-ah
+ 837   var first-value/ecx: (addr float) <- get first, number-data
+ 838   #
+ 839   var result/xmm0: float <- copy *first-value
+ 840   var zero: float
+ 841   compare result, zero
+ 842   {
+ 843     break-if-float>=
+ 844     var neg1/eax: int <- copy -1
+ 845     var neg1-f/xmm1: float <- convert neg1
+ 846     result <- multiply neg1-f
+ 847   }
+ 848   new-float out, result
+ 849 }
+ 850 
+ 851 fn apply-sgn _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 852   trace-text trace, "eval", "apply sgn"
+ 853   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 854   var _args/eax: (addr cell) <- lookup *args-ah
+ 855   var args/esi: (addr cell) <- copy _args
  856   {
- 857     var foo/eax: byte <- read-key 0/keyboard
- 858     compare foo, 0
- 859     loop-if-=
- 860   }
- 861   # return nothing
- 862 }
- 863 
- 864 fn apply-< _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 865   trace-text trace, "eval", "apply '<'"
- 866   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 867   var _args/eax: (addr cell) <- lookup *args-ah
- 868   var args/esi: (addr cell) <- copy _args
- 869   # TODO: check that args is a pair
- 870   var empty-args?/eax: boolean <- nil? args
- 871   compare empty-args?, 0/false
- 872   {
- 873     break-if-=
- 874     error trace, "'<' needs 2 args but got 0"
- 875     return
- 876   }
- 877   # args->left
- 878   var first-ah/ecx: (addr handle cell) <- get args, left
- 879   # args->right->left
- 880   var right-ah/eax: (addr handle cell) <- get args, right
- 881   var right/eax: (addr cell) <- lookup *right-ah
- 882   # TODO: check that right is a pair
- 883   var second-ah/edx: (addr handle cell) <- get right, left
- 884   # compare
- 885   var _first/eax: (addr cell) <- lookup *first-ah
- 886   var first/ecx: (addr cell) <- copy _first
- 887   var first-type/eax: (addr int) <- get first, type
- 888   compare *first-type, 1/number
- 889   {
- 890     break-if-=
- 891     error trace, "first arg for '<' is not a number"
- 892     return
- 893   }
- 894   var first-value/ecx: (addr float) <- get first, number-data
- 895   var first-float/xmm0: float <- copy *first-value
- 896   var second/eax: (addr cell) <- lookup *second-ah
- 897   var second-type/edx: (addr int) <- get second, type
- 898   compare *second-type, 1/number
- 899   {
- 900     break-if-=
- 901     error trace, "first arg for '<' is not a number"
- 902     return
- 903   }
- 904   var second-value/eax: (addr float) <- get second, number-data
- 905   compare first-float, *second-value
- 906   {
- 907     break-if-float<
- 908     nil out
- 909     return
- 910   }
- 911   new-integer out, 1/true
- 912 }
- 913 
- 914 fn apply-> _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 915   trace-text trace, "eval", "apply '>'"
- 916   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 917   var _args/eax: (addr cell) <- lookup *args-ah
- 918   var args/esi: (addr cell) <- copy _args
- 919   # TODO: check that args is a pair
- 920   var empty-args?/eax: boolean <- nil? args
- 921   compare empty-args?, 0/false
- 922   {
- 923     break-if-=
- 924     error trace, "'>' needs 2 args but got 0"
- 925     return
- 926   }
- 927   # args->left
- 928   var first-ah/ecx: (addr handle cell) <- get args, left
- 929   # args->right->left
- 930   var right-ah/eax: (addr handle cell) <- get args, right
- 931   var right/eax: (addr cell) <- lookup *right-ah
- 932   # TODO: check that right is a pair
- 933   var second-ah/edx: (addr handle cell) <- get right, left
- 934   # compare
- 935   var _first/eax: (addr cell) <- lookup *first-ah
- 936   var first/ecx: (addr cell) <- copy _first
- 937   var first-type/eax: (addr int) <- get first, type
- 938   compare *first-type, 1/number
- 939   {
- 940     break-if-=
- 941     error trace, "first arg for '>' is not a number"
- 942     return
- 943   }
- 944   var first-value/ecx: (addr float) <- get first, number-data
- 945   var first-float/xmm0: float <- copy *first-value
- 946   var second/eax: (addr cell) <- lookup *second-ah
- 947   var second-type/edx: (addr int) <- get second, type
- 948   compare *second-type, 1/number
- 949   {
- 950     break-if-=
- 951     error trace, "first arg for '>' is not a number"
- 952     return
- 953   }
- 954   var second-value/eax: (addr float) <- get second, number-data
- 955   compare first-float, *second-value
- 956   {
- 957     break-if-float>
- 958     nil out
- 959     return
- 960   }
- 961   new-integer out, 1/true
- 962 }
- 963 
- 964 fn apply-<= _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
- 965   trace-text trace, "eval", "apply '<='"
- 966   var args-ah/eax: (addr handle cell) <- copy _args-ah
- 967   var _args/eax: (addr cell) <- lookup *args-ah
- 968   var args/esi: (addr cell) <- copy _args
- 969   # TODO: check that args is a pair
- 970   var empty-args?/eax: boolean <- nil? args
- 971   compare empty-args?, 0/false
- 972   {
- 973     break-if-=
- 974     error trace, "'<=' needs 2 args but got 0"
- 975     return
- 976   }
- 977   # args->left
- 978   var first-ah/ecx: (addr handle cell) <- get args, left
- 979   # args->right->left
- 980   var right-ah/eax: (addr handle cell) <- get args, right
- 981   var right/eax: (addr cell) <- lookup *right-ah
- 982   # TODO: check that right is a pair
- 983   var second-ah/edx: (addr handle cell) <- get right, left
- 984   # compare
- 985   var _first/eax: (addr cell) <- lookup *first-ah
- 986   var first/ecx: (addr cell) <- copy _first
- 987   var first-type/eax: (addr int) <- get first, type
- 988   compare *first-type, 1/number
- 989   {
- 990     break-if-=
- 991     error trace, "first arg for '<=' is not a number"
- 992     return
- 993   }
- 994   var first-value/ecx: (addr float) <- get first, number-data
- 995   var first-float/xmm0: float <- copy *first-value
- 996   var second/eax: (addr cell) <- lookup *second-ah
- 997   var second-type/edx: (addr int) <- get second, type
- 998   compare *second-type, 1/number
- 999   {
-1000     break-if-=
-1001     error trace, "first arg for '<=' is not a number"
-1002     return
-1003   }
-1004   var second-value/eax: (addr float) <- get second, number-data
-1005   compare first-float, *second-value
-1006   {
-1007     break-if-float<=
-1008     nil out
-1009     return
-1010   }
-1011   new-integer out, 1/true
-1012 }
-1013 
-1014 fn apply->= _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1015   trace-text trace, "eval", "apply '>='"
-1016   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1017   var _args/eax: (addr cell) <- lookup *args-ah
-1018   var args/esi: (addr cell) <- copy _args
-1019   # TODO: check that args is a pair
-1020   var empty-args?/eax: boolean <- nil? args
-1021   compare empty-args?, 0/false
-1022   {
-1023     break-if-=
-1024     error trace, "'>=' needs 2 args but got 0"
-1025     return
-1026   }
-1027   # args->left
-1028   var first-ah/ecx: (addr handle cell) <- get args, left
-1029   # args->right->left
-1030   var right-ah/eax: (addr handle cell) <- get args, right
-1031   var right/eax: (addr cell) <- lookup *right-ah
-1032   # TODO: check that right is a pair
-1033   var second-ah/edx: (addr handle cell) <- get right, left
-1034   # compare
-1035   var _first/eax: (addr cell) <- lookup *first-ah
-1036   var first/ecx: (addr cell) <- copy _first
-1037   var first-type/eax: (addr int) <- get first, type
-1038   compare *first-type, 1/number
-1039   {
-1040     break-if-=
-1041     error trace, "first arg for '>=' is not a number"
-1042     return
-1043   }
-1044   var first-value/ecx: (addr float) <- get first, number-data
-1045   var first-float/xmm0: float <- copy *first-value
-1046   var second/eax: (addr cell) <- lookup *second-ah
-1047   var second-type/edx: (addr int) <- get second, type
-1048   compare *second-type, 1/number
-1049   {
-1050     break-if-=
-1051     error trace, "first arg for '>=' is not a number"
-1052     return
-1053   }
-1054   var second-value/eax: (addr float) <- get second, number-data
-1055   compare first-float, *second-value
-1056   {
-1057     break-if-float>=
-1058     nil out
+ 857     var args-type/ecx: (addr int) <- get args, type
+ 858     compare *args-type, 0/pair
+ 859     break-if-=
+ 860     error trace, "args to sgn are not a list"
+ 861     return
+ 862   }
+ 863   var empty-args?/eax: boolean <- nil? args
+ 864   compare empty-args?, 0/false
+ 865   {
+ 866     break-if-=
+ 867     error trace, "sgn needs 1 arg but got 0"
+ 868     return
+ 869   }
+ 870   # args->left->value
+ 871   var first-ah/eax: (addr handle cell) <- get args, left
+ 872   var first/eax: (addr cell) <- lookup *first-ah
+ 873   var first-type/ecx: (addr int) <- get first, type
+ 874   compare *first-type, 1/number
+ 875   {
+ 876     break-if-=
+ 877     error trace, "arg for sgn is not a number"
+ 878     return
+ 879   }
+ 880   var first-value/ecx: (addr float) <- get first, number-data
+ 881   #
+ 882   var result/xmm0: float <- copy *first-value
+ 883   var zero: float
+ 884   $apply-sgn:core: {
+ 885     compare result, zero
+ 886     break-if-=
+ 887     {
+ 888       break-if-float>
+ 889       var neg1/eax: int <- copy -1
+ 890       result <- convert neg1
+ 891       break $apply-sgn:core
+ 892     }
+ 893     {
+ 894       break-if-float<
+ 895       var one/eax: int <- copy 1
+ 896       result <- convert one
+ 897       break $apply-sgn:core
+ 898     }
+ 899   }
+ 900   new-float out, result
+ 901 }
+ 902 
+ 903 fn apply-car _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 904   trace-text trace, "eval", "apply car"
+ 905   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 906   var _args/eax: (addr cell) <- lookup *args-ah
+ 907   var args/esi: (addr cell) <- copy _args
+ 908   {
+ 909     var args-type/ecx: (addr int) <- get args, type
+ 910     compare *args-type, 0/pair
+ 911     break-if-=
+ 912     error trace, "args to car are not a list"
+ 913     return
+ 914   }
+ 915   var empty-args?/eax: boolean <- nil? args
+ 916   compare empty-args?, 0/false
+ 917   {
+ 918     break-if-=
+ 919     error trace, "car needs 1 arg but got 0"
+ 920     return
+ 921   }
+ 922   # args->left
+ 923   var first-ah/edx: (addr handle cell) <- get args, left
+ 924   var first/eax: (addr cell) <- lookup *first-ah
+ 925   var first-type/ecx: (addr int) <- get first, type
+ 926   compare *first-type, 0/pair
+ 927   {
+ 928     break-if-=
+ 929     error trace, "arg for car is not a pair"
+ 930     return
+ 931   }
+ 932   # nil? return nil
+ 933   {
+ 934     var nil?/eax: boolean <- nil? first
+ 935     compare nil?, 0/false
+ 936     break-if-=
+ 937     copy-object first-ah, out
+ 938     return
+ 939   }
+ 940   # car
+ 941   var result/eax: (addr handle cell) <- get first, left
+ 942   copy-object result, out
+ 943 }
+ 944 
+ 945 fn apply-cdr _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 946   trace-text trace, "eval", "apply cdr"
+ 947   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 948   var _args/eax: (addr cell) <- lookup *args-ah
+ 949   var args/esi: (addr cell) <- copy _args
+ 950   {
+ 951     var args-type/ecx: (addr int) <- get args, type
+ 952     compare *args-type, 0/pair
+ 953     break-if-=
+ 954     error trace, "args to cdr are not a list"
+ 955     return
+ 956   }
+ 957   var empty-args?/eax: boolean <- nil? args
+ 958   compare empty-args?, 0/false
+ 959   {
+ 960     break-if-=
+ 961     error trace, "cdr needs 1 arg but got 0"
+ 962     return
+ 963   }
+ 964   # args->left
+ 965   var first-ah/edx: (addr handle cell) <- get args, left
+ 966   var first/eax: (addr cell) <- lookup *first-ah
+ 967   var first-type/ecx: (addr int) <- get first, type
+ 968   compare *first-type, 0/pair
+ 969   {
+ 970     break-if-=
+ 971     error trace, "arg for cdr is not a pair"
+ 972     return
+ 973   }
+ 974   # nil? return nil
+ 975   {
+ 976     var nil?/eax: boolean <- nil? first
+ 977     compare nil?, 0/false
+ 978     break-if-=
+ 979     copy-object first-ah, out
+ 980     return
+ 981   }
+ 982   # cdr
+ 983   var result/eax: (addr handle cell) <- get first, right
+ 984   copy-object result, out
+ 985 }
+ 986 
+ 987 fn apply-cons _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+ 988   trace-text trace, "eval", "apply cons"
+ 989   var args-ah/eax: (addr handle cell) <- copy _args-ah
+ 990   var _args/eax: (addr cell) <- lookup *args-ah
+ 991   var args/esi: (addr cell) <- copy _args
+ 992   {
+ 993     var args-type/ecx: (addr int) <- get args, type
+ 994     compare *args-type, 0/pair
+ 995     break-if-=
+ 996     error trace, "args to 'cons' are not a list"
+ 997     return
+ 998   }
+ 999   var empty-args?/eax: boolean <- nil? args
+1000   compare empty-args?, 0/false
+1001   {
+1002     break-if-=
+1003     error trace, "cons needs 2 args but got 0"
+1004     return
+1005   }
+1006   # args->left
+1007   var first-ah/ecx: (addr handle cell) <- get args, left
+1008   # args->right->left
+1009   var right-ah/eax: (addr handle cell) <- get args, right
+1010   var right/eax: (addr cell) <- lookup *right-ah
+1011   {
+1012     var right-type/ecx: (addr int) <- get right, type
+1013     compare *right-type, 0/pair
+1014     break-if-=
+1015     error trace, "'cons' encountered non-pair"
+1016     return
+1017   }
+1018   {
+1019     var nil?/eax: boolean <- nil? right
+1020     compare nil?, 0/false
+1021     break-if-=
+1022     error trace, "'cons' needs 2 args but got 1"
+1023     return
+1024   }
+1025   var second-ah/eax: (addr handle cell) <- get right, left
+1026   # cons
+1027   new-pair out, *first-ah, *second-ah
+1028 }
+1029 
+1030 fn apply-structurally-equal _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1031   trace-text trace, "eval", "apply '='"
+1032   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1033   var _args/eax: (addr cell) <- lookup *args-ah
+1034   var args/esi: (addr cell) <- copy _args
+1035   {
+1036     var args-type/ecx: (addr int) <- get args, type
+1037     compare *args-type, 0/pair
+1038     break-if-=
+1039     error trace, "args to '=' are not a list"
+1040     return
+1041   }
+1042   var empty-args?/eax: boolean <- nil? args
+1043   compare empty-args?, 0/false
+1044   {
+1045     break-if-=
+1046     error trace, "'=' needs 2 args but got 0"
+1047     return
+1048   }
+1049   # args->left
+1050   var first-ah/ecx: (addr handle cell) <- get args, left
+1051   # args->right->left
+1052   var right-ah/eax: (addr handle cell) <- get args, right
+1053   var right/eax: (addr cell) <- lookup *right-ah
+1054   {
+1055     var right-type/ecx: (addr int) <- get right, type
+1056     compare *right-type, 0/pair
+1057     break-if-=
+1058     error trace, "'=' encountered non-pair"
 1059     return
 1060   }
-1061   new-integer out, 1/true
-1062 }
-1063 
-1064 fn apply-print _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1065   trace-text trace, "eval", "apply print"
-1066   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1067   var _args/eax: (addr cell) <- lookup *args-ah
-1068   var args/esi: (addr cell) <- copy _args
-1069   # TODO: check that args is a pair
-1070   var empty-args?/eax: boolean <- nil? args
-1071   compare empty-args?, 0/false
-1072   {
-1073     break-if-=
-1074     error trace, "print needs 2 args but got 0"
-1075     return
-1076   }
-1077   # screen = args->left
-1078   var first-ah/eax: (addr handle cell) <- get args, left
-1079   var first/eax: (addr cell) <- lookup *first-ah
-1080   var first-type/ecx: (addr int) <- get first, type
-1081   compare *first-type, 5/screen
-1082   {
-1083     break-if-=
-1084     error trace, "first arg for 'print' is not a screen"
-1085     return
-1086   }
-1087   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1088   var _screen/eax: (addr screen) <- lookup *screen-ah
-1089   var screen/ecx: (addr screen) <- copy _screen
-1090   # args->right->left
-1091   var right-ah/eax: (addr handle cell) <- get args, right
-1092   var right/eax: (addr cell) <- lookup *right-ah
-1093   # TODO: check that right is a pair
-1094   var second-ah/eax: (addr handle cell) <- get right, left
-1095   var stream-storage: (stream byte 0x100)
-1096   var stream/edi: (addr stream byte) <- address stream-storage
-1097   print-cell second-ah, stream, trace
-1098   draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen, stream, 7/fg, 0/bg
-1099   # return what was printed
-1100   copy-object second-ah, out
-1101 }
-1102 
-1103 fn apply-clear _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1104   trace-text trace, "eval", "apply clear"
-1105   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1106   var _args/eax: (addr cell) <- lookup *args-ah
-1107   var args/esi: (addr cell) <- copy _args
-1108   # TODO: check that args is a pair
-1109   var empty-args?/eax: boolean <- nil? args
-1110   compare empty-args?, 0/false
-1111   {
-1112     break-if-=
-1113     error trace, "'clear' needs 1 arg but got 0"
-1114     return
-1115   }
-1116   # screen = args->left
-1117   var first-ah/eax: (addr handle cell) <- get args, left
-1118   var first/eax: (addr cell) <- lookup *first-ah
-1119   var first-type/ecx: (addr int) <- get first, type
-1120   compare *first-type, 5/screen
+1061   {
+1062     var nil?/eax: boolean <- nil? right
+1063     compare nil?, 0/false
+1064     break-if-=
+1065     error trace, "'=' needs 2 args but got 1"
+1066     return
+1067   }
+1068   var second-ah/edx: (addr handle cell) <- get right, left
+1069   # compare
+1070   var _first/eax: (addr cell) <- lookup *first-ah
+1071   var first/ecx: (addr cell) <- copy _first
+1072   var second/eax: (addr cell) <- lookup *second-ah
+1073   var match?/eax: boolean <- cell-isomorphic? first, second, trace
+1074   compare match?, 0/false
+1075   {
+1076     break-if-!=
+1077     nil out
+1078     return
+1079   }
+1080   new-integer out, 1/true
+1081 }
+1082 
+1083 fn apply-not _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1084   trace-text trace, "eval", "apply 'not'"
+1085   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1086   var _args/eax: (addr cell) <- lookup *args-ah
+1087   var args/esi: (addr cell) <- copy _args
+1088   {
+1089     var args-type/ecx: (addr int) <- get args, type
+1090     compare *args-type, 0/pair
+1091     break-if-=
+1092     error trace, "args to 'not' are not a list"
+1093     return
+1094   }
+1095   var empty-args?/eax: boolean <- nil? args
+1096   compare empty-args?, 0/false
+1097   {
+1098     break-if-=
+1099     error trace, "'not' needs 1 arg but got 0"
+1100     return
+1101   }
+1102   # args->left
+1103   var first-ah/eax: (addr handle cell) <- get args, left
+1104   var first/eax: (addr cell) <- lookup *first-ah
+1105   # not
+1106   var nil?/eax: boolean <- nil? first
+1107   compare nil?, 0/false
+1108   {
+1109     break-if-!=
+1110     nil out
+1111     return
+1112   }
+1113   new-integer out, 1
+1114 }
+1115 
+1116 fn apply-debug _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1117   trace-text trace, "eval", "apply 'debug'"
+1118   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1119   var _args/eax: (addr cell) <- lookup *args-ah
+1120   var args/esi: (addr cell) <- copy _args
 1121   {
-1122     break-if-=
-1123     error trace, "first arg for 'clear' is not a screen"
-1124     return
-1125   }
-1126   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1127   var _screen/eax: (addr screen) <- lookup *screen-ah
-1128   var screen/ecx: (addr screen) <- copy _screen
-1129   #
-1130   clear-screen screen
-1131 }
-1132 
-1133 fn apply-up _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1134   trace-text trace, "eval", "apply up"
-1135   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1136   var _args/eax: (addr cell) <- lookup *args-ah
-1137   var args/esi: (addr cell) <- copy _args
-1138   # TODO: check that args is a pair
-1139   var empty-args?/eax: boolean <- nil? args
-1140   compare empty-args?, 0/false
-1141   {
-1142     break-if-=
-1143     error trace, "'up' needs 1 arg but got 0"
-1144     return
-1145   }
-1146   # screen = args->left
-1147   var first-ah/eax: (addr handle cell) <- get args, left
-1148   var first/eax: (addr cell) <- lookup *first-ah
-1149   var first-type/ecx: (addr int) <- get first, type
-1150   compare *first-type, 5/screen
+1122     var args-type/ecx: (addr int) <- get args, type
+1123     compare *args-type, 0/pair
+1124     break-if-=
+1125     error trace, "args to 'debug' are not a list"
+1126     return
+1127   }
+1128   var empty-args?/eax: boolean <- nil? args
+1129   compare empty-args?, 0/false
+1130   {
+1131     break-if-=
+1132     error trace, "'debug' needs 1 arg but got 0"
+1133     return
+1134   }
+1135   # dump args->left uglily to screen and wait for a keypress
+1136   var first-ah/eax: (addr handle cell) <- get args, left
+1137   dump-cell-from-cursor-over-full-screen first-ah
+1138   {
+1139     var foo/eax: byte <- read-key 0/keyboard
+1140     compare foo, 0
+1141     loop-if-=
+1142   }
+1143   # return nothing
+1144 }
+1145 
+1146 fn apply-< _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1147   trace-text trace, "eval", "apply '<'"
+1148   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1149   var _args/eax: (addr cell) <- lookup *args-ah
+1150   var args/esi: (addr cell) <- copy _args
 1151   {
-1152     break-if-=
-1153     error trace, "first arg for 'up' is not a screen"
-1154     return
-1155   }
-1156   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1157   var _screen/eax: (addr screen) <- lookup *screen-ah
-1158   var screen/ecx: (addr screen) <- copy _screen
-1159   #
-1160   move-cursor-up screen
-1161 }
-1162 
-1163 fn apply-down _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1164   trace-text trace, "eval", "apply 'down'"
-1165   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1166   var _args/eax: (addr cell) <- lookup *args-ah
-1167   var args/esi: (addr cell) <- copy _args
-1168   # TODO: check that args is a pair
-1169   var empty-args?/eax: boolean <- nil? args
-1170   compare empty-args?, 0/false
-1171   {
-1172     break-if-=
-1173     error trace, "'down' needs 1 arg but got 0"
-1174     return
-1175   }
-1176   # screen = args->left
-1177   var first-ah/eax: (addr handle cell) <- get args, left
-1178   var first/eax: (addr cell) <- lookup *first-ah
-1179   var first-type/ecx: (addr int) <- get first, type
-1180   compare *first-type, 5/screen
-1181   {
-1182     break-if-=
-1183     error trace, "first arg for 'down' is not a screen"
-1184     return
-1185   }
-1186   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1187   var _screen/eax: (addr screen) <- lookup *screen-ah
-1188   var screen/ecx: (addr screen) <- copy _screen
-1189   #
-1190   move-cursor-down screen
-1191 }
-1192 
-1193 fn apply-left _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1194   trace-text trace, "eval", "apply 'left'"
-1195   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1196   var _args/eax: (addr cell) <- lookup *args-ah
-1197   var args/esi: (addr cell) <- copy _args
-1198   # TODO: check that args is a pair
-1199   var empty-args?/eax: boolean <- nil? args
-1200   compare empty-args?, 0/false
-1201   {
-1202     break-if-=
-1203     error trace, "'left' needs 1 arg but got 0"
-1204     return
-1205   }
-1206   # screen = args->left
-1207   var first-ah/eax: (addr handle cell) <- get args, left
-1208   var first/eax: (addr cell) <- lookup *first-ah
-1209   var first-type/ecx: (addr int) <- get first, type
-1210   compare *first-type, 5/screen
-1211   {
-1212     break-if-=
-1213     error trace, "first arg for 'left' is not a screen"
-1214     return
-1215   }
-1216   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1217   var _screen/eax: (addr screen) <- lookup *screen-ah
-1218   var screen/ecx: (addr screen) <- copy _screen
-1219   #
-1220   move-cursor-left screen
-1221 }
-1222 
-1223 fn apply-right _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1224   trace-text trace, "eval", "apply 'right'"
-1225   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1226   var _args/eax: (addr cell) <- lookup *args-ah
-1227   var args/esi: (addr cell) <- copy _args
-1228   # TODO: check that args is a pair
-1229   var empty-args?/eax: boolean <- nil? args
-1230   compare empty-args?, 0/false
-1231   {
-1232     break-if-=
-1233     error trace, "'right' needs 1 arg but got 0"
-1234     return
-1235   }
-1236   # screen = args->left
-1237   var first-ah/eax: (addr handle cell) <- get args, left
-1238   var first/eax: (addr cell) <- lookup *first-ah
-1239   var first-type/ecx: (addr int) <- get first, type
-1240   compare *first-type, 5/screen
-1241   {
+1152     var args-type/ecx: (addr int) <- get args, type
+1153     compare *args-type, 0/pair
+1154     break-if-=
+1155     error trace, "args to '<' are not a list"
+1156     return
+1157   }
+1158   var empty-args?/eax: boolean <- nil? args
+1159   compare empty-args?, 0/false
+1160   {
+1161     break-if-=
+1162     error trace, "'<' needs 2 args but got 0"
+1163     return
+1164   }
+1165   # args->left
+1166   var first-ah/ecx: (addr handle cell) <- get args, left
+1167   # args->right->left
+1168   var right-ah/eax: (addr handle cell) <- get args, right
+1169   var right/eax: (addr cell) <- lookup *right-ah
+1170   {
+1171     var right-type/ecx: (addr int) <- get right, type
+1172     compare *right-type, 0/pair
+1173     break-if-=
+1174     error trace, "'<' encountered non-pair"
+1175     return
+1176   }
+1177   {
+1178     var nil?/eax: boolean <- nil? right
+1179     compare nil?, 0/false
+1180     break-if-=
+1181     error trace, "'<' needs 2 args but got 1"
+1182     return
+1183   }
+1184   var second-ah/edx: (addr handle cell) <- get right, left
+1185   # compare
+1186   var _first/eax: (addr cell) <- lookup *first-ah
+1187   var first/ecx: (addr cell) <- copy _first
+1188   var first-type/eax: (addr int) <- get first, type
+1189   compare *first-type, 1/number
+1190   {
+1191     break-if-=
+1192     error trace, "first arg for '<' is not a number"
+1193     return
+1194   }
+1195   var first-value/ecx: (addr float) <- get first, number-data
+1196   var first-float/xmm0: float <- copy *first-value
+1197   var second/eax: (addr cell) <- lookup *second-ah
+1198   var second-type/edx: (addr int) <- get second, type
+1199   compare *second-type, 1/number
+1200   {
+1201     break-if-=
+1202     error trace, "second arg for '<' is not a number"
+1203     return
+1204   }
+1205   var second-value/eax: (addr float) <- get second, number-data
+1206   compare first-float, *second-value
+1207   {
+1208     break-if-float<
+1209     nil out
+1210     return
+1211   }
+1212   new-integer out, 1/true
+1213 }
+1214 
+1215 fn apply-> _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1216   trace-text trace, "eval", "apply '>'"
+1217   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1218   var _args/eax: (addr cell) <- lookup *args-ah
+1219   var args/esi: (addr cell) <- copy _args
+1220   {
+1221     var args-type/ecx: (addr int) <- get args, type
+1222     compare *args-type, 0/pair
+1223     break-if-=
+1224     error trace, "args to '>' are not a list"
+1225     return
+1226   }
+1227   var empty-args?/eax: boolean <- nil? args
+1228   compare empty-args?, 0/false
+1229   {
+1230     break-if-=
+1231     error trace, "'>' needs 2 args but got 0"
+1232     return
+1233   }
+1234   # args->left
+1235   var first-ah/ecx: (addr handle cell) <- get args, left
+1236   # args->right->left
+1237   var right-ah/eax: (addr handle cell) <- get args, right
+1238   var right/eax: (addr cell) <- lookup *right-ah
+1239   {
+1240     var right-type/ecx: (addr int) <- get right, type
+1241     compare *right-type, 0/pair
 1242     break-if-=
-1243     error trace, "first arg for 'right' is not a screen"
+1243     error trace, "'>' encountered non-pair"
 1244     return
 1245   }
-1246   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1247   var _screen/eax: (addr screen) <- lookup *screen-ah
-1248   var screen/ecx: (addr screen) <- copy _screen
-1249   #
-1250   move-cursor-right screen
-1251 }
-1252 
-1253 fn apply-cr _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1254   trace-text trace, "eval", "apply 'cr'"
-1255   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1256   var _args/eax: (addr cell) <- lookup *args-ah
-1257   var args/esi: (addr cell) <- copy _args
-1258   # TODO: check that args is a pair
-1259   var empty-args?/eax: boolean <- nil? args
-1260   compare empty-args?, 0/false
-1261   {
-1262     break-if-=
-1263     error trace, "'cr' needs 1 arg but got 0"
-1264     return
-1265   }
-1266   # screen = args->left
-1267   var first-ah/eax: (addr handle cell) <- get args, left
-1268   var first/eax: (addr cell) <- lookup *first-ah
-1269   var first-type/ecx: (addr int) <- get first, type
-1270   compare *first-type, 5/screen
-1271   {
-1272     break-if-=
-1273     error trace, "first arg for 'cr' is not a screen"
-1274     return
-1275   }
-1276   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1277   var _screen/eax: (addr screen) <- lookup *screen-ah
-1278   var screen/ecx: (addr screen) <- copy _screen
-1279   #
-1280   move-cursor-to-left-margin-of-next-line screen
-1281 }
-1282 
-1283 fn apply-pixel _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1284   trace-text trace, "eval", "apply pixel"
-1285   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1286   var _args/eax: (addr cell) <- lookup *args-ah
-1287   var args/esi: (addr cell) <- copy _args
-1288   # TODO: check that args is a pair
-1289   var empty-args?/eax: boolean <- nil? args
-1290   compare empty-args?, 0/false
-1291   {
+1246   {
+1247     var nil?/eax: boolean <- nil? right
+1248     compare nil?, 0/false
+1249     break-if-=
+1250     error trace, "'>' needs 2 args but got 1"
+1251     return
+1252   }
+1253   var second-ah/edx: (addr handle cell) <- get right, left
+1254   # compare
+1255   var _first/eax: (addr cell) <- lookup *first-ah
+1256   var first/ecx: (addr cell) <- copy _first
+1257   var first-type/eax: (addr int) <- get first, type
+1258   compare *first-type, 1/number
+1259   {
+1260     break-if-=
+1261     error trace, "first arg for '>' is not a number"
+1262     return
+1263   }
+1264   var first-value/ecx: (addr float) <- get first, number-data
+1265   var first-float/xmm0: float <- copy *first-value
+1266   var second/eax: (addr cell) <- lookup *second-ah
+1267   var second-type/edx: (addr int) <- get second, type
+1268   compare *second-type, 1/number
+1269   {
+1270     break-if-=
+1271     error trace, "second arg for '>' is not a number"
+1272     return
+1273   }
+1274   var second-value/eax: (addr float) <- get second, number-data
+1275   compare first-float, *second-value
+1276   {
+1277     break-if-float>
+1278     nil out
+1279     return
+1280   }
+1281   new-integer out, 1/true
+1282 }
+1283 
+1284 fn apply-<= _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1285   trace-text trace, "eval", "apply '<='"
+1286   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1287   var _args/eax: (addr cell) <- lookup *args-ah
+1288   var args/esi: (addr cell) <- copy _args
+1289   {
+1290     var args-type/ecx: (addr int) <- get args, type
+1291     compare *args-type, 0/pair
 1292     break-if-=
-1293     error trace, "pixel needs 4 args but got 0"
+1293     error trace, "args to '<=' are not a list"
 1294     return
 1295   }
-1296   # screen = args->left
-1297   var first-ah/eax: (addr handle cell) <- get args, left
-1298   var first/eax: (addr cell) <- lookup *first-ah
-1299   var first-type/ecx: (addr int) <- get first, type
-1300   compare *first-type, 5/screen
-1301   {
-1302     break-if-=
-1303     error trace, "first arg for 'pixel' is not a screen"
-1304     return
-1305   }
-1306   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1307   var _screen/eax: (addr screen) <- lookup *screen-ah
-1308   var screen/edi: (addr screen) <- copy _screen
-1309   # x = args->right->left->value
-1310   var rest-ah/eax: (addr handle cell) <- get args, right
-1311   var _rest/eax: (addr cell) <- lookup *rest-ah
-1312   var rest/esi: (addr cell) <- copy _rest
-1313   # TODO: check that rest is a pair
-1314   var second-ah/eax: (addr handle cell) <- get rest, left
-1315   var second/eax: (addr cell) <- lookup *second-ah
-1316   var second-type/ecx: (addr int) <- get second, type
-1317   compare *second-type, 1/number
-1318   {
-1319     break-if-=
-1320     error trace, "second arg for 'pixel' is not an int (x coordinate)"
-1321     return
-1322   }
-1323   var second-value/eax: (addr float) <- get second, number-data
-1324   var x/edx: int <- convert *second-value
-1325   # y = rest->right->left->value
-1326   var rest-ah/eax: (addr handle cell) <- get rest, right
-1327   var _rest/eax: (addr cell) <- lookup *rest-ah
-1328   rest <- copy _rest
-1329   # TODO: check that rest is a pair
-1330   var third-ah/eax: (addr handle cell) <- get rest, left
-1331   var third/eax: (addr cell) <- lookup *third-ah
-1332   var third-type/ecx: (addr int) <- get third, type
-1333   compare *third-type, 1/number
-1334   {
-1335     break-if-=
-1336     error trace, "third arg for 'pixel' is not an int (y coordinate)"
-1337     return
-1338   }
-1339   var third-value/eax: (addr float) <- get third, number-data
-1340   var y/ebx: int <- convert *third-value
-1341   # color = rest->right->left->value
-1342   var rest-ah/eax: (addr handle cell) <- get rest, right
-1343   var _rest/eax: (addr cell) <- lookup *rest-ah
-1344   rest <- copy _rest
-1345   # TODO: check that rest is a pair
-1346   var fourth-ah/eax: (addr handle cell) <- get rest, left
-1347   var fourth/eax: (addr cell) <- lookup *fourth-ah
-1348   var fourth-type/ecx: (addr int) <- get fourth, type
-1349   compare *fourth-type, 1/number
-1350   {
-1351     break-if-=
-1352     error trace, "fourth arg for 'pixel' is not an int (color; 0..0xff)"
-1353     return
-1354   }
-1355   var fourth-value/eax: (addr float) <- get fourth, number-data
-1356   var color/eax: int <- convert *fourth-value
-1357   pixel screen, x, y, color
-1358   # return nothing
-1359 }
-1360 
-1361 fn apply-wait-for-key _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1362   trace-text trace, "eval", "apply key"
-1363   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1364   var _args/eax: (addr cell) <- lookup *args-ah
-1365   var args/esi: (addr cell) <- copy _args
-1366   # TODO: check that args is a pair
-1367   var empty-args?/eax: boolean <- nil? args
-1368   compare empty-args?, 0/false
-1369   {
-1370     break-if-=
-1371     error trace, "key needs 1 arg but got 0"
-1372     return
-1373   }
-1374   # keyboard = args->left
-1375   var first-ah/eax: (addr handle cell) <- get args, left
-1376   var first/eax: (addr cell) <- lookup *first-ah
-1377   var first-type/ecx: (addr int) <- get first, type
-1378   compare *first-type, 6/keyboard
-1379   {
+1296   var empty-args?/eax: boolean <- nil? args
+1297   compare empty-args?, 0/false
+1298   {
+1299     break-if-=
+1300     error trace, "'<=' needs 2 args but got 0"
+1301     return
+1302   }
+1303   # args->left
+1304   var first-ah/ecx: (addr handle cell) <- get args, left
+1305   # args->right->left
+1306   var right-ah/eax: (addr handle cell) <- get args, right
+1307   var right/eax: (addr cell) <- lookup *right-ah
+1308   {
+1309     var right-type/ecx: (addr int) <- get right, type
+1310     compare *right-type, 0/pair
+1311     break-if-=
+1312     error trace, "'<=' encountered non-pair"
+1313     return
+1314   }
+1315   {
+1316     var nil?/eax: boolean <- nil? right
+1317     compare nil?, 0/false
+1318     break-if-=
+1319     error trace, "'<=' needs 2 args but got 1"
+1320     return
+1321   }
+1322   var second-ah/edx: (addr handle cell) <- get right, left
+1323   # compare
+1324   var _first/eax: (addr cell) <- lookup *first-ah
+1325   var first/ecx: (addr cell) <- copy _first
+1326   var first-type/eax: (addr int) <- get first, type
+1327   compare *first-type, 1/number
+1328   {
+1329     break-if-=
+1330     error trace, "first arg for '<=' is not a number"
+1331     return
+1332   }
+1333   var first-value/ecx: (addr float) <- get first, number-data
+1334   var first-float/xmm0: float <- copy *first-value
+1335   var second/eax: (addr cell) <- lookup *second-ah
+1336   var second-type/edx: (addr int) <- get second, type
+1337   compare *second-type, 1/number
+1338   {
+1339     break-if-=
+1340     error trace, "second arg for '<=' is not a number"
+1341     return
+1342   }
+1343   var second-value/eax: (addr float) <- get second, number-data
+1344   compare first-float, *second-value
+1345   {
+1346     break-if-float<=
+1347     nil out
+1348     return
+1349   }
+1350   new-integer out, 1/true
+1351 }
+1352 
+1353 fn apply->= _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1354   trace-text trace, "eval", "apply '>='"
+1355   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1356   var _args/eax: (addr cell) <- lookup *args-ah
+1357   var args/esi: (addr cell) <- copy _args
+1358   {
+1359     var args-type/ecx: (addr int) <- get args, type
+1360     compare *args-type, 0/pair
+1361     break-if-=
+1362     error trace, "args to '>=' are not a list"
+1363     return
+1364   }
+1365   var empty-args?/eax: boolean <- nil? args
+1366   compare empty-args?, 0/false
+1367   {
+1368     break-if-=
+1369     error trace, "'>=' needs 2 args but got 0"
+1370     return
+1371   }
+1372   # args->left
+1373   var first-ah/ecx: (addr handle cell) <- get args, left
+1374   # args->right->left
+1375   var right-ah/eax: (addr handle cell) <- get args, right
+1376   var right/eax: (addr cell) <- lookup *right-ah
+1377   {
+1378     var right-type/ecx: (addr int) <- get right, type
+1379     compare *right-type, 0/pair
 1380     break-if-=
-1381     error trace, "first arg for 'key' is not a keyboard"
+1381     error trace, "'>=' encountered non-pair"
 1382     return
 1383   }
-1384   var keyboard-ah/eax: (addr handle gap-buffer) <- get first, keyboard-data
-1385   var _keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah
-1386   var keyboard/ecx: (addr gap-buffer) <- copy _keyboard
-1387   var result/eax: int <- wait-for-key keyboard
-1388   # return key typed
-1389   new-integer out, result
-1390 }
-1391 
-1392 fn wait-for-key keyboard: (addr gap-buffer) -> _/eax: int {
-1393   # if keyboard is 0, use real keyboard
-1394   {
-1395     compare keyboard, 0/real-keyboard
-1396     break-if-!=
-1397     var key/eax: byte <- read-key 0/real-keyboard
-1398     var result/eax: int <- copy key
-1399     return result
-1400   }
-1401   # otherwise read from fake keyboard
-1402   var g/eax: grapheme <- read-from-gap-buffer keyboard
-1403   var result/eax: int <- copy g
-1404   return result
-1405 }
-1406 
-1407 fn apply-stream _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1408   trace-text trace, "eval", "apply stream"
-1409   allocate-stream out
-1410 }
-1411 
-1412 fn apply-write _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1413   trace-text trace, "eval", "apply write"
-1414   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1415   var _args/eax: (addr cell) <- lookup *args-ah
-1416   var args/esi: (addr cell) <- copy _args
-1417   # TODO: check that args is a pair
-1418   var empty-args?/eax: boolean <- nil? args
-1419   compare empty-args?, 0/false
-1420   {
-1421     break-if-=
-1422     error trace, "write needs 2 args but got 0"
-1423     return
-1424   }
-1425   # stream = args->left
-1426   var first-ah/edx: (addr handle cell) <- get args, left
-1427   var first/eax: (addr cell) <- lookup *first-ah
-1428   var first-type/ecx: (addr int) <- get first, type
-1429   compare *first-type, 3/stream
-1430   {
-1431     break-if-=
-1432     error trace, "first arg for 'write' is not a stream"
-1433     return
-1434   }
-1435   var stream-data-ah/eax: (addr handle stream byte) <- get first, text-data
-1436   var _stream-data/eax: (addr stream byte) <- lookup *stream-data-ah
-1437   var stream-data/ebx: (addr stream byte) <- copy _stream-data
-1438   # args->right->left
-1439   var right-ah/eax: (addr handle cell) <- get args, right
-1440   var right/eax: (addr cell) <- lookup *right-ah
-1441   # TODO: check that right is a pair
-1442   var second-ah/eax: (addr handle cell) <- get right, left
-1443   var second/eax: (addr cell) <- lookup *second-ah
-1444   var second-type/ecx: (addr int) <- get second, type
-1445   compare *second-type, 1/number
+1384   {
+1385     var nil?/eax: boolean <- nil? right
+1386     compare nil?, 0/false
+1387     break-if-=
+1388     error trace, "'>=' needs 2 args but got 1"
+1389     return
+1390   }
+1391   var second-ah/edx: (addr handle cell) <- get right, left
+1392   # compare
+1393   var _first/eax: (addr cell) <- lookup *first-ah
+1394   var first/ecx: (addr cell) <- copy _first
+1395   var first-type/eax: (addr int) <- get first, type
+1396   compare *first-type, 1/number
+1397   {
+1398     break-if-=
+1399     error trace, "first arg for '>=' is not a number"
+1400     return
+1401   }
+1402   var first-value/ecx: (addr float) <- get first, number-data
+1403   var first-float/xmm0: float <- copy *first-value
+1404   var second/eax: (addr cell) <- lookup *second-ah
+1405   var second-type/edx: (addr int) <- get second, type
+1406   compare *second-type, 1/number
+1407   {
+1408     break-if-=
+1409     error trace, "second arg for '>=' is not a number"
+1410     return
+1411   }
+1412   var second-value/eax: (addr float) <- get second, number-data
+1413   compare first-float, *second-value
+1414   {
+1415     break-if-float>=
+1416     nil out
+1417     return
+1418   }
+1419   new-integer out, 1/true
+1420 }
+1421 
+1422 fn apply-print _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1423   trace-text trace, "eval", "apply 'print'"
+1424   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1425   var _args/eax: (addr cell) <- lookup *args-ah
+1426   var args/esi: (addr cell) <- copy _args
+1427   {
+1428     var args-type/ecx: (addr int) <- get args, type
+1429     compare *args-type, 0/pair
+1430     break-if-=
+1431     error trace, "args to 'print' are not a list"
+1432     return
+1433   }
+1434   var empty-args?/eax: boolean <- nil? args
+1435   compare empty-args?, 0/false
+1436   {
+1437     break-if-=
+1438     error trace, "'print' needs 2 args but got 0"
+1439     return
+1440   }
+1441   # screen = args->left
+1442   var first-ah/eax: (addr handle cell) <- get args, left
+1443   var first/eax: (addr cell) <- lookup *first-ah
+1444   var first-type/ecx: (addr int) <- get first, type
+1445   compare *first-type, 5/screen
 1446   {
 1447     break-if-=
-1448     error trace, "second arg for stream is not a number/grapheme"
+1448     error trace, "first arg for 'print' is not a screen"
 1449     return
 1450   }
-1451   var second-value/eax: (addr float) <- get second, number-data
-1452   var x-float/xmm0: float <- copy *second-value
-1453   var x/eax: int <- convert x-float
-1454   var x-grapheme/eax: grapheme <- copy x
-1455   write-grapheme stream-data, x-grapheme
-1456   # return the stream
-1457   copy-object first-ah, out
-1458 }
-1459 
-1460 fn apply-lines _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1461   trace-text trace, "eval", "apply lines"
-1462   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1463   var _args/eax: (addr cell) <- lookup *args-ah
-1464   var args/esi: (addr cell) <- copy _args
-1465   # TODO: check that args is a pair
-1466   var empty-args?/eax: boolean <- nil? args
-1467   compare empty-args?, 0/false
-1468   {
-1469     break-if-=
-1470     error trace, "lines needs 1 arg but got 0"
-1471     return
-1472   }
-1473   # screen = args->left
-1474   var first-ah/eax: (addr handle cell) <- get args, left
-1475   var first/eax: (addr cell) <- lookup *first-ah
-1476   var first-type/ecx: (addr int) <- get first, type
-1477   compare *first-type, 5/screen
-1478   {
-1479     break-if-=
-1480     error trace, "first arg for 'lines' is not a screen"
-1481     return
-1482   }
-1483   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1484   var _screen/eax: (addr screen) <- lookup *screen-ah
-1485   var screen/edx: (addr screen) <- copy _screen
-1486   # compute dimensions
-1487   var dummy/eax: int <- copy 0
-1488   var height/ecx: int <- copy 0
-1489   dummy, height <- screen-size screen
-1490   var result/xmm0: float <- convert height
-1491   new-float out, result
-1492 }
-1493 
-1494 fn apply-abort _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1495   abort "aa"
-1496 }
-1497 
-1498 fn apply-columns _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1499   trace-text trace, "eval", "apply columns"
-1500   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1501   var _args/eax: (addr cell) <- lookup *args-ah
-1502   var args/esi: (addr cell) <- copy _args
-1503   # TODO: check that args is a pair
-1504   var empty-args?/eax: boolean <- nil? args
-1505   compare empty-args?, 0/false
-1506   {
-1507     break-if-=
-1508     error trace, "columns needs 1 arg but got 0"
-1509     return
-1510   }
-1511   # screen = args->left
-1512   var first-ah/eax: (addr handle cell) <- get args, left
-1513   var first/eax: (addr cell) <- lookup *first-ah
-1514   var first-type/ecx: (addr int) <- get first, type
-1515   compare *first-type, 5/screen
-1516   {
-1517     break-if-=
-1518     error trace, "first arg for 'columns' is not a screen"
-1519     return
-1520   }
-1521   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1522   var _screen/eax: (addr screen) <- lookup *screen-ah
-1523   var screen/edx: (addr screen) <- copy _screen
-1524   # compute dimensions
-1525   var width/eax: int <- copy 0
-1526   var dummy/ecx: int <- copy 0
-1527   width, dummy <- screen-size screen
-1528   var result/xmm0: float <- convert width
-1529   new-float out, result
-1530 }
-1531 
-1532 fn apply-width _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1533   trace-text trace, "eval", "apply width"
-1534   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1535   var _args/eax: (addr cell) <- lookup *args-ah
-1536   var args/esi: (addr cell) <- copy _args
-1537   # TODO: check that args is a pair
-1538   var empty-args?/eax: boolean <- nil? args
-1539   compare empty-args?, 0/false
+1451   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1452   var _screen/eax: (addr screen) <- lookup *screen-ah
+1453   var screen/ecx: (addr screen) <- copy _screen
+1454   # args->right->left
+1455   var right-ah/eax: (addr handle cell) <- get args, right
+1456   var right/eax: (addr cell) <- lookup *right-ah
+1457   {
+1458     var right-type/ecx: (addr int) <- get right, type
+1459     compare *right-type, 0/pair
+1460     break-if-=
+1461     error trace, "'print' encountered non-pair"
+1462     return
+1463   }
+1464   {
+1465     var nil?/eax: boolean <- nil? right
+1466     compare nil?, 0/false
+1467     break-if-=
+1468     error trace, "'print' needs 2 args but got 1"
+1469     return
+1470   }
+1471   var second-ah/eax: (addr handle cell) <- get right, left
+1472   var stream-storage: (stream byte 0x100)
+1473   var stream/edi: (addr stream byte) <- address stream-storage
+1474   print-cell second-ah, stream, trace
+1475   draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen, stream, 7/fg, 0/bg
+1476   # return what was printed
+1477   copy-object second-ah, out
+1478 }
+1479 
+1480 fn apply-clear _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1481   trace-text trace, "eval", "apply 'clear'"
+1482   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1483   var _args/eax: (addr cell) <- lookup *args-ah
+1484   var args/esi: (addr cell) <- copy _args
+1485   {
+1486     var args-type/ecx: (addr int) <- get args, type
+1487     compare *args-type, 0/pair
+1488     break-if-=
+1489     error trace, "args to 'clear' are not a list"
+1490     return
+1491   }
+1492   var empty-args?/eax: boolean <- nil? args
+1493   compare empty-args?, 0/false
+1494   {
+1495     break-if-=
+1496     error trace, "'clear' needs 1 arg but got 0"
+1497     return
+1498   }
+1499   # screen = args->left
+1500   var first-ah/eax: (addr handle cell) <- get args, left
+1501   var first/eax: (addr cell) <- lookup *first-ah
+1502   var first-type/ecx: (addr int) <- get first, type
+1503   compare *first-type, 5/screen
+1504   {
+1505     break-if-=
+1506     error trace, "first arg for 'clear' is not a screen"
+1507     return
+1508   }
+1509   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1510   var _screen/eax: (addr screen) <- lookup *screen-ah
+1511   var screen/ecx: (addr screen) <- copy _screen
+1512   #
+1513   clear-screen screen
+1514 }
+1515 
+1516 fn apply-up _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1517   trace-text trace, "eval", "apply 'up'"
+1518   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1519   var _args/eax: (addr cell) <- lookup *args-ah
+1520   var args/esi: (addr cell) <- copy _args
+1521   {
+1522     var args-type/ecx: (addr int) <- get args, type
+1523     compare *args-type, 0/pair
+1524     break-if-=
+1525     error trace, "args to 'up' are not a list"
+1526     return
+1527   }
+1528   var empty-args?/eax: boolean <- nil? args
+1529   compare empty-args?, 0/false
+1530   {
+1531     break-if-=
+1532     error trace, "'up' needs 1 arg but got 0"
+1533     return
+1534   }
+1535   # screen = args->left
+1536   var first-ah/eax: (addr handle cell) <- get args, left
+1537   var first/eax: (addr cell) <- lookup *first-ah
+1538   var first-type/ecx: (addr int) <- get first, type
+1539   compare *first-type, 5/screen
 1540   {
 1541     break-if-=
-1542     error trace, "width needs 1 arg but got 0"
+1542     error trace, "first arg for 'up' is not a screen"
 1543     return
 1544   }
-1545   # screen = args->left
-1546   var first-ah/eax: (addr handle cell) <- get args, left
-1547   var first/eax: (addr cell) <- lookup *first-ah
-1548   var first-type/ecx: (addr int) <- get first, type
-1549   compare *first-type, 5/screen
-1550   {
-1551     break-if-=
-1552     error trace, "first arg for 'width' is not a screen"
-1553     return
-1554   }
-1555   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1556   var _screen/eax: (addr screen) <- lookup *screen-ah
-1557   var screen/edx: (addr screen) <- copy _screen
-1558   # compute dimensions
-1559   var width/eax: int <- copy 0
-1560   var dummy/ecx: int <- copy 0
-1561   width, dummy <- screen-size screen
-1562   width <- shift-left 3/log2-font-width
-1563   var result/xmm0: float <- convert width
-1564   new-float out, result
-1565 }
-1566 
-1567 fn apply-height _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
-1568   trace-text trace, "eval", "apply height"
-1569   var args-ah/eax: (addr handle cell) <- copy _args-ah
-1570   var _args/eax: (addr cell) <- lookup *args-ah
-1571   var args/esi: (addr cell) <- copy _args
-1572   # TODO: check that args is a pair
-1573   var empty-args?/eax: boolean <- nil? args
-1574   compare empty-args?, 0/false
-1575   {
-1576     break-if-=
-1577     error trace, "height needs 1 arg but got 0"
-1578     return
-1579   }
-1580   # screen = args->left
-1581   var first-ah/eax: (addr handle cell) <- get args, left
-1582   var first/eax: (addr cell) <- lookup *first-ah
-1583   var first-type/ecx: (addr int) <- get first, type
-1584   compare *first-type, 5/screen
-1585   {
-1586     break-if-=
-1587     error trace, "first arg for 'height' is not a screen"
-1588     return
-1589   }
-1590   var screen-ah/eax: (addr handle screen) <- get first, screen-data
-1591   var _screen/eax: (addr screen) <- lookup *screen-ah
-1592   var screen/edx: (addr screen) <- copy _screen
-1593   # compute dimensions
-1594   var dummy/eax: int <- copy 0
-1595   var height/ecx: int <- copy 0
-1596   dummy, height <- screen-size screen
-1597   height <- shift-left 4/log2-font-height
-1598   var result/xmm0: float <- convert height
-1599   new-float out, result
-1600 }
+1545   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1546   var _screen/eax: (addr screen) <- lookup *screen-ah
+1547   var screen/ecx: (addr screen) <- copy _screen
+1548   #
+1549   move-cursor-up screen
+1550 }
+1551 
+1552 fn apply-down _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1553   trace-text trace, "eval", "apply 'down'"
+1554   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1555   var _args/eax: (addr cell) <- lookup *args-ah
+1556   var args/esi: (addr cell) <- copy _args
+1557   {
+1558     var args-type/ecx: (addr int) <- get args, type
+1559     compare *args-type, 0/pair
+1560     break-if-=
+1561     error trace, "args to 'down' are not a list"
+1562     return
+1563   }
+1564   var empty-args?/eax: boolean <- nil? args
+1565   compare empty-args?, 0/false
+1566   {
+1567     break-if-=
+1568     error trace, "'down' needs 1 arg but got 0"
+1569     return
+1570   }
+1571   # screen = args->left
+1572   var first-ah/eax: (addr handle cell) <- get args, left
+1573   var first/eax: (addr cell) <- lookup *first-ah
+1574   var first-type/ecx: (addr int) <- get first, type
+1575   compare *first-type, 5/screen
+1576   {
+1577     break-if-=
+1578     error trace, "first arg for 'down' is not a screen"
+1579     return
+1580   }
+1581   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1582   var _screen/eax: (addr screen) <- lookup *screen-ah
+1583   var screen/ecx: (addr screen) <- copy _screen
+1584   #
+1585   move-cursor-down screen
+1586 }
+1587 
+1588 fn apply-left _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1589   trace-text trace, "eval", "apply 'left'"
+1590   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1591   var _args/eax: (addr cell) <- lookup *args-ah
+1592   var args/esi: (addr cell) <- copy _args
+1593   {
+1594     var args-type/ecx: (addr int) <- get args, type
+1595     compare *args-type, 0/pair
+1596     break-if-=
+1597     error trace, "args to 'left' are not a list"
+1598     return
+1599   }
+1600   var empty-args?/eax: boolean <- nil? args
+1601   compare empty-args?, 0/false
+1602   {
+1603     break-if-=
+1604     error trace, "'left' needs 1 arg but got 0"
+1605     return
+1606   }
+1607   # screen = args->left
+1608   var first-ah/eax: (addr handle cell) <- get args, left
+1609   var first/eax: (addr cell) <- lookup *first-ah
+1610   var first-type/ecx: (addr int) <- get first, type
+1611   compare *first-type, 5/screen
+1612   {
+1613     break-if-=
+1614     error trace, "first arg for 'left' is not a screen"
+1615     return
+1616   }
+1617   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1618   var _screen/eax: (addr screen) <- lookup *screen-ah
+1619   var screen/ecx: (addr screen) <- copy _screen
+1620   #
+1621   move-cursor-left screen
+1622 }
+1623 
+1624 fn apply-right _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1625   trace-text trace, "eval", "apply 'right'"
+1626   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1627   var _args/eax: (addr cell) <- lookup *args-ah
+1628   var args/esi: (addr cell) <- copy _args
+1629   {
+1630     var args-type/ecx: (addr int) <- get args, type
+1631     compare *args-type, 0/pair
+1632     break-if-=
+1633     error trace, "args to 'right' are not a list"
+1634     return
+1635   }
+1636   var empty-args?/eax: boolean <- nil? args
+1637   compare empty-args?, 0/false
+1638   {
+1639     break-if-=
+1640     error trace, "'right' needs 1 arg but got 0"
+1641     return
+1642   }
+1643   # screen = args->left
+1644   var first-ah/eax: (addr handle cell) <- get args, left
+1645   var first/eax: (addr cell) <- lookup *first-ah
+1646   var first-type/ecx: (addr int) <- get first, type
+1647   compare *first-type, 5/screen
+1648   {
+1649     break-if-=
+1650     error trace, "first arg for 'right' is not a screen"
+1651     return
+1652   }
+1653   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1654   var _screen/eax: (addr screen) <- lookup *screen-ah
+1655   var screen/ecx: (addr screen) <- copy _screen
+1656   #
+1657   move-cursor-right screen
+1658 }
+1659 
+1660 fn apply-cr _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1661   trace-text trace, "eval", "apply 'cr'"
+1662   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1663   var _args/eax: (addr cell) <- lookup *args-ah
+1664   var args/esi: (addr cell) <- copy _args
+1665   {
+1666     var args-type/ecx: (addr int) <- get args, type
+1667     compare *args-type, 0/pair
+1668     break-if-=
+1669     error trace, "args to 'cr' are not a list"
+1670     return
+1671   }
+1672   var empty-args?/eax: boolean <- nil? args
+1673   compare empty-args?, 0/false
+1674   {
+1675     break-if-=
+1676     error trace, "'cr' needs 1 arg but got 0"
+1677     return
+1678   }
+1679   # screen = args->left
+1680   var first-ah/eax: (addr handle cell) <- get args, left
+1681   var first/eax: (addr cell) <- lookup *first-ah
+1682   var first-type/ecx: (addr int) <- get first, type
+1683   compare *first-type, 5/screen
+1684   {
+1685     break-if-=
+1686     error trace, "first arg for 'cr' is not a screen"
+1687     return
+1688   }
+1689   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1690   var _screen/eax: (addr screen) <- lookup *screen-ah
+1691   var screen/ecx: (addr screen) <- copy _screen
+1692   #
+1693   move-cursor-to-left-margin-of-next-line screen
+1694 }
+1695 
+1696 fn apply-pixel _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1697   trace-text trace, "eval", "apply 'pixel'"
+1698   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1699   var _args/eax: (addr cell) <- lookup *args-ah
+1700   var args/esi: (addr cell) <- copy _args
+1701   {
+1702     var args-type/ecx: (addr int) <- get args, type
+1703     compare *args-type, 0/pair
+1704     break-if-=
+1705     error trace, "args to 'pixel' are not a list"
+1706     return
+1707   }
+1708   var empty-args?/eax: boolean <- nil? args
+1709   compare empty-args?, 0/false
+1710   {
+1711     break-if-=
+1712     error trace, "'pixel' needs 4 args but got 0"
+1713     return
+1714   }
+1715   # screen = args->left
+1716   var first-ah/eax: (addr handle cell) <- get args, left
+1717   var first/eax: (addr cell) <- lookup *first-ah
+1718   var first-type/ecx: (addr int) <- get first, type
+1719   compare *first-type, 5/screen
+1720   {
+1721     break-if-=
+1722     error trace, "first arg for 'pixel' is not a screen"
+1723     return
+1724   }
+1725   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1726   var _screen/eax: (addr screen) <- lookup *screen-ah
+1727   var screen/edi: (addr screen) <- copy _screen
+1728   # x = args->right->left->value
+1729   var rest-ah/eax: (addr handle cell) <- get args, right
+1730   var _rest/eax: (addr cell) <- lookup *rest-ah
+1731   var rest/esi: (addr cell) <- copy _rest
+1732   {
+1733     var rest-type/ecx: (addr int) <- get rest, type
+1734     compare *rest-type, 0/pair
+1735     break-if-=
+1736     error trace, "'pixel' encountered non-pair"
+1737     return
+1738   }
+1739   {
+1740     var rest-nil?/eax: boolean <- nil? rest
+1741     compare rest-nil?, 0/false
+1742     break-if-=
+1743     error trace, "'pixel' needs 4 args but got 1"
+1744     return
+1745   }
+1746   var second-ah/eax: (addr handle cell) <- get rest, left
+1747   var second/eax: (addr cell) <- lookup *second-ah
+1748   var second-type/ecx: (addr int) <- get second, type
+1749   compare *second-type, 1/number
+1750   {
+1751     break-if-=
+1752     error trace, "second arg for 'pixel' is not an int (x coordinate)"
+1753     return
+1754   }
+1755   var second-value/eax: (addr float) <- get second, number-data
+1756   var x/edx: int <- convert *second-value
+1757   # y = rest->right->left->value
+1758   var rest-ah/eax: (addr handle cell) <- get rest, right
+1759   var _rest/eax: (addr cell) <- lookup *rest-ah
+1760   rest <- copy _rest
+1761   {
+1762     var rest-type/ecx: (addr int) <- get rest, type
+1763     compare *rest-type, 0/pair
+1764     break-if-=
+1765     error trace, "'pixel' encountered non-pair"
+1766     return
+1767   }
+1768   {
+1769     var rest-nil?/eax: boolean <- nil? rest
+1770     compare rest-nil?, 0/false
+1771     break-if-=
+1772     error trace, "'pixel' needs 4 args but got 2"
+1773     return
+1774   }
+1775   var third-ah/eax: (addr handle cell) <- get rest, left
+1776   var third/eax: (addr cell) <- lookup *third-ah
+1777   var third-type/ecx: (addr int) <- get third, type
+1778   compare *third-type, 1/number
+1779   {
+1780     break-if-=
+1781     error trace, "third arg for 'pixel' is not an int (y coordinate)"
+1782     return
+1783   }
+1784   var third-value/eax: (addr float) <- get third, number-data
+1785   var y/ebx: int <- convert *third-value
+1786   # color = rest->right->left->value
+1787   var rest-ah/eax: (addr handle cell) <- get rest, right
+1788   var _rest/eax: (addr cell) <- lookup *rest-ah
+1789   rest <- copy _rest
+1790   {
+1791     var rest-type/ecx: (addr int) <- get rest, type
+1792     compare *rest-type, 0/pair
+1793     break-if-=
+1794     error trace, "'pixel' encountered non-pair"
+1795     return
+1796   }
+1797   {
+1798     var rest-nil?/eax: boolean <- nil? rest
+1799     compare rest-nil?, 0/false
+1800     break-if-=
+1801     error trace, "'pixel' needs 4 args but got 3"
+1802     return
+1803   }
+1804   var fourth-ah/eax: (addr handle cell) <- get rest, left
+1805   var fourth/eax: (addr cell) <- lookup *fourth-ah
+1806   var fourth-type/ecx: (addr int) <- get fourth, type
+1807   compare *fourth-type, 1/number
+1808   {
+1809     break-if-=
+1810     error trace, "fourth arg for 'pixel' is not an int (color; 0..0xff)"
+1811     return
+1812   }
+1813   var fourth-value/eax: (addr float) <- get fourth, number-data
+1814   var color/eax: int <- convert *fourth-value
+1815   pixel screen, x, y, color
+1816   # return nothing
+1817 }
+1818 
+1819 fn apply-wait-for-key _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1820   trace-text trace, "eval", "apply 'key'"
+1821   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1822   var _args/eax: (addr cell) <- lookup *args-ah
+1823   var args/esi: (addr cell) <- copy _args
+1824   {
+1825     var args-type/ecx: (addr int) <- get args, type
+1826     compare *args-type, 0/pair
+1827     break-if-=
+1828     error trace, "args to 'key' are not a list"
+1829     return
+1830   }
+1831   var empty-args?/eax: boolean <- nil? args
+1832   compare empty-args?, 0/false
+1833   {
+1834     break-if-=
+1835     error trace, "'key' needs 1 arg but got 0"
+1836     return
+1837   }
+1838   # keyboard = args->left
+1839   var first-ah/eax: (addr handle cell) <- get args, left
+1840   var first/eax: (addr cell) <- lookup *first-ah
+1841   var first-type/ecx: (addr int) <- get first, type
+1842   compare *first-type, 6/keyboard
+1843   {
+1844     break-if-=
+1845     error trace, "first arg for 'key' is not a keyboard"
+1846     return
+1847   }
+1848   var keyboard-ah/eax: (addr handle gap-buffer) <- get first, keyboard-data
+1849   var _keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah
+1850   var keyboard/ecx: (addr gap-buffer) <- copy _keyboard
+1851   var result/eax: int <- wait-for-key keyboard
+1852   # return key typed
+1853   new-integer out, result
+1854 }
+1855 
+1856 fn wait-for-key keyboard: (addr gap-buffer) -> _/eax: int {
+1857   # if keyboard is 0, use real keyboard
+1858   {
+1859     compare keyboard, 0/real-keyboard
+1860     break-if-!=
+1861     var key/eax: byte <- read-key 0/real-keyboard
+1862     var result/eax: int <- copy key
+1863     return result
+1864   }
+1865   # otherwise read from fake keyboard
+1866   var g/eax: grapheme <- read-from-gap-buffer keyboard
+1867   var result/eax: int <- copy g
+1868   return result
+1869 }
+1870 
+1871 fn apply-stream _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1872   trace-text trace, "eval", "apply stream"
+1873   allocate-stream out
+1874 }
+1875 
+1876 fn apply-write _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1877   trace-text trace, "eval", "apply 'write'"
+1878   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1879   var _args/eax: (addr cell) <- lookup *args-ah
+1880   var args/esi: (addr cell) <- copy _args
+1881   {
+1882     var args-type/ecx: (addr int) <- get args, type
+1883     compare *args-type, 0/pair
+1884     break-if-=
+1885     error trace, "args to 'write' are not a list"
+1886     return
+1887   }
+1888   var empty-args?/eax: boolean <- nil? args
+1889   compare empty-args?, 0/false
+1890   {
+1891     break-if-=
+1892     error trace, "'write' needs 2 args but got 0"
+1893     return
+1894   }
+1895   # stream = args->left
+1896   var first-ah/edx: (addr handle cell) <- get args, left
+1897   var first/eax: (addr cell) <- lookup *first-ah
+1898   var first-type/ecx: (addr int) <- get first, type
+1899   compare *first-type, 3/stream
+1900   {
+1901     break-if-=
+1902     error trace, "first arg for 'write' is not a stream"
+1903     return
+1904   }
+1905   var stream-data-ah/eax: (addr handle stream byte) <- get first, text-data
+1906   var _stream-data/eax: (addr stream byte) <- lookup *stream-data-ah
+1907   var stream-data/ebx: (addr stream byte) <- copy _stream-data
+1908   # args->right->left
+1909   var right-ah/eax: (addr handle cell) <- get args, right
+1910   var right/eax: (addr cell) <- lookup *right-ah
+1911   {
+1912     var right-type/ecx: (addr int) <- get right, type
+1913     compare *right-type, 0/pair
+1914     break-if-=
+1915     error trace, "'write' encountered non-pair"
+1916     return
+1917   }
+1918   {
+1919     var nil?/eax: boolean <- nil? right
+1920     compare nil?, 0/false
+1921     break-if-=
+1922     error trace, "'write' needs 2 args but got 1"
+1923     return
+1924   }
+1925   var second-ah/eax: (addr handle cell) <- get right, left
+1926   var second/eax: (addr cell) <- lookup *second-ah
+1927   var second-type/ecx: (addr int) <- get second, type
+1928   compare *second-type, 1/number
+1929   {
+1930     break-if-=
+1931     error trace, "second arg for 'write' is not a number/grapheme"
+1932     return
+1933   }
+1934   var second-value/eax: (addr float) <- get second, number-data
+1935   var x-float/xmm0: float <- copy *second-value
+1936   var x/eax: int <- convert x-float
+1937   var x-grapheme/eax: grapheme <- copy x
+1938   write-grapheme stream-data, x-grapheme
+1939   # return the stream
+1940   copy-object first-ah, out
+1941 }
+1942 
+1943 fn apply-lines _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1944   trace-text trace, "eval", "apply 'lines'"
+1945   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1946   var _args/eax: (addr cell) <- lookup *args-ah
+1947   var args/esi: (addr cell) <- copy _args
+1948   {
+1949     var args-type/ecx: (addr int) <- get args, type
+1950     compare *args-type, 0/pair
+1951     break-if-=
+1952     error trace, "args to 'lines' are not a list"
+1953     return
+1954   }
+1955   var empty-args?/eax: boolean <- nil? args
+1956   compare empty-args?, 0/false
+1957   {
+1958     break-if-=
+1959     error trace, "'lines' needs 1 arg but got 0"
+1960     return
+1961   }
+1962   # screen = args->left
+1963   var first-ah/eax: (addr handle cell) <- get args, left
+1964   var first/eax: (addr cell) <- lookup *first-ah
+1965   var first-type/ecx: (addr int) <- get first, type
+1966   compare *first-type, 5/screen
+1967   {
+1968     break-if-=
+1969     error trace, "first arg for 'lines' is not a screen"
+1970     return
+1971   }
+1972   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+1973   var _screen/eax: (addr screen) <- lookup *screen-ah
+1974   var screen/edx: (addr screen) <- copy _screen
+1975   # compute dimensions
+1976   var dummy/eax: int <- copy 0
+1977   var height/ecx: int <- copy 0
+1978   dummy, height <- screen-size screen
+1979   var result/xmm0: float <- convert height
+1980   new-float out, result
+1981 }
+1982 
+1983 fn apply-abort _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1984   abort "aa"
+1985 }
+1986 
+1987 fn apply-columns _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+1988   trace-text trace, "eval", "apply 'columns'"
+1989   var args-ah/eax: (addr handle cell) <- copy _args-ah
+1990   var _args/eax: (addr cell) <- lookup *args-ah
+1991   var args/esi: (addr cell) <- copy _args
+1992   {
+1993     var args-type/ecx: (addr int) <- get args, type
+1994     compare *args-type, 0/pair
+1995     break-if-=
+1996     error trace, "args to 'columns' are not a list"
+1997     return
+1998   }
+1999   var empty-args?/eax: boolean <- nil? args
+2000   compare empty-args?, 0/false
+2001   {
+2002     break-if-=
+2003     error trace, "'columns' needs 1 arg but got 0"
+2004     return
+2005   }
+2006   # screen = args->left
+2007   var first-ah/eax: (addr handle cell) <- get args, left
+2008   var first/eax: (addr cell) <- lookup *first-ah
+2009   var first-type/ecx: (addr int) <- get first, type
+2010   compare *first-type, 5/screen
+2011   {
+2012     break-if-=
+2013     error trace, "first arg for 'columns' is not a screen"
+2014     return
+2015   }
+2016   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+2017   var _screen/eax: (addr screen) <- lookup *screen-ah
+2018   var screen/edx: (addr screen) <- copy _screen
+2019   # compute dimensions
+2020   var width/eax: int <- copy 0
+2021   var dummy/ecx: int <- copy 0
+2022   width, dummy <- screen-size screen
+2023   var result/xmm0: float <- convert width
+2024   new-float out, result
+2025 }
+2026 
+2027 fn apply-width _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+2028   trace-text trace, "eval", "apply 'width'"
+2029   var args-ah/eax: (addr handle cell) <- copy _args-ah
+2030   var _args/eax: (addr cell) <- lookup *args-ah
+2031   var args/esi: (addr cell) <- copy _args
+2032   {
+2033     var args-type/ecx: (addr int) <- get args, type
+2034     compare *args-type, 0/pair
+2035     break-if-=
+2036     error trace, "args to 'width' are not a list"
+2037     return
+2038   }
+2039   var empty-args?/eax: boolean <- nil? args
+2040   compare empty-args?, 0/false
+2041   {
+2042     break-if-=
+2043     error trace, "'width' needs 1 arg but got 0"
+2044     return
+2045   }
+2046   # screen = args->left
+2047   var first-ah/eax: (addr handle cell) <- get args, left
+2048   var first/eax: (addr cell) <- lookup *first-ah
+2049   var first-type/ecx: (addr int) <- get first, type
+2050   compare *first-type, 5/screen
+2051   {
+2052     break-if-=
+2053     error trace, "first arg for 'width' is not a screen"
+2054     return
+2055   }
+2056   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+2057   var _screen/eax: (addr screen) <- lookup *screen-ah
+2058   var screen/edx: (addr screen) <- copy _screen
+2059   # compute dimensions
+2060   var width/eax: int <- copy 0
+2061   var dummy/ecx: int <- copy 0
+2062   width, dummy <- screen-size screen
+2063   width <- shift-left 3/log2-font-width
+2064   var result/xmm0: float <- convert width
+2065   new-float out, result
+2066 }
+2067 
+2068 fn apply-height _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
+2069   trace-text trace, "eval", "apply 'height'"
+2070   var args-ah/eax: (addr handle cell) <- copy _args-ah
+2071   var _args/eax: (addr cell) <- lookup *args-ah
+2072   var args/esi: (addr cell) <- copy _args
+2073   {
+2074     var args-type/ecx: (addr int) <- get args, type
+2075     compare *args-type, 0/pair
+2076     break-if-=
+2077     error trace, "args to 'height' are not a list"
+2078     return
+2079   }
+2080   var empty-args?/eax: boolean <- nil? args
+2081   compare empty-args?, 0/false
+2082   {
+2083     break-if-=
+2084     error trace, "'height' needs 1 arg but got 0"
+2085     return
+2086   }
+2087   # screen = args->left
+2088   var first-ah/eax: (addr handle cell) <- get args, left
+2089   var first/eax: (addr cell) <- lookup *first-ah
+2090   var first-type/ecx: (addr int) <- get first, type
+2091   compare *first-type, 5/screen
+2092   {
+2093     break-if-=
+2094     error trace, "first arg for 'height' is not a screen"
+2095     return
+2096   }
+2097   var screen-ah/eax: (addr handle screen) <- get first, screen-data
+2098   var _screen/eax: (addr screen) <- lookup *screen-ah
+2099   var screen/edx: (addr screen) <- copy _screen
+2100   # compute dimensions
+2101   var dummy/eax: int <- copy 0
+2102   var height/ecx: int <- copy 0
+2103   dummy, height <- screen-size screen
+2104   height <- shift-left 4/log2-font-height
+2105   var result/xmm0: float <- convert height
+2106   new-float out, result
+2107 }
 
diff --git a/html/shell/print.mu.html b/html/shell/print.mu.html index 09e963d4..b528a799 100644 --- a/html/shell/print.mu.html +++ b/html/shell/print.mu.html @@ -15,14 +15,14 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } -.muRegEdx { color: #878700; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } -.muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } +.muRegEdx { color: #878700; } .Constant { color: #008787; } +.muRegEsi { color: #87d787; } .muRegEax { color: #875f00; } -.muRegEcx { color: #af875f; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muTest { color: #5f8700; } diff --git a/html/shell/read.mu.html b/html/shell/read.mu.html index c25ebb64..e7ce90fd 100644 --- a/html/shell/read.mu.html +++ b/html/shell/read.mu.html @@ -15,11 +15,11 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .PreProc { color: #c000c0; } +.muRegEcx { color: #af875f; } .Special { color: #ff6060; } .LineNr { } .Constant { color: #008787; } .muRegEax { color: #875f00; } -.muRegEcx { color: #af875f; } .Delimiter { color: #c000c0; } .muFunction { color: #af5f00; text-decoration: underline; } .muComment { color: #005faf; } diff --git a/html/shell/sandbox.mu.html b/html/shell/sandbox.mu.html index d75bd69e..f0760df1 100644 --- a/html/shell/sandbox.mu.html +++ b/html/shell/sandbox.mu.html @@ -16,19 +16,19 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } .Delimiter { color: #c000c0; } -.muFunction { color: #af5f00; text-decoration: underline; } +.CommentedCode { color: #8a8a8a; } +.muRegEdx { color: #878700; } .muRegEbx { color: #8787af; } .muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } .Constant { color: #008787; } .Special { color: #ff6060; } .PreProc { color: #c000c0; } -.CommentedCode { color: #8a8a8a; } +.muFunction { color: #af5f00; text-decoration: underline; } .muTest { color: #5f8700; } .muComment { color: #005faf; } .muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } --> @@ -75,21 +75,21 @@ if ('onhashchange' in window) { 9 cursor-in-keyboard?: boolean 10 } 11 - 12 fn initialize-sandbox _self: (addr sandbox), fake-screen-and-keyboard?: boolean { + 12 fn initialize-sandbox _self: (addr sandbox), fake-screen-width: int, fake-screen-height: int { 13 var self/esi: (addr sandbox) <- copy _self 14 var data-ah/eax: (addr handle gap-buffer) <- get self, data 15 allocate data-ah 16 var data/eax: (addr gap-buffer) <- lookup *data-ah - 17 initialize-gap-buffer data, 0x1000/4KB + 17 initialize-gap-buffer data, 0x2000/default-gap-buffer-size=8KB 18 # 19 var value-ah/eax: (addr handle stream byte) <- get self, value 20 populate-stream value-ah, 0x1000/4KB 21 # 22 { - 23 compare fake-screen-and-keyboard?, 0/false + 23 compare fake-screen-width, 0 24 break-if-= 25 var screen-ah/eax: (addr handle cell) <- get self, screen-var - 26 new-fake-screen screen-ah, 8/width, 3/height, 1/enable-pixel-graphics + 26 new-fake-screen screen-ah, fake-screen-width, fake-screen-height, 1/enable-pixel-graphics 27 var keyboard-ah/eax: (addr handle cell) <- get self, keyboard-var 28 new-fake-keyboard keyboard-ah, 0x10/keyboard-capacity 29 } @@ -132,7 +132,7 @@ if ('onhashchange' in window) { 66 var data-ah/eax: (addr handle gap-buffer) <- get self, data 67 var data/eax: (addr gap-buffer) <- lookup *data-ah 68 { - 69 var len/eax: int <- gap-buffer-length data + 69 var len/eax: int <- gap-buffer-length data 70 compare len, 0 71 break-if-!= 72 return @@ -145,7 +145,7 @@ if ('onhashchange' in window) { 79 ## 80 81 fn render-sandbox screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int, xmax: int, ymax: int, show-cursor?: boolean { - 82 clear-rect screen, xmin, ymin, xmax, ymax, 0xc5/bg=blue-bg + 82 clear-rect screen, xmin, ymin, xmax, ymax, 0xc5/bg=blue-bg 83 add-to xmin, 1/padding-left 84 add-to ymin, 1/padding-top 85 subtract-from xmax, 1/padding-right @@ -157,7 +157,7 @@ if ('onhashchange' in window) { 91 var x/eax: int <- copy xmin 92 var y/ecx: int <- copy ymin 93 y <- maybe-render-empty-screen screen, self, xmin, y - 94 y <- maybe-render-keyboard screen, self, xmin, y + 94 y <- maybe-render-keyboard screen, self, xmin, y 95 var cursor-in-editor?/ebx: boolean <- copy show-cursor? 96 { 97 compare cursor-in-editor?, 0/false @@ -190,7 +190,7 @@ if ('onhashchange' in window) { 124 var dummy/eax: int <- draw-stream-rightward screen, value, x2, xmax, y, 7/fg=grey, 0xc5/bg=blue-bg 125 } 126 y <- add 2 # padding - 127 y <- maybe-render-screen screen, self, xmin, y + 127 maybe-render-screen screen, self, xmin, y 128 } 129 130 fn render-sandbox-menu screen: (addr screen), _self: (addr sandbox) { @@ -199,7 +199,7 @@ if ('onhashchange' in window) { 133 compare *cursor-in-data?, 0/false 134 { 135 break-if-= - 136 render-sandbox-edit-menu screen, self + 136 render-sandbox-edit-menu screen, self 137 return 138 } 139 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? @@ -213,7 +213,7 @@ if ('onhashchange' in window) { 147 compare *cursor-in-keyboard?, 0/false 148 { 149 break-if-= - 150 render-keyboard-menu screen + 150 render-keyboard-menu screen 151 return 152 } 153 } @@ -227,11 +227,11 @@ if ('onhashchange' in window) { 161 var x/eax: int <- copy xmin 162 var y/ecx: int <- copy ymin 163 y <- maybe-render-empty-screen screen, self, xmin, y - 164 y <- maybe-render-keyboard screen, self, xmin, y + 164 y <- maybe-render-keyboard screen, self, xmin, y 165 var cursor-in-sandbox?/ebx: (addr boolean) <- get self, cursor-in-data? 166 x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, xmax, ymax, *cursor-in-sandbox?, 3/fg, 0xc5/bg=blue-bg 167 y <- increment - 168 clear-rect screen, xmin, y, xmax, ymax, 0xc5/bg=blue-bg + 168 clear-rect screen, xmin, y, xmax, ymax, 0xc5/bg=blue-bg 169 } 170 171 fn maybe-render-empty-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int { @@ -254,1016 +254,947 @@ if ('onhashchange' in window) { 188 var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah 189 var screen-obj/edx: (addr screen) <- copy _screen-obj 190 var x/eax: int <- draw-text-rightward screen, "screen: ", xmin, 0x99/xmax, y, 0x17/fg, 0xc5/bg=blue-bg - 191 y <- render-empty-screen screen, screen-obj, x, y - 192 return y - 193 } - 194 - 195 fn maybe-render-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int { - 196 var self/esi: (addr sandbox) <- copy _self - 197 var screen-obj-cell-ah/eax: (addr handle cell) <- get self, screen-var - 198 var screen-obj-cell/eax: (addr cell) <- lookup *screen-obj-cell-ah - 199 compare screen-obj-cell, 0 - 200 { - 201 break-if-!= - 202 return ymin - 203 } - 204 var screen-obj-cell-type/ecx: (addr int) <- get screen-obj-cell, type - 205 compare *screen-obj-cell-type, 5/screen - 206 { - 207 break-if-= - 208 return ymin # silently give up on rendering the screen - 209 } - 210 var screen-obj-ah/eax: (addr handle screen) <- get screen-obj-cell, screen-data - 211 var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah - 212 var screen-obj/edx: (addr screen) <- copy _screen-obj - 213 { - 214 var screen-empty?/eax: boolean <- fake-screen-empty? screen-obj - 215 compare screen-empty?, 0/false - 216 break-if-= - 217 return ymin - 218 } - 219 var x/eax: int <- draw-text-rightward screen, "screen: ", xmin, 0x99/xmax, ymin, 0x17/fg, 0xc5/bg=blue-bg - 220 var y/ecx: int <- copy ymin - 221 y <- render-screen screen, screen-obj, x, y - 222 return y - 223 } - 224 - 225 fn render-empty-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int -> _/ecx: int { - 226 var target-screen/esi: (addr screen) <- copy _target-screen - 227 var screen-y/edi: int <- copy ymin - 228 # screen - 229 var height/edx: (addr int) <- get target-screen, height - 230 var y/ecx: int <- copy 0 - 231 { - 232 compare y, *height - 233 break-if->= - 234 set-cursor-position screen, xmin, screen-y - 235 var width/edx: (addr int) <- get target-screen, width - 236 var x/ebx: int <- copy 0 - 237 { - 238 compare x, *width - 239 break-if->= - 240 draw-code-point-at-cursor screen, 0x20/space, 0x18/fg, 0/bg - 241 move-cursor-right screen - 242 x <- increment - 243 loop - 244 } - 245 y <- increment - 246 screen-y <- increment - 247 loop - 248 } - 249 return screen-y - 250 } - 251 - 252 fn render-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int -> _/ecx: int { - 253 var target-screen/esi: (addr screen) <- copy _target-screen - 254 var screen-y/edi: int <- copy ymin - 255 # text data - 256 { - 257 var height/edx: (addr int) <- get target-screen, height - 258 var y/ecx: int <- copy 0 - 259 { - 260 compare y, *height - 261 break-if->= - 262 set-cursor-position screen, xmin, screen-y - 263 var width/edx: (addr int) <- get target-screen, width - 264 var x/ebx: int <- copy 0 - 265 { - 266 compare x, *width - 267 break-if->= - 268 print-screen-cell-of-fake-screen screen, target-screen, x, y - 269 move-cursor-right screen - 270 x <- increment - 271 loop - 272 } - 273 y <- increment - 274 screen-y <- increment - 275 loop - 276 } - 277 } - 278 # pixel data - 279 { - 280 # screen top left pixels x y width height - 281 var tmp/eax: int <- copy xmin - 282 tmp <- shift-left 3/log2-font-width - 283 var left: int - 284 copy-to left, tmp - 285 tmp <- copy ymin - 286 tmp <- shift-left 4/log2-font-height - 287 var top: int - 288 copy-to top, tmp - 289 var pixels-ah/eax: (addr handle array byte) <- get target-screen, pixels - 290 var _pixels/eax: (addr array byte) <- lookup *pixels-ah - 291 var pixels/edi: (addr array byte) <- copy _pixels - 292 compare pixels, 0 - 293 break-if-= - 294 var y/ebx: int <- copy 0 - 295 var height-addr/edx: (addr int) <- get target-screen, height - 296 var height/edx: int <- copy *height-addr - 297 height <- shift-left 4/log2-font-height - 298 { - 299 compare y, height - 300 break-if->= - 301 var width-addr/edx: (addr int) <- get target-screen, width - 302 var width/edx: int <- copy *width-addr - 303 width <- shift-left 3/log2-font-width - 304 var x/eax: int <- copy 0 - 305 { - 306 compare x, width - 307 break-if->= - 308 { - 309 var idx/ecx: int <- pixel-index target-screen, x, y - 310 var color-addr/ecx: (addr byte) <- index pixels, idx - 311 var color/ecx: byte <- copy-byte *color-addr - 312 var color2/ecx: int <- copy color - 313 compare color2, 0 - 314 break-if-= - 315 var x2/eax: int <- copy x - 316 x2 <- add left - 317 var y2/ebx: int <- copy y - 318 y2 <- add top - 319 pixel screen, x2, y2, color2 - 320 } - 321 x <- increment - 322 loop - 323 } - 324 y <- increment - 325 loop - 326 } - 327 } - 328 return screen-y - 329 } - 330 - 331 fn has-keyboard? _self: (addr sandbox) -> _/eax: boolean { - 332 var self/esi: (addr sandbox) <- copy _self - 333 var keyboard-obj-cell-ah/eax: (addr handle cell) <- get self, keyboard-var - 334 var keyboard-obj-cell/eax: (addr cell) <- lookup *keyboard-obj-cell-ah - 335 compare keyboard-obj-cell, 0 - 336 { - 337 break-if-!= - 338 return 0/false - 339 } - 340 var keyboard-obj-cell-type/ecx: (addr int) <- get keyboard-obj-cell, type - 341 compare *keyboard-obj-cell-type, 6/keyboard + 191 x <- copy xmin + 192 x <- add 2 + 193 y <- increment + 194 y <- render-empty-screen screen, screen-obj, x, y + 195 return y + 196 } + 197 + 198 fn maybe-render-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int { + 199 var self/esi: (addr sandbox) <- copy _self + 200 var screen-obj-cell-ah/eax: (addr handle cell) <- get self, screen-var + 201 var screen-obj-cell/eax: (addr cell) <- lookup *screen-obj-cell-ah + 202 compare screen-obj-cell, 0 + 203 { + 204 break-if-!= + 205 return + 206 } + 207 var screen-obj-cell-type/ecx: (addr int) <- get screen-obj-cell, type + 208 compare *screen-obj-cell-type, 5/screen + 209 { + 210 break-if-= + 211 return # silently give up on rendering the screen + 212 } + 213 var screen-obj-ah/eax: (addr handle screen) <- get screen-obj-cell, screen-data + 214 var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah + 215 var screen-obj/edx: (addr screen) <- copy _screen-obj + 216 { + 217 var screen-empty?/eax: boolean <- fake-screen-empty? screen-obj + 218 compare screen-empty?, 0/false + 219 break-if-= + 220 return + 221 } + 222 var x/eax: int <- draw-text-rightward screen, "screen: ", xmin, 0x99/xmax, ymin, 0x17/fg, 0xc5/bg=blue-bg + 223 x <- copy xmin + 224 x <- add 2 + 225 var y/ecx: int <- copy ymin + 226 y <- increment + 227 render-screen screen, screen-obj, x, y + 228 } + 229 + 230 fn render-empty-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int -> _/ecx: int { + 231 var target-screen/esi: (addr screen) <- copy _target-screen + 232 var screen-y/edi: int <- copy ymin + 233 # screen + 234 var height/edx: (addr int) <- get target-screen, height + 235 var y/ecx: int <- copy 0 + 236 { + 237 compare y, *height + 238 break-if->= + 239 set-cursor-position screen, xmin, screen-y + 240 var width/edx: (addr int) <- get target-screen, width + 241 var x/ebx: int <- copy 0 + 242 { + 243 compare x, *width + 244 break-if->= + 245 draw-code-point-at-cursor screen, 0x20/space, 0x18/fg, 0/bg + 246 move-cursor-right screen + 247 x <- increment + 248 loop + 249 } + 250 y <- increment + 251 screen-y <- increment + 252 loop + 253 } + 254 return screen-y + 255 } + 256 + 257 fn render-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int { + 258 var target-screen/esi: (addr screen) <- copy _target-screen + 259 convert-graphemes-to-pixels target-screen # might overwrite existing pixel data with graphemes + 260 # overlapping the two is not supported + 261 # pixel data + 262 { + 263 # screen top left pixels x y width height + 264 var tmp/eax: int <- copy xmin + 265 tmp <- shift-left 3/log2-font-width + 266 var left: int + 267 copy-to left, tmp + 268 tmp <- copy ymin + 269 tmp <- shift-left 4/log2-font-height + 270 var top: int + 271 copy-to top, tmp + 272 var pixels-ah/eax: (addr handle array byte) <- get target-screen, pixels + 273 var _pixels/eax: (addr array byte) <- lookup *pixels-ah + 274 var pixels/edi: (addr array byte) <- copy _pixels + 275 compare pixels, 0 + 276 break-if-= + 277 var y/ebx: int <- copy 0 + 278 var height-addr/edx: (addr int) <- get target-screen, height + 279 var height/edx: int <- copy *height-addr + 280 height <- shift-left 4/log2-font-height + 281 { + 282 compare y, height + 283 break-if->= + 284 var width-addr/edx: (addr int) <- get target-screen, width + 285 var width/edx: int <- copy *width-addr + 286 width <- shift-left 3/log2-font-width + 287 var x/eax: int <- copy 0 + 288 { + 289 compare x, width + 290 break-if->= + 291 { + 292 var idx/ecx: int <- pixel-index target-screen, x, y + 293 var color-addr/ecx: (addr byte) <- index pixels, idx + 294 var color/ecx: byte <- copy-byte *color-addr + 295 var color2/ecx: int <- copy color + 296 var x2/eax: int <- copy x + 297 x2 <- add left + 298 var y2/ebx: int <- copy y + 299 y2 <- add top + 300 pixel screen, x2, y2, color2 + 301 } + 302 x <- increment + 303 loop + 304 } + 305 y <- increment + 306 loop + 307 } + 308 } + 309 } + 310 + 311 fn has-keyboard? _self: (addr sandbox) -> _/eax: boolean { + 312 var self/esi: (addr sandbox) <- copy _self + 313 var keyboard-obj-cell-ah/eax: (addr handle cell) <- get self, keyboard-var + 314 var keyboard-obj-cell/eax: (addr cell) <- lookup *keyboard-obj-cell-ah + 315 compare keyboard-obj-cell, 0 + 316 { + 317 break-if-!= + 318 return 0/false + 319 } + 320 var keyboard-obj-cell-type/ecx: (addr int) <- get keyboard-obj-cell, type + 321 compare *keyboard-obj-cell-type, 6/keyboard + 322 { + 323 break-if-= + 324 return 0/false + 325 } + 326 var keyboard-obj-ah/eax: (addr handle gap-buffer) <- get keyboard-obj-cell, keyboard-data + 327 var _keyboard-obj/eax: (addr gap-buffer) <- lookup *keyboard-obj-ah + 328 var keyboard-obj/edx: (addr gap-buffer) <- copy _keyboard-obj + 329 compare keyboard-obj, 0 + 330 { + 331 break-if-!= + 332 return 0/false + 333 } + 334 return 1/true + 335 } + 336 + 337 fn maybe-render-keyboard screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int { + 338 var self/esi: (addr sandbox) <- copy _self + 339 var keyboard-obj-cell-ah/eax: (addr handle cell) <- get self, keyboard-var + 340 var keyboard-obj-cell/eax: (addr cell) <- lookup *keyboard-obj-cell-ah + 341 compare keyboard-obj-cell, 0 342 { - 343 break-if-= - 344 return 0/false + 343 break-if-!= + 344 return ymin 345 } - 346 var keyboard-obj-ah/eax: (addr handle gap-buffer) <- get keyboard-obj-cell, keyboard-data - 347 var _keyboard-obj/eax: (addr gap-buffer) <- lookup *keyboard-obj-ah - 348 var keyboard-obj/edx: (addr gap-buffer) <- copy _keyboard-obj - 349 compare keyboard-obj, 0 - 350 { - 351 break-if-!= - 352 return 0/false - 353 } - 354 return 1/true - 355 } - 356 - 357 fn maybe-render-keyboard screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int { - 358 var self/esi: (addr sandbox) <- copy _self - 359 var keyboard-obj-cell-ah/eax: (addr handle cell) <- get self, keyboard-var - 360 var keyboard-obj-cell/eax: (addr cell) <- lookup *keyboard-obj-cell-ah - 361 compare keyboard-obj-cell, 0 - 362 { - 363 break-if-!= - 364 return ymin - 365 } - 366 var keyboard-obj-cell-type/ecx: (addr int) <- get keyboard-obj-cell, type - 367 compare *keyboard-obj-cell-type, 6/keyboard - 368 { - 369 break-if-= - 370 return ymin # silently give up on rendering the keyboard - 371 } - 372 var keyboard-obj-ah/eax: (addr handle gap-buffer) <- get keyboard-obj-cell, keyboard-data - 373 var _keyboard-obj/eax: (addr gap-buffer) <- lookup *keyboard-obj-ah - 374 var keyboard-obj/edx: (addr gap-buffer) <- copy _keyboard-obj - 375 var y/ecx: int <- copy ymin - 376 y <- increment # padding - 377 var x/eax: int <- draw-text-rightward screen, "keyboard: ", xmin, 0x99/xmax, y, 0x17/fg, 0xc5/bg=blue-bg - 378 var cursor-in-keyboard?/esi: (addr boolean) <- get self, cursor-in-keyboard? - 379 y <- render-keyboard screen, keyboard-obj, x, y, *cursor-in-keyboard? - 380 y <- increment # padding - 381 return y - 382 } - 383 - 384 fn render-keyboard screen: (addr screen), _keyboard: (addr gap-buffer), xmin: int, ymin: int, render-cursor?: boolean -> _/ecx: int { - 385 var keyboard/esi: (addr gap-buffer) <- copy _keyboard - 386 var width/edx: int <- copy 0x10/keyboard-capacity - 387 var y/edi: int <- copy ymin - 388 # keyboard - 389 var x/eax: int <- copy xmin - 390 var xmax/ecx: int <- copy x - 391 xmax <- add 0x10 - 392 var ymax/edx: int <- copy ymin - 393 ymax <- add 1 - 394 clear-rect screen, x, y, xmax, ymax, 0/bg - 395 x <- render-gap-buffer screen, keyboard, x, y, render-cursor?, 3/fg, 0/bg - 396 y <- increment - 397 return y - 398 } - 399 - 400 fn print-screen-cell-of-fake-screen screen: (addr screen), _target: (addr screen), x: int, y: int { - 401 var target/ecx: (addr screen) <- copy _target - 402 var data-ah/eax: (addr handle array screen-cell) <- get target, data - 403 var data/eax: (addr array screen-cell) <- lookup *data-ah - 404 var index/ecx: int <- screen-cell-index target, x, y - 405 var offset/ecx: (offset screen-cell) <- compute-offset data, index - 406 var src-cell/esi: (addr screen-cell) <- index data, offset - 407 var src-grapheme/eax: (addr grapheme) <- get src-cell, data - 408 var src-color/ecx: (addr int) <- get src-cell, color - 409 var src-background-color/edx: (addr int) <- get src-cell, background-color - 410 draw-grapheme-at-cursor screen, *src-grapheme, *src-color, *src-background-color - 411 } - 412 - 413 fn render-sandbox-edit-menu screen: (addr screen), _self: (addr sandbox) { - 414 var _width/eax: int <- copy 0 - 415 var height/ecx: int <- copy 0 - 416 _width, height <- screen-size screen - 417 var width/edx: int <- copy _width - 418 var y/ecx: int <- copy height - 419 y <- decrement - 420 var height/ebx: int <- copy y - 421 height <- increment - 422 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg - 423 set-cursor-position screen, 0/x, y - 424 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight - 425 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg - 426 draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight - 427 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0xc5/bg=blue-bg - 428 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight - 429 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg - 430 $render-sandbox-edit-menu:render-ctrl-m: { - 431 var self/eax: (addr sandbox) <- copy _self - 432 var has-trace?/eax: boolean <- has-trace? self - 433 compare has-trace?, 0/false - 434 { - 435 break-if-= - 436 draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 0x38/bg=trace - 437 draw-text-rightward-from-cursor screen, " to trace ", width, 7/fg, 0xc5/bg=blue-bg - 438 break $render-sandbox-edit-menu:render-ctrl-m - 439 } - 440 draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 3/bg=keyboard - 441 draw-text-rightward-from-cursor screen, " to keyboard ", width, 7/fg, 0xc5/bg=blue-bg - 442 } - 443 draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight - 444 draw-text-rightward-from-cursor screen, " << ", width, 7/fg, 0xc5/bg=blue-bg - 445 draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight - 446 draw-text-rightward-from-cursor screen, " <word ", width, 7/fg, 0xc5/bg=blue-bg - 447 draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight - 448 draw-text-rightward-from-cursor screen, " word> ", width, 7/fg, 0xc5/bg=blue-bg - 449 draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight - 450 draw-text-rightward-from-cursor screen, " >> ", width, 7/fg, 0xc5/bg=blue-bg + 346 var keyboard-obj-cell-type/ecx: (addr int) <- get keyboard-obj-cell, type + 347 compare *keyboard-obj-cell-type, 6/keyboard + 348 { + 349 break-if-= + 350 return ymin # silently give up on rendering the keyboard + 351 } + 352 var keyboard-obj-ah/eax: (addr handle gap-buffer) <- get keyboard-obj-cell, keyboard-data + 353 var _keyboard-obj/eax: (addr gap-buffer) <- lookup *keyboard-obj-ah + 354 var keyboard-obj/edx: (addr gap-buffer) <- copy _keyboard-obj + 355 var y/ecx: int <- copy ymin + 356 y <- increment # padding + 357 var x/eax: int <- draw-text-rightward screen, "keyboard: ", xmin, 0x99/xmax, y, 0x17/fg, 0xc5/bg=blue-bg + 358 var cursor-in-keyboard?/esi: (addr boolean) <- get self, cursor-in-keyboard? + 359 y <- render-keyboard screen, keyboard-obj, x, y, *cursor-in-keyboard? + 360 y <- increment # padding + 361 return y + 362 } + 363 + 364 fn render-keyboard screen: (addr screen), _keyboard: (addr gap-buffer), xmin: int, ymin: int, render-cursor?: boolean -> _/ecx: int { + 365 var keyboard/esi: (addr gap-buffer) <- copy _keyboard + 366 var width/edx: int <- copy 0x10/keyboard-capacity + 367 var y/edi: int <- copy ymin + 368 # keyboard + 369 var x/eax: int <- copy xmin + 370 var xmax/ecx: int <- copy x + 371 xmax <- add 0x10 + 372 var ymax/edx: int <- copy ymin + 373 ymax <- add 1 + 374 clear-rect screen, x, y, xmax, ymax, 0/bg + 375 x <- render-gap-buffer screen, keyboard, x, y, render-cursor?, 3/fg, 0/bg + 376 y <- increment + 377 return y + 378 } + 379 + 380 fn print-screen-cell-of-fake-screen screen: (addr screen), _target: (addr screen), x: int, y: int { + 381 var target/ecx: (addr screen) <- copy _target + 382 var data-ah/eax: (addr handle array screen-cell) <- get target, data + 383 var data/eax: (addr array screen-cell) <- lookup *data-ah + 384 var index/ecx: int <- screen-cell-index target, x, y + 385 var offset/ecx: (offset screen-cell) <- compute-offset data, index + 386 var src-cell/esi: (addr screen-cell) <- index data, offset + 387 var src-grapheme/eax: (addr grapheme) <- get src-cell, data + 388 var src-color/ecx: (addr int) <- get src-cell, color + 389 var src-background-color/edx: (addr int) <- get src-cell, background-color + 390 draw-grapheme-at-cursor screen, *src-grapheme, *src-color, *src-background-color + 391 } + 392 + 393 fn render-sandbox-edit-menu screen: (addr screen), _self: (addr sandbox) { + 394 var _width/eax: int <- copy 0 + 395 var height/ecx: int <- copy 0 + 396 _width, height <- screen-size screen + 397 var width/edx: int <- copy _width + 398 var y/ecx: int <- copy height + 399 y <- decrement + 400 var height/ebx: int <- copy y + 401 height <- increment + 402 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg + 403 set-cursor-position screen, 0/x, y + 404 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight + 405 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg + 406 draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight + 407 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0xc5/bg=blue-bg + 408 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight + 409 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg + 410 $render-sandbox-edit-menu:render-ctrl-m: { + 411 var self/eax: (addr sandbox) <- copy _self + 412 var has-trace?/eax: boolean <- has-trace? self + 413 compare has-trace?, 0/false + 414 { + 415 break-if-= + 416 draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 0x38/bg=trace + 417 draw-text-rightward-from-cursor screen, " to trace ", width, 7/fg, 0xc5/bg=blue-bg + 418 break $render-sandbox-edit-menu:render-ctrl-m + 419 } + 420 draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 3/bg=keyboard + 421 draw-text-rightward-from-cursor screen, " to keyboard ", width, 7/fg, 0xc5/bg=blue-bg + 422 } + 423 draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight + 424 draw-text-rightward-from-cursor screen, " << ", width, 7/fg, 0xc5/bg=blue-bg + 425 draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight + 426 draw-text-rightward-from-cursor screen, " <word ", width, 7/fg, 0xc5/bg=blue-bg + 427 draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight + 428 draw-text-rightward-from-cursor screen, " word> ", width, 7/fg, 0xc5/bg=blue-bg + 429 draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight + 430 draw-text-rightward-from-cursor screen, " >> ", width, 7/fg, 0xc5/bg=blue-bg + 431 } + 432 + 433 fn render-keyboard-menu screen: (addr screen) { + 434 var width/eax: int <- copy 0 + 435 var height/ecx: int <- copy 0 + 436 width, height <- screen-size screen + 437 var y/ecx: int <- copy height + 438 y <- decrement + 439 var height/edx: int <- copy y + 440 height <- increment + 441 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg + 442 set-cursor-position screen, 0/x, y + 443 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight + 444 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg + 445 draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight + 446 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0xc5/bg=blue-bg + 447 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight + 448 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg + 449 draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 7/bg + 450 draw-text-rightward-from-cursor screen, " to sandbox ", width, 7/fg, 0xc5/bg=blue-bg 451 } 452 - 453 fn render-keyboard-menu screen: (addr screen) { - 454 var width/eax: int <- copy 0 - 455 var height/ecx: int <- copy 0 - 456 width, height <- screen-size screen - 457 var y/ecx: int <- copy height - 458 y <- decrement - 459 var height/edx: int <- copy y - 460 height <- increment - 461 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg - 462 set-cursor-position screen, 0/x, y - 463 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight - 464 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg - 465 draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight - 466 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0xc5/bg=blue-bg - 467 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight - 468 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg - 469 draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 7/bg - 470 draw-text-rightward-from-cursor screen, " to sandbox ", width, 7/fg, 0xc5/bg=blue-bg - 471 } - 472 - 473 fn edit-sandbox _self: (addr sandbox), key: grapheme, globals: (addr global-table), data-disk: (addr disk), tweak-real-screen?: boolean { - 474 var self/esi: (addr sandbox) <- copy _self - 475 # ctrl-s - 476 { - 477 compare key, 0x13/ctrl-s - 478 break-if-!= - 479 # if cursor is in trace, skip - 480 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? - 481 compare *cursor-in-trace?, 0/false - 482 break-if-!= - 483 # minor gotcha here: any bindings created later in this iteration won't be - 484 # persisted until the next call to ctrl-s. - 485 store-state data-disk, self, globals - 486 # - 487 run-sandbox self, globals, tweak-real-screen? - 488 return - 489 } - 490 # ctrl-m - 491 { - 492 compare key, 0xd/ctrl-m - 493 break-if-!= - 494 # if cursor in data, switch to trace or fall through to keyboard - 495 { - 496 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? - 497 compare *cursor-in-data?, 0/false - 498 break-if-= - 499 var has-trace?/eax: boolean <- has-trace? self - 500 compare has-trace?, 0/false - 501 { - 502 break-if-= - 503 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? - 504 copy-to *cursor-in-data?, 0/false - 505 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? - 506 copy-to *cursor-in-trace?, 1/false - 507 return - 508 } - 509 var has-keyboard?/eax: boolean <- has-keyboard? self - 510 compare has-keyboard?, 0/false - 511 { - 512 break-if-= - 513 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? - 514 copy-to *cursor-in-data?, 0/false - 515 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard? - 516 copy-to *cursor-in-keyboard?, 1/false - 517 return - 518 } - 519 return - 520 } - 521 # if cursor in trace, switch to keyboard or fall through to data - 522 { - 523 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? - 524 compare *cursor-in-trace?, 0/false - 525 break-if-= - 526 copy-to *cursor-in-trace?, 0/false - 527 var cursor-target/ecx: (addr boolean) <- get self, cursor-in-keyboard? - 528 var has-keyboard?/eax: boolean <- has-keyboard? self - 529 compare has-keyboard?, 0/false - 530 { - 531 break-if-!= - 532 cursor-target <- get self, cursor-in-data? - 533 } - 534 copy-to *cursor-target, 1/true - 535 return - 536 } - 537 # otherwise if cursor in keyboard, switch to data - 538 { - 539 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard? - 540 compare *cursor-in-keyboard?, 0/false - 541 break-if-= - 542 copy-to *cursor-in-keyboard?, 0/false - 543 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? - 544 copy-to *cursor-in-data?, 1/true - 545 return - 546 } - 547 return - 548 } - 549 # if cursor in data, send key to data - 550 { - 551 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? - 552 compare *cursor-in-data?, 0/false - 553 break-if-= - 554 var data-ah/eax: (addr handle gap-buffer) <- get self, data - 555 var data/eax: (addr gap-buffer) <- lookup *data-ah - 556 edit-gap-buffer data, key - 557 return - 558 } - 559 # if cursor in keyboard, send key to keyboard - 560 { - 561 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard? - 562 compare *cursor-in-keyboard?, 0/false - 563 break-if-= - 564 var keyboard-cell-ah/eax: (addr handle cell) <- get self, keyboard-var - 565 var keyboard-cell/eax: (addr cell) <- lookup *keyboard-cell-ah - 566 compare keyboard-cell, 0 - 567 { - 568 break-if-!= - 569 return - 570 } - 571 var keyboard-cell-type/ecx: (addr int) <- get keyboard-cell, type - 572 compare *keyboard-cell-type, 6/keyboard - 573 { - 574 break-if-= - 575 return - 576 } - 577 var keyboard-ah/eax: (addr handle gap-buffer) <- get keyboard-cell, keyboard-data - 578 var keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah - 579 edit-gap-buffer keyboard, key - 580 return - 581 } - 582 # if cursor in trace, send key to trace - 583 { - 584 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? - 585 compare *cursor-in-trace?, 0/false - 586 break-if-= - 587 var trace-ah/eax: (addr handle trace) <- get self, trace - 588 var trace/eax: (addr trace) <- lookup *trace-ah - 589 # if expanding the trace, first check if we need to run the sandbox again with a deeper trace - 590 { - 591 compare key, 0xa/newline - 592 break-if-!= - 593 { - 594 var need-rerun?/eax: boolean <- cursor-too-deep? trace - 595 compare need-rerun?, 0/false - 596 } - 597 break-if-= - 598 #? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "rerun", 7/fg 0/bg - 599 # save trace lines at various cached indices - 600 var save: trace-index-stash - 601 var save-addr/ecx: (addr trace-index-stash) <- address save - 602 save-indices trace, save-addr - 603 # rerun at higher depth - 604 var max-depth-addr/ecx: (addr int) <- get trace, max-depth - 605 increment *max-depth-addr - 606 run-sandbox self, globals, tweak-real-screen? - 607 # recompute cached indices - 608 recompute-all-visible-lines trace - 609 var save-addr/ecx: (addr trace-index-stash) <- address save - 610 restore-indices trace, save-addr - 611 } - 612 edit-trace trace, key - 613 return - 614 } - 615 } - 616 - 617 # hack: tweak-real-screen guards things there are no tests for - 618 fn run-sandbox _self: (addr sandbox), globals: (addr global-table), tweak-real-screen?: boolean { - 619 var self/esi: (addr sandbox) <- copy _self - 620 var data-ah/ecx: (addr handle gap-buffer) <- get self, data - 621 var value-ah/eax: (addr handle stream byte) <- get self, value - 622 var _value/eax: (addr stream byte) <- lookup *value-ah - 623 var value/edx: (addr stream byte) <- copy _value - 624 var trace-ah/eax: (addr handle trace) <- get self, trace - 625 var _trace/eax: (addr trace) <- lookup *trace-ah - 626 var trace/ebx: (addr trace) <- copy _trace - 627 clear-trace trace - 628 { - 629 compare tweak-real-screen?, 0/false - 630 break-if-= - 631 clear-sandbox-output 0/screen, self, 0x56/sandbox-left-margin, 1/y, 0x80/screen-width, 0x2f/screen-height-without-menu - 632 } - 633 var screen-cell/eax: (addr handle cell) <- get self, screen-var - 634 clear-screen-cell screen-cell - 635 var keyboard-cell/esi: (addr handle cell) <- get self, keyboard-var - 636 rewind-keyboard-cell keyboard-cell # don't clear keys from before - 637 { - 638 compare tweak-real-screen?, 0/false - 639 break-if-= - 640 set-cursor-position 0/screen, 0/x, 0/y # for any debug prints during evaluation - 641 } - 642 run data-ah, value, globals, trace, screen-cell, keyboard-cell - 643 } - 644 - 645 fn run _in-ah: (addr handle gap-buffer), out: (addr stream byte), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) { - 646 var in-ah/eax: (addr handle gap-buffer) <- copy _in-ah - 647 var in/eax: (addr gap-buffer) <- lookup *in-ah - 648 var read-result-h: (handle cell) - 649 var read-result-ah/esi: (addr handle cell) <- address read-result-h - 650 read-cell in, read-result-ah, trace - 651 var error?/eax: boolean <- has-errors? trace - 652 { - 653 compare error?, 0/false - 654 break-if-= - 655 return - 656 } - 657 macroexpand read-result-ah, globals, trace - 658 var error?/eax: boolean <- has-errors? trace - 659 { - 660 compare error?, 0/false - 661 break-if-= - 662 return - 663 } - 664 var nil-h: (handle cell) - 665 var nil-ah/eax: (addr handle cell) <- address nil-h - 666 allocate-pair nil-ah - 667 var eval-result-h: (handle cell) - 668 var eval-result-ah/edi: (addr handle cell) <- address eval-result-h - 669 #? set-cursor-position 0/screen, 0 0 - 670 #? turn-on-debug-print - 671 debug-print "^", 4/fg, 0/bg - 672 evaluate read-result-ah, eval-result-ah, *nil-ah, globals, trace, screen-cell, keyboard-cell, 1/call-number - 673 debug-print "$", 4/fg, 0/bg - 674 var error?/eax: boolean <- has-errors? trace - 675 { - 676 compare error?, 0/false - 677 break-if-= - 678 return - 679 } - 680 # if there was no error and the read-result starts with "set" or "def", save - 681 # the gap buffer in the modified global, then create a new one for the next - 682 # command. - 683 maybe-stash-gap-buffer-to-global globals, read-result-ah, _in-ah - 684 clear-stream out - 685 print-cell eval-result-ah, out, trace - 686 mark-lines-dirty trace - 687 } - 688 - 689 fn read-evaluate-and-move-to-globals _in-ah: (addr handle gap-buffer), globals: (addr global-table), definition-name: (addr stream byte) { - 690 var in-ah/eax: (addr handle gap-buffer) <- copy _in-ah - 691 var in/eax: (addr gap-buffer) <- lookup *in-ah - 692 var read-result-h: (handle cell) - 693 var read-result-ah/esi: (addr handle cell) <- address read-result-h - 694 var trace-storage: trace - 695 var trace/edx: (addr trace) <- address trace-storage - 696 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible - 697 read-cell in, read-result-ah, trace - 698 macroexpand read-result-ah, globals, trace - 699 var nil-storage: (handle cell) - 700 var nil-ah/eax: (addr handle cell) <- address nil-storage - 701 allocate-pair nil-ah - 702 var eval-result-storage: (handle cell) - 703 var eval-result/edi: (addr handle cell) <- address eval-result-storage - 704 debug-print "^", 4/fg, 0/bg - 705 evaluate read-result-ah, eval-result, *nil-ah, globals, trace, 0/no-screen-cell, 0/no-keyboard-cell, 1/call-number - 706 { - 707 var error?/eax: boolean <- has-errors? trace - 708 compare error?, 0/false - 709 break-if-= - 710 set-cursor-position 0/screen, 0x40/x, 0x18/y - 711 draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "error when loading definition for ", 4/fg 0/bg - 712 rewind-stream definition-name - 713 draw-stream-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, definition-name, 3/fg 0/bg - 714 set-cursor-position 0/screen, 0x40/x, 0x19/y - 715 draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "see trace in grey at top-left", 7/fg 0/bg - 716 dump-trace trace # will print from 0, 0 - 717 { - 718 loop - 719 } - 720 } - 721 debug-print "$", 4/fg, 0/bg - 722 move-gap-buffer-to-global globals, read-result-ah, _in-ah - 723 } - 724 - 725 fn test-run-integer { - 726 var sandbox-storage: sandbox - 727 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 728 initialize-sandbox-with sandbox, "1" - 729 # eval - 730 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 731 # setup: screen - 732 var screen-on-stack: screen - 733 var screen/edi: (addr screen) <- address screen-on-stack - 734 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 735 # - 736 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 737 # skip one line of padding - 738 check-screen-row screen, 1/y, " 1 ", "F - test-run-integer/0" - 739 check-screen-row screen, 2/y, " ... ", "F - test-run-integer/1" - 740 check-screen-row screen, 3/y, " => 1 ", "F - test-run-integer/2" - 741 } - 742 - 743 fn test-run-error-invalid-integer { - 744 var sandbox-storage: sandbox - 745 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 746 initialize-sandbox-with sandbox, "1a" - 747 # eval - 748 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 749 # setup: screen - 750 var screen-on-stack: screen - 751 var screen/edi: (addr screen) <- address screen-on-stack - 752 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 753 # - 754 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 755 # skip one line of padding - 756 check-screen-row screen, 1/y, " 1a ", "F - test-run-error-invalid-integer/0" - 757 check-screen-row screen, 2/y, " ... ", "F - test-run-error-invalid-integer/1" - 758 check-screen-row-in-color screen, 0xc/fg=error, 3/y, " invalid number ", "F - test-run-error-invalid-integer/2" - 759 } - 760 - 761 fn test-run-error-unknown-symbol { - 762 var sandbox-storage: sandbox - 763 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 764 initialize-sandbox-with sandbox, "a" - 765 # eval - 766 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 767 # setup: screen - 768 var screen-on-stack: screen - 769 var screen/edi: (addr screen) <- address screen-on-stack - 770 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 771 # - 772 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 773 # skip one line of padding - 774 check-screen-row screen, 1/y, " a ", "F - test-run-error-unknown-symbol/0" - 775 check-screen-row screen, 2/y, " ... ", "F - test-run-error-unknown-symbol/1" - 776 check-screen-row-in-color screen, 0xc/fg=error, 3/y, " unbound symbol: a ", "F - test-run-error-unknown-symbol/2" - 777 } - 778 - 779 fn test-run-with-spaces { - 780 var sandbox-storage: sandbox - 781 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 782 initialize-sandbox-with sandbox, " 1 \n" - 783 # eval - 784 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 785 # setup: screen - 786 var screen-on-stack: screen - 787 var screen/edi: (addr screen) <- address screen-on-stack - 788 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 789 # - 790 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 791 # skip one line of padding - 792 check-screen-row screen, 1/y, " 1 ", "F - test-run-with-spaces/0" - 793 check-screen-row screen, 2/y, " ", "F - test-run-with-spaces/1" - 794 check-screen-row screen, 3/y, " ... ", "F - test-run-with-spaces/2" - 795 check-screen-row screen, 4/y, " => 1 ", "F - test-run-with-spaces/3" - 796 } - 797 - 798 fn test-run-quote { - 799 var sandbox-storage: sandbox - 800 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 801 initialize-sandbox-with sandbox, "'a" - 802 # eval - 803 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 804 # setup: screen - 805 var screen-on-stack: screen - 806 var screen/edi: (addr screen) <- address screen-on-stack - 807 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 808 # - 809 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 810 # skip one line of padding - 811 check-screen-row screen, 1/y, " 'a ", "F - test-run-quote/0" - 812 check-screen-row screen, 2/y, " ... ", "F - test-run-quote/1" - 813 check-screen-row screen, 3/y, " => a ", "F - test-run-quote/2" - 814 } - 815 - 816 fn test-run-dotted-list { - 817 var sandbox-storage: sandbox - 818 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 819 initialize-sandbox-with sandbox, "'(a . b)" - 820 # eval - 821 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 822 # setup: screen - 823 var screen-on-stack: screen - 824 var screen/edi: (addr screen) <- address screen-on-stack - 825 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 826 # - 827 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 828 # skip one line of padding - 829 check-screen-row screen, 1/y, " '(a . b) ", "F - test-run-dotted-list/0" - 830 check-screen-row screen, 2/y, " ... ", "F - test-run-dotted-list/1" - 831 check-screen-row screen, 3/y, " => (a . b) ", "F - test-run-dotted-list/2" - 832 } - 833 - 834 fn test-run-dot-and-list { - 835 var sandbox-storage: sandbox - 836 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 837 initialize-sandbox-with sandbox, "'(a . (b))" - 838 # eval - 839 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 840 # setup: screen - 841 var screen-on-stack: screen - 842 var screen/edi: (addr screen) <- address screen-on-stack - 843 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 844 # - 845 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 846 # skip one line of padding - 847 check-screen-row screen, 1/y, " '(a . (b)) ", "F - test-run-dot-and-list/0" - 848 check-screen-row screen, 2/y, " ... ", "F - test-run-dot-and-list/1" - 849 check-screen-row screen, 3/y, " => (a b) ", "F - test-run-dot-and-list/2" - 850 } - 851 - 852 fn test-run-final-dot { - 853 var sandbox-storage: sandbox - 854 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 855 initialize-sandbox-with sandbox, "'(a .)" - 856 # eval - 857 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 858 # setup: screen - 859 var screen-on-stack: screen - 860 var screen/edi: (addr screen) <- address screen-on-stack - 861 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 862 # - 863 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 864 # skip one line of padding - 865 check-screen-row screen, 1/y, " '(a .) ", "F - test-run-final-dot/0" - 866 check-screen-row screen, 2/y, " ... ", "F - test-run-final-dot/1" - 867 check-screen-row screen, 3/y, " '. )' makes no sense ", "F - test-run-final-dot/2" - 868 # further errors may occur - 869 } - 870 - 871 fn test-run-double-dot { - 872 var sandbox-storage: sandbox - 873 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 874 initialize-sandbox-with sandbox, "'(a . .)" - 875 # eval - 876 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 877 # setup: screen - 878 var screen-on-stack: screen - 879 var screen/edi: (addr screen) <- address screen-on-stack - 880 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 881 # - 882 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 883 # skip one line of padding - 884 check-screen-row screen, 1/y, " '(a . .) ", "F - test-run-double-dot/0" - 885 check-screen-row screen, 2/y, " ... ", "F - test-run-double-dot/1" - 886 check-screen-row screen, 3/y, " '. .' makes no sense ", "F - test-run-double-dot/2" - 887 # further errors may occur - 888 } - 889 - 890 fn test-run-multiple-expressions-after-dot { - 891 var sandbox-storage: sandbox - 892 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 893 initialize-sandbox-with sandbox, "'(a . b c)" - 894 # eval - 895 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 896 # setup: screen - 897 var screen-on-stack: screen - 898 var screen/edi: (addr screen) <- address screen-on-stack - 899 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 900 # - 901 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 902 # skip one line of padding - 903 check-screen-row screen, 1/y, " '(a . b c) ", "F - test-run-multiple-expressions-after-dot/0" - 904 check-screen-row screen, 2/y, " ... ", "F - test-run-multiple-expressions-after-dot/1" - 905 check-screen-row screen, 3/y, " cannot have multiple expressions between '.' and ')' ", "F - test-run-multiple-expressions-after-dot/2" - 906 # further errors may occur - 907 } - 908 - 909 fn test-run-stream { - 910 var sandbox-storage: sandbox - 911 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 912 initialize-sandbox-with sandbox, "[a b]" - 913 # eval - 914 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 915 # setup: screen - 916 var screen-on-stack: screen - 917 var screen/edi: (addr screen) <- address screen-on-stack - 918 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 919 # - 920 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 921 # skip one line of padding - 922 check-screen-row screen, 1/y, " [a b] ", "F - test-run-stream/0" - 923 check-screen-row screen, 2/y, " ... ", "F - test-run-stream/1" - 924 check-screen-row screen, 3/y, " => [a b] ", "F - test-run-stream/2" - 925 } - 926 - 927 fn test-run-move-cursor-into-trace { - 928 var sandbox-storage: sandbox - 929 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 930 initialize-sandbox-with sandbox, "12" - 931 # eval - 932 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 933 # setup: screen - 934 var screen-on-stack: screen - 935 var screen/edi: (addr screen) <- address screen-on-stack - 936 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics - 937 # - 938 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 939 # skip one line of padding - 940 check-screen-row screen, 1/y, " 12 ", "F - test-run-move-cursor-into-trace/pre-0" - 941 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-move-cursor-into-trace/pre-0/cursor" - 942 check-screen-row screen, 2/y, " ... ", "F - test-run-move-cursor-into-trace/pre-1" - 943 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/pre-1/cursor" - 944 check-screen-row screen, 3/y, " => 12 ", "F - test-run-move-cursor-into-trace/pre-2" - 945 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-move-cursor-into-trace/pre-2/cursor" - 946 # move cursor into trace - 947 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 948 # - 949 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 950 # skip one line of padding - 951 check-screen-row screen, 1/y, " 12 ", "F - test-run-move-cursor-into-trace/trace-0" - 952 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-move-cursor-into-trace/trace-0/cursor" - 953 check-screen-row screen, 2/y, " ... ", "F - test-run-move-cursor-into-trace/trace-1" - 954 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||| ", "F - test-run-move-cursor-into-trace/trace-1/cursor" - 955 check-screen-row screen, 3/y, " => 12 ", "F - test-run-move-cursor-into-trace/trace-2" - 956 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-move-cursor-into-trace/trace-2/cursor" - 957 # move cursor into input - 958 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 959 # - 960 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor - 961 # skip one line of padding - 962 check-screen-row screen, 1/y, " 12 ", "F - test-run-move-cursor-into-trace/input-0" - 963 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-move-cursor-into-trace/input-0/cursor" - 964 check-screen-row screen, 2/y, " ... ", "F - test-run-move-cursor-into-trace/input-1" - 965 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/input-1/cursor" - 966 check-screen-row screen, 3/y, " => 12 ", "F - test-run-move-cursor-into-trace/input-2" - 967 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-move-cursor-into-trace/input-2/cursor" - 968 } - 969 - 970 fn has-trace? _self: (addr sandbox) -> _/eax: boolean { - 971 var self/esi: (addr sandbox) <- copy _self - 972 var trace-ah/eax: (addr handle trace) <- get self, trace - 973 var _trace/eax: (addr trace) <- lookup *trace-ah - 974 var trace/edx: (addr trace) <- copy _trace - 975 compare trace, 0 - 976 { - 977 break-if-!= - 978 abort "null trace" - 979 } - 980 var first-free/ebx: (addr int) <- get trace, first-free - 981 compare *first-free, 0 - 982 { - 983 break-if-> - 984 return 0/false - 985 } - 986 return 1/true - 987 } - 988 - 989 fn test-run-expand-trace { - 990 var sandbox-storage: sandbox - 991 var sandbox/esi: (addr sandbox) <- address sandbox-storage - 992 initialize-sandbox-with sandbox, "12" - 993 # eval - 994 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen - 995 # setup: screen - 996 var screen-on-stack: screen - 997 var screen/edi: (addr screen) <- address screen-on-stack - 998 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 453 fn edit-sandbox _self: (addr sandbox), key: grapheme, globals: (addr global-table), data-disk: (addr disk) { + 454 var self/esi: (addr sandbox) <- copy _self + 455 # ctrl-s + 456 { + 457 compare key, 0x13/ctrl-s + 458 break-if-!= + 459 # if cursor is in trace, skip + 460 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? + 461 compare *cursor-in-trace?, 0/false + 462 break-if-!= + 463 # minor gotcha here: any bindings created later in this iteration won't be + 464 # persisted until the next call to ctrl-s. + 465 store-state data-disk, self, globals + 466 # + 467 run-sandbox self, globals + 468 return + 469 } + 470 # ctrl-m + 471 { + 472 compare key, 0xd/ctrl-m + 473 break-if-!= + 474 # if cursor in data, switch to trace or fall through to keyboard + 475 { + 476 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? + 477 compare *cursor-in-data?, 0/false + 478 break-if-= + 479 var has-trace?/eax: boolean <- has-trace? self + 480 compare has-trace?, 0/false + 481 { + 482 break-if-= + 483 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? + 484 copy-to *cursor-in-data?, 0/false + 485 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? + 486 copy-to *cursor-in-trace?, 1/false + 487 return + 488 } + 489 var has-keyboard?/eax: boolean <- has-keyboard? self + 490 compare has-keyboard?, 0/false + 491 { + 492 break-if-= + 493 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? + 494 copy-to *cursor-in-data?, 0/false + 495 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard? + 496 copy-to *cursor-in-keyboard?, 1/false + 497 return + 498 } + 499 return + 500 } + 501 # if cursor in trace, switch to keyboard or fall through to data + 502 { + 503 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? + 504 compare *cursor-in-trace?, 0/false + 505 break-if-= + 506 copy-to *cursor-in-trace?, 0/false + 507 var cursor-target/ecx: (addr boolean) <- get self, cursor-in-keyboard? + 508 var has-keyboard?/eax: boolean <- has-keyboard? self + 509 compare has-keyboard?, 0/false + 510 { + 511 break-if-!= + 512 cursor-target <- get self, cursor-in-data? + 513 } + 514 copy-to *cursor-target, 1/true + 515 return + 516 } + 517 # otherwise if cursor in keyboard, switch to data + 518 { + 519 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard? + 520 compare *cursor-in-keyboard?, 0/false + 521 break-if-= + 522 copy-to *cursor-in-keyboard?, 0/false + 523 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? + 524 copy-to *cursor-in-data?, 1/true + 525 return + 526 } + 527 return + 528 } + 529 # if cursor in data, send key to data + 530 { + 531 var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? + 532 compare *cursor-in-data?, 0/false + 533 break-if-= + 534 var data-ah/eax: (addr handle gap-buffer) <- get self, data + 535 var data/eax: (addr gap-buffer) <- lookup *data-ah + 536 edit-gap-buffer data, key + 537 return + 538 } + 539 # if cursor in keyboard, send key to keyboard + 540 { + 541 var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard? + 542 compare *cursor-in-keyboard?, 0/false + 543 break-if-= + 544 var inner-keyboard-var-ah/eax: (addr handle cell) <- get self, keyboard-var + 545 var inner-keyboard-var/eax: (addr cell) <- lookup *inner-keyboard-var-ah + 546 compare inner-keyboard-var, 0 + 547 { + 548 break-if-!= + 549 return + 550 } + 551 var inner-keyboard-var-type/ecx: (addr int) <- get inner-keyboard-var, type + 552 compare *inner-keyboard-var-type, 6/keyboard + 553 { + 554 break-if-= + 555 return + 556 } + 557 var keyboard-ah/eax: (addr handle gap-buffer) <- get inner-keyboard-var, keyboard-data + 558 var keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah + 559 edit-gap-buffer keyboard, key + 560 return + 561 } + 562 # if cursor in trace, send key to trace + 563 { + 564 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? + 565 compare *cursor-in-trace?, 0/false + 566 break-if-= + 567 var trace-ah/eax: (addr handle trace) <- get self, trace + 568 var trace/eax: (addr trace) <- lookup *trace-ah + 569 # if expanding the trace, first check if we need to run the sandbox again with a deeper trace + 570 { + 571 compare key, 0xa/newline + 572 break-if-!= + 573 { + 574 var need-rerun?/eax: boolean <- cursor-too-deep? trace + 575 compare need-rerun?, 0/false + 576 } + 577 break-if-= + 578 #? draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "rerun", 7/fg 0/bg + 579 # save trace lines at various cached indices + 580 var save: trace-index-stash + 581 var save-addr/ecx: (addr trace-index-stash) <- address save + 582 save-indices trace, save-addr + 583 # rerun at higher depth + 584 var max-depth-addr/ecx: (addr int) <- get trace, max-depth + 585 increment *max-depth-addr + 586 run-sandbox self, globals + 587 # recompute cached indices + 588 recompute-all-visible-lines trace + 589 var save-addr/ecx: (addr trace-index-stash) <- address save + 590 restore-indices trace, save-addr + 591 } + 592 edit-trace trace, key + 593 return + 594 } + 595 } + 596 + 597 fn run-sandbox _self: (addr sandbox), globals: (addr global-table) { + 598 var self/esi: (addr sandbox) <- copy _self + 599 var data-ah/ecx: (addr handle gap-buffer) <- get self, data + 600 var eval-result-h: (handle cell) + 601 var eval-result-ah/edi: (addr handle cell) <- address eval-result-h + 602 var definitions-created-storage: (stream int 0x10) + 603 var definitions-created/edx: (addr stream int) <- address definitions-created-storage + 604 var trace-ah/eax: (addr handle trace) <- get self, trace + 605 var _trace/eax: (addr trace) <- lookup *trace-ah + 606 var trace/ebx: (addr trace) <- copy _trace + 607 clear-trace trace + 608 var tmp/eax: (addr handle cell) <- get self, screen-var + 609 var inner-screen-var: (addr handle cell) + 610 copy-to inner-screen-var, tmp + 611 clear-screen-var inner-screen-var + 612 var inner-keyboard-var/eax: (addr handle cell) <- get self, keyboard-var + 613 rewind-keyboard-var inner-keyboard-var # don't clear keys from before + 614 # + 615 read-and-evaluate-and-save-gap-buffer-to-globals data-ah, eval-result-ah, globals, definitions-created, trace, inner-screen-var, inner-keyboard-var + 616 # if necessary, initialize a new gap-buffer for sandbox + 617 { + 618 compare globals, 0 + 619 break-if-= + 620 rewind-stream definitions-created + 621 var no-definitions?/eax: boolean <- stream-empty? definitions-created + 622 compare no-definitions?, 0/false + 623 break-if-!= + 624 # some definitions were created; clear the gap buffer + 625 var data/eax: (addr gap-buffer) <- lookup *data-ah + 626 var capacity/edx: int <- gap-buffer-capacity data + 627 allocate data-ah + 628 var new-data/eax: (addr gap-buffer) <- lookup *data-ah + 629 initialize-gap-buffer new-data, capacity + 630 } + 631 # print + 632 var value-ah/eax: (addr handle stream byte) <- get self, value + 633 var value/eax: (addr stream byte) <- lookup *value-ah + 634 clear-stream value + 635 print-cell eval-result-ah, value, trace + 636 } + 637 + 638 fn test-run-integer { + 639 var sandbox-storage: sandbox + 640 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 641 initialize-sandbox-with sandbox, "1" + 642 # eval + 643 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 644 # setup: screen + 645 var screen-on-stack: screen + 646 var screen/edi: (addr screen) <- address screen-on-stack + 647 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 648 # + 649 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 650 # skip one line of padding + 651 check-screen-row screen, 1/y, " 1 ", "F - test-run-integer/0" + 652 check-screen-row screen, 2/y, " ... ", "F - test-run-integer/1" + 653 check-screen-row screen, 3/y, " => 1 ", "F - test-run-integer/2" + 654 } + 655 + 656 fn test-run-negative-integer { + 657 var sandbox-storage: sandbox + 658 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 659 initialize-sandbox-with sandbox, "-1" + 660 # eval + 661 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 662 # setup: screen + 663 var screen-on-stack: screen + 664 var screen/edi: (addr screen) <- address screen-on-stack + 665 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 666 # + 667 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 668 # skip one line of padding + 669 check-screen-row screen, 1/y, " -1 ", "F - test-run-negative-integer/0" + 670 check-screen-row screen, 2/y, " ... ", "F - test-run-negative-integer/1" + 671 check-screen-row screen, 3/y, " => -1 ", "F - test-run-negative-integer/2" + 672 } + 673 + 674 fn test-run-error-invalid-integer { + 675 var sandbox-storage: sandbox + 676 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 677 initialize-sandbox-with sandbox, "1a" + 678 # eval + 679 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 680 # setup: screen + 681 var screen-on-stack: screen + 682 var screen/edi: (addr screen) <- address screen-on-stack + 683 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 684 # + 685 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 686 # skip one line of padding + 687 check-screen-row screen, 1/y, " 1a ", "F - test-run-error-invalid-integer/0" + 688 check-screen-row screen, 2/y, " ... ", "F - test-run-error-invalid-integer/1" + 689 check-screen-row-in-color screen, 0xc/fg=error, 3/y, " invalid number ", "F - test-run-error-invalid-integer/2" + 690 } + 691 + 692 fn test-run-error-unknown-symbol { + 693 var sandbox-storage: sandbox + 694 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 695 initialize-sandbox-with sandbox, "a" + 696 # eval + 697 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 698 # setup: screen + 699 var screen-on-stack: screen + 700 var screen/edi: (addr screen) <- address screen-on-stack + 701 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 702 # + 703 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 704 # skip one line of padding + 705 check-screen-row screen, 1/y, " a ", "F - test-run-error-unknown-symbol/0" + 706 check-screen-row screen, 2/y, " ... ", "F - test-run-error-unknown-symbol/1" + 707 check-screen-row-in-color screen, 0xc/fg=error, 3/y, " unbound symbol: a ", "F - test-run-error-unknown-symbol/2" + 708 } + 709 + 710 fn test-run-with-spaces { + 711 var sandbox-storage: sandbox + 712 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 713 initialize-sandbox-with sandbox, " 1 \n" + 714 # eval + 715 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 716 # setup: screen + 717 var screen-on-stack: screen + 718 var screen/edi: (addr screen) <- address screen-on-stack + 719 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 720 # + 721 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 722 # skip one line of padding + 723 check-screen-row screen, 1/y, " 1 ", "F - test-run-with-spaces/0" + 724 check-screen-row screen, 2/y, " ", "F - test-run-with-spaces/1" + 725 check-screen-row screen, 3/y, " ... ", "F - test-run-with-spaces/2" + 726 check-screen-row screen, 4/y, " => 1 ", "F - test-run-with-spaces/3" + 727 } + 728 + 729 fn test-run-quote { + 730 var sandbox-storage: sandbox + 731 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 732 initialize-sandbox-with sandbox, "'a" + 733 # eval + 734 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 735 # setup: screen + 736 var screen-on-stack: screen + 737 var screen/edi: (addr screen) <- address screen-on-stack + 738 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 739 # + 740 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 741 # skip one line of padding + 742 check-screen-row screen, 1/y, " 'a ", "F - test-run-quote/0" + 743 check-screen-row screen, 2/y, " ... ", "F - test-run-quote/1" + 744 check-screen-row screen, 3/y, " => a ", "F - test-run-quote/2" + 745 } + 746 + 747 fn test-run-dotted-list { + 748 var sandbox-storage: sandbox + 749 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 750 initialize-sandbox-with sandbox, "'(a . b)" + 751 # eval + 752 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 753 # setup: screen + 754 var screen-on-stack: screen + 755 var screen/edi: (addr screen) <- address screen-on-stack + 756 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 757 # + 758 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 759 # skip one line of padding + 760 check-screen-row screen, 1/y, " '(a . b) ", "F - test-run-dotted-list/0" + 761 check-screen-row screen, 2/y, " ... ", "F - test-run-dotted-list/1" + 762 check-screen-row screen, 3/y, " => (a . b) ", "F - test-run-dotted-list/2" + 763 } + 764 + 765 fn test-run-dot-and-list { + 766 var sandbox-storage: sandbox + 767 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 768 initialize-sandbox-with sandbox, "'(a . (b))" + 769 # eval + 770 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 771 # setup: screen + 772 var screen-on-stack: screen + 773 var screen/edi: (addr screen) <- address screen-on-stack + 774 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 775 # + 776 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 777 # skip one line of padding + 778 check-screen-row screen, 1/y, " '(a . (b)) ", "F - test-run-dot-and-list/0" + 779 check-screen-row screen, 2/y, " ... ", "F - test-run-dot-and-list/1" + 780 check-screen-row screen, 3/y, " => (a b) ", "F - test-run-dot-and-list/2" + 781 } + 782 + 783 fn test-run-final-dot { + 784 var sandbox-storage: sandbox + 785 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 786 initialize-sandbox-with sandbox, "'(a .)" + 787 # eval + 788 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 789 # setup: screen + 790 var screen-on-stack: screen + 791 var screen/edi: (addr screen) <- address screen-on-stack + 792 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 793 # + 794 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 795 # skip one line of padding + 796 check-screen-row screen, 1/y, " '(a .) ", "F - test-run-final-dot/0" + 797 check-screen-row screen, 2/y, " ... ", "F - test-run-final-dot/1" + 798 check-screen-row screen, 3/y, " '. )' makes no sense ", "F - test-run-final-dot/2" + 799 # further errors may occur + 800 } + 801 + 802 fn test-run-double-dot { + 803 var sandbox-storage: sandbox + 804 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 805 initialize-sandbox-with sandbox, "'(a . .)" + 806 # eval + 807 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 808 # setup: screen + 809 var screen-on-stack: screen + 810 var screen/edi: (addr screen) <- address screen-on-stack + 811 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 812 # + 813 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 814 # skip one line of padding + 815 check-screen-row screen, 1/y, " '(a . .) ", "F - test-run-double-dot/0" + 816 check-screen-row screen, 2/y, " ... ", "F - test-run-double-dot/1" + 817 check-screen-row screen, 3/y, " '. .' makes no sense ", "F - test-run-double-dot/2" + 818 # further errors may occur + 819 } + 820 + 821 fn test-run-multiple-expressions-after-dot { + 822 var sandbox-storage: sandbox + 823 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 824 initialize-sandbox-with sandbox, "'(a . b c)" + 825 # eval + 826 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 827 # setup: screen + 828 var screen-on-stack: screen + 829 var screen/edi: (addr screen) <- address screen-on-stack + 830 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 831 # + 832 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 833 # skip one line of padding + 834 check-screen-row screen, 1/y, " '(a . b c) ", "F - test-run-multiple-expressions-after-dot/0" + 835 check-screen-row screen, 2/y, " ... ", "F - test-run-multiple-expressions-after-dot/1" + 836 check-screen-row screen, 3/y, " cannot have multiple expressions between '.' and ')' ", "F - test-run-multiple-expressions-after-dot/2" + 837 # further errors may occur + 838 } + 839 + 840 fn test-run-stream { + 841 var sandbox-storage: sandbox + 842 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 843 initialize-sandbox-with sandbox, "[a b]" + 844 # eval + 845 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 846 # setup: screen + 847 var screen-on-stack: screen + 848 var screen/edi: (addr screen) <- address screen-on-stack + 849 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 850 # + 851 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 852 # skip one line of padding + 853 check-screen-row screen, 1/y, " [a b] ", "F - test-run-stream/0" + 854 check-screen-row screen, 2/y, " ... ", "F - test-run-stream/1" + 855 check-screen-row screen, 3/y, " => [a b] ", "F - test-run-stream/2" + 856 } + 857 + 858 fn test-run-move-cursor-into-trace { + 859 var sandbox-storage: sandbox + 860 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 861 initialize-sandbox-with sandbox, "12" + 862 # eval + 863 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 864 # setup: screen + 865 var screen-on-stack: screen + 866 var screen/edi: (addr screen) <- address screen-on-stack + 867 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 868 # + 869 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 870 # skip one line of padding + 871 check-screen-row screen, 1/y, " 12 ", "F - test-run-move-cursor-into-trace/pre-0" + 872 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-move-cursor-into-trace/pre-0/cursor" + 873 check-screen-row screen, 2/y, " ... ", "F - test-run-move-cursor-into-trace/pre-1" + 874 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/pre-1/cursor" + 875 check-screen-row screen, 3/y, " => 12 ", "F - test-run-move-cursor-into-trace/pre-2" + 876 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-move-cursor-into-trace/pre-2/cursor" + 877 # move cursor into trace + 878 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk + 879 # + 880 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 881 # skip one line of padding + 882 check-screen-row screen, 1/y, " 12 ", "F - test-run-move-cursor-into-trace/trace-0" + 883 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-move-cursor-into-trace/trace-0/cursor" + 884 check-screen-row screen, 2/y, " ... ", "F - test-run-move-cursor-into-trace/trace-1" + 885 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||| ", "F - test-run-move-cursor-into-trace/trace-1/cursor" + 886 check-screen-row screen, 3/y, " => 12 ", "F - test-run-move-cursor-into-trace/trace-2" + 887 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-move-cursor-into-trace/trace-2/cursor" + 888 # move cursor into input + 889 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk + 890 # + 891 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 892 # skip one line of padding + 893 check-screen-row screen, 1/y, " 12 ", "F - test-run-move-cursor-into-trace/input-0" + 894 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-move-cursor-into-trace/input-0/cursor" + 895 check-screen-row screen, 2/y, " ... ", "F - test-run-move-cursor-into-trace/input-1" + 896 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/input-1/cursor" + 897 check-screen-row screen, 3/y, " => 12 ", "F - test-run-move-cursor-into-trace/input-2" + 898 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-move-cursor-into-trace/input-2/cursor" + 899 } + 900 + 901 fn has-trace? _self: (addr sandbox) -> _/eax: boolean { + 902 var self/esi: (addr sandbox) <- copy _self + 903 var trace-ah/eax: (addr handle trace) <- get self, trace + 904 var _trace/eax: (addr trace) <- lookup *trace-ah + 905 var trace/edx: (addr trace) <- copy _trace + 906 compare trace, 0 + 907 { + 908 break-if-!= + 909 abort "null trace" + 910 } + 911 var first-free/ebx: (addr int) <- get trace, first-free + 912 compare *first-free, 0 + 913 { + 914 break-if-> + 915 return 0/false + 916 } + 917 return 1/true + 918 } + 919 + 920 fn test-run-expand-trace { + 921 var sandbox-storage: sandbox + 922 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 923 initialize-sandbox-with sandbox, "12" + 924 # eval + 925 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 926 # setup: screen + 927 var screen-on-stack: screen + 928 var screen/edi: (addr screen) <- address screen-on-stack + 929 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 930 # + 931 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 932 # skip one line of padding + 933 check-screen-row screen, 1/y, " 12 ", "F - test-run-expand-trace/pre0-0" + 934 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-expand-trace/pre0-0/cursor" + 935 check-screen-row screen, 2/y, " ... ", "F - test-run-expand-trace/pre0-1" + 936 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-expand-trace/pre0-1/cursor" + 937 check-screen-row screen, 3/y, " => 12 ", "F - test-run-expand-trace/pre0-2" + 938 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-expand-trace/pre0-2/cursor" + 939 # move cursor into trace + 940 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk + 941 # + 942 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 943 # skip one line of padding + 944 check-screen-row screen, 1/y, " 12 ", "F - test-run-expand-trace/pre1-0" + 945 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-expand-trace/pre1-0/cursor" + 946 check-screen-row screen, 2/y, " ... ", "F - test-run-expand-trace/pre1-1" + 947 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||| ", "F - test-run-expand-trace/pre1-1/cursor" + 948 check-screen-row screen, 3/y, " => 12 ", "F - test-run-expand-trace/pre1-2" + 949 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-expand-trace/pre1-2/cursor" + 950 # expand + 951 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk + 952 # + 953 clear-screen screen + 954 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 955 # skip one line of padding + 956 check-screen-row screen, 1/y, " 12 ", "F - test-run-expand-trace/expand-0" + 957 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-expand-trace/expand-0/cursor" + 958 check-screen-row screen, 2/y, " 1 toke", "F - test-run-expand-trace/expand-1" + 959 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||||||", "F - test-run-expand-trace/expand-1/cursor" + 960 check-screen-row screen, 3/y, " ... ", "F - test-run-expand-trace/expand-2" + 961 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-expand-trace/expand-2/cursor" + 962 check-screen-row screen, 4/y, " 1 pars", "F - test-run-expand-trace/expand-2" + 963 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-expand-trace/expand-2/cursor" + 964 } + 965 + 966 fn test-run-can-rerun-when-expanding-trace { + 967 var sandbox-storage: sandbox + 968 var sandbox/esi: (addr sandbox) <- address sandbox-storage + 969 # initialize sandbox with a max-depth of 3 + 970 initialize-sandbox-with sandbox, "12" + 971 # eval + 972 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk + 973 # setup: screen + 974 var screen-on-stack: screen + 975 var screen/edi: (addr screen) <- address screen-on-stack + 976 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics + 977 # + 978 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 979 # skip one line of padding + 980 check-screen-row screen, 1/y, " 12 ", "F - test-run-can-rerun-when-expanding-trace/pre0-0" + 981 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-can-rerun-when-expanding-trace/pre0-0/cursor" + 982 check-screen-row screen, 2/y, " ... ", "F - test-run-can-rerun-when-expanding-trace/pre0-1" + 983 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre0-1/cursor" + 984 check-screen-row screen, 3/y, " => 12 ", "F - test-run-can-rerun-when-expanding-trace/pre0-2" + 985 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre0-2/cursor" + 986 # move cursor into trace + 987 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk + 988 # + 989 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor + 990 # skip one line of padding + 991 check-screen-row screen, 1/y, " 12 ", "F - test-run-can-rerun-when-expanding-trace/pre1-0" + 992 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre1-0/cursor" + 993 check-screen-row screen, 2/y, " ... ", "F - test-run-can-rerun-when-expanding-trace/pre1-1" + 994 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||| ", "F - test-run-can-rerun-when-expanding-trace/pre1-1/cursor" + 995 check-screen-row screen, 3/y, " => 12 ", "F - test-run-can-rerun-when-expanding-trace/pre1-2" + 996 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre1-2/cursor" + 997 # expand + 998 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk 999 # -1000 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1001 # skip one line of padding -1002 check-screen-row screen, 1/y, " 12 ", "F - test-run-expand-trace/pre0-0" -1003 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-expand-trace/pre0-0/cursor" -1004 check-screen-row screen, 2/y, " ... ", "F - test-run-expand-trace/pre0-1" -1005 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-expand-trace/pre0-1/cursor" -1006 check-screen-row screen, 3/y, " => 12 ", "F - test-run-expand-trace/pre0-2" -1007 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-expand-trace/pre0-2/cursor" -1008 # move cursor into trace -1009 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1010 # -1011 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1012 # skip one line of padding -1013 check-screen-row screen, 1/y, " 12 ", "F - test-run-expand-trace/pre1-0" -1014 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-expand-trace/pre1-0/cursor" -1015 check-screen-row screen, 2/y, " ... ", "F - test-run-expand-trace/pre1-1" -1016 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||| ", "F - test-run-expand-trace/pre1-1/cursor" -1017 check-screen-row screen, 3/y, " => 12 ", "F - test-run-expand-trace/pre1-2" -1018 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-expand-trace/pre1-2/cursor" -1019 # expand -1020 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1021 # -1022 clear-screen screen -1023 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1024 # skip one line of padding -1025 check-screen-row screen, 1/y, " 12 ", "F - test-run-expand-trace/expand-0" -1026 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-expand-trace/expand-0/cursor" -1027 check-screen-row screen, 2/y, " 1 toke", "F - test-run-expand-trace/expand-1" -1028 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||||||", "F - test-run-expand-trace/expand-1/cursor" -1029 check-screen-row screen, 3/y, " ... ", "F - test-run-expand-trace/expand-2" -1030 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-expand-trace/expand-2/cursor" -1031 check-screen-row screen, 4/y, " 1 pars", "F - test-run-expand-trace/expand-2" -1032 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-expand-trace/expand-2/cursor" -1033 } -1034 -1035 fn test-run-can-rerun-when-expanding-trace { -1036 var sandbox-storage: sandbox -1037 var sandbox/esi: (addr sandbox) <- address sandbox-storage -1038 # initialize sandbox with a max-depth of 3 -1039 initialize-sandbox-with sandbox, "12" -1040 # eval -1041 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1042 # setup: screen -1043 var screen-on-stack: screen -1044 var screen/edi: (addr screen) <- address screen-on-stack -1045 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics -1046 # -1047 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1048 # skip one line of padding -1049 check-screen-row screen, 1/y, " 12 ", "F - test-run-can-rerun-when-expanding-trace/pre0-0" -1050 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-can-rerun-when-expanding-trace/pre0-0/cursor" -1051 check-screen-row screen, 2/y, " ... ", "F - test-run-can-rerun-when-expanding-trace/pre0-1" -1052 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre0-1/cursor" -1053 check-screen-row screen, 3/y, " => 12 ", "F - test-run-can-rerun-when-expanding-trace/pre0-2" -1054 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre0-2/cursor" -1055 # move cursor into trace -1056 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1057 # -1058 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1059 # skip one line of padding -1060 check-screen-row screen, 1/y, " 12 ", "F - test-run-can-rerun-when-expanding-trace/pre1-0" -1061 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre1-0/cursor" -1062 check-screen-row screen, 2/y, " ... ", "F - test-run-can-rerun-when-expanding-trace/pre1-1" -1063 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||| ", "F - test-run-can-rerun-when-expanding-trace/pre1-1/cursor" -1064 check-screen-row screen, 3/y, " => 12 ", "F - test-run-can-rerun-when-expanding-trace/pre1-2" -1065 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre1-2/cursor" -1066 # expand -1067 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1068 # -1069 clear-screen screen -1070 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1071 # skip one line of padding -1072 check-screen-row screen, 1/y, " 12 ", "F - test-run-can-rerun-when-expanding-trace/pre2-0" -1073 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre2-0/cursor" -1074 check-screen-row screen, 2/y, " 1 toke", "F - test-run-can-rerun-when-expanding-trace/pre2-1" -1075 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||||||", "F - test-run-can-rerun-when-expanding-trace/pre2-1/cursor" -1076 check-screen-row screen, 3/y, " ... ", "F - test-run-can-rerun-when-expanding-trace/pre2-2" -1077 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre2-2/cursor" -1078 check-screen-row screen, 4/y, " 1 pars", "F - test-run-can-rerun-when-expanding-trace/pre2-2" -1079 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre2-2/cursor" -1080 # move cursor down and expand -1081 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1082 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1083 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1084 # -1085 clear-screen screen +1000 clear-screen screen +1001 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1002 # skip one line of padding +1003 check-screen-row screen, 1/y, " 12 ", "F - test-run-can-rerun-when-expanding-trace/pre2-0" +1004 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre2-0/cursor" +1005 check-screen-row screen, 2/y, " 1 toke", "F - test-run-can-rerun-when-expanding-trace/pre2-1" +1006 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||||||", "F - test-run-can-rerun-when-expanding-trace/pre2-1/cursor" +1007 check-screen-row screen, 3/y, " ... ", "F - test-run-can-rerun-when-expanding-trace/pre2-2" +1008 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre2-2/cursor" +1009 check-screen-row screen, 4/y, " 1 pars", "F - test-run-can-rerun-when-expanding-trace/pre2-2" +1010 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-can-rerun-when-expanding-trace/pre2-2/cursor" +1011 # move cursor down and expand +1012 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk +1013 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1014 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk +1015 # +1016 clear-screen screen +1017 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1018 # screen looks same as if trace max-depth was really high +1019 check-screen-row screen, 1/y, " 12 ", "F - test-run-can-rerun-when-expanding-trace/expand-0" +1020 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-can-rerun-when-expanding-trace/expand-0/cursor" +1021 check-screen-row screen, 2/y, " 1 toke", "F - test-run-can-rerun-when-expanding-trace/expand-1" +1022 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-can-rerun-when-expanding-trace/expand-1/cursor" +1023 check-screen-row screen, 3/y, " 2 next", "F - test-run-can-rerun-when-expanding-trace/expand-2" +1024 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ||||||", "F - test-run-can-rerun-when-expanding-trace/expand-2/cursor" +1025 check-screen-row screen, 4/y, " ... ", "F - test-run-can-rerun-when-expanding-trace/expand-3" +1026 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-can-rerun-when-expanding-trace/expand-3/cursor" +1027 check-screen-row screen, 5/y, " 2 => 1", "F - test-run-can-rerun-when-expanding-trace/expand-4" +1028 check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, " ", "F - test-run-can-rerun-when-expanding-trace/expand-4/cursor" +1029 } +1030 +1031 fn test-run-preserves-trace-view-on-rerun { +1032 var sandbox-storage: sandbox +1033 var sandbox/esi: (addr sandbox) <- address sandbox-storage +1034 # initialize sandbox with a max-depth of 3 +1035 initialize-sandbox-with sandbox, "7" +1036 # eval +1037 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk +1038 # setup: screen +1039 var screen-on-stack: screen +1040 var screen/edi: (addr screen) <- address screen-on-stack +1041 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics +1042 # +1043 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1044 # skip one line of padding +1045 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/pre0-0" +1046 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-preserves-trace-view-on-rerun/pre0-0/cursor" +1047 check-screen-row screen, 2/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre0-1" +1048 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre0-1/cursor" +1049 check-screen-row screen, 3/y, " => 7 ", "F - test-run-preserves-trace-view-on-rerun/pre0-2" +1050 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre0-2/cursor" +1051 # move cursor into trace +1052 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk +1053 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1054 # +1055 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/pre1-0" +1056 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre1-0/cursor" +1057 check-screen-row screen, 2/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre1-1" +1058 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||| ", "F - test-run-preserves-trace-view-on-rerun/pre1-1/cursor" +1059 check-screen-row screen, 3/y, " => 7 ", "F - test-run-preserves-trace-view-on-rerun/pre1-2" +1060 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre1-2/cursor" +1061 # expand +1062 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk +1063 clear-screen screen +1064 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1065 # +1066 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/pre2-0" +1067 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-0/cursor" +1068 check-screen-row screen, 2/y, " 1 tokenize ", "F - test-run-preserves-trace-view-on-rerun/pre2-1" +1069 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " |||||||||| ", "F - test-run-preserves-trace-view-on-rerun/pre2-1/cursor" +1070 check-screen-row screen, 3/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre2-2" +1071 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-2/cursor" +1072 check-screen-row screen, 4/y, " 1 parse ", "F - test-run-preserves-trace-view-on-rerun/pre2-3" +1073 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-3/cursor" +1074 check-screen-row screen, 5/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre2-4" +1075 check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-4/cursor" +1076 check-screen-row screen, 6/y, " 1 macroexpand 7 ", "F - test-run-preserves-trace-view-on-rerun/pre2-5" +1077 check-background-color-in-screen-row screen, 7/bg=cursor, 6/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-5/cursor" +1078 check-screen-row screen, 7/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre2-6" +1079 check-background-color-in-screen-row screen, 7/bg=cursor, 7/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-6/cursor" +1080 check-screen-row screen, 8/y, " 1 => 7 ", "F - test-run-preserves-trace-view-on-rerun/pre2-7" +1081 check-background-color-in-screen-row screen, 7/bg=cursor, 8/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-7/cursor" +1082 # move cursor down below the macroexpand line and expand +1083 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk +1084 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1085 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk 1086 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1087 # screen looks same as if trace max-depth was really high -1088 check-screen-row screen, 1/y, " 12 ", "F - test-run-can-rerun-when-expanding-trace/expand-0" -1089 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-can-rerun-when-expanding-trace/expand-0/cursor" -1090 check-screen-row screen, 2/y, " 1 toke", "F - test-run-can-rerun-when-expanding-trace/expand-1" -1091 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-can-rerun-when-expanding-trace/expand-1/cursor" -1092 check-screen-row screen, 3/y, " 2 next", "F - test-run-can-rerun-when-expanding-trace/expand-2" -1093 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ||||||", "F - test-run-can-rerun-when-expanding-trace/expand-2/cursor" -1094 check-screen-row screen, 4/y, " ... ", "F - test-run-can-rerun-when-expanding-trace/expand-3" -1095 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-can-rerun-when-expanding-trace/expand-3/cursor" -1096 check-screen-row screen, 5/y, " 2 => 1", "F - test-run-can-rerun-when-expanding-trace/expand-4" -1097 check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, " ", "F - test-run-can-rerun-when-expanding-trace/expand-4/cursor" -1098 } -1099 -1100 fn test-run-preserves-trace-view-on-rerun { -1101 var sandbox-storage: sandbox -1102 var sandbox/esi: (addr sandbox) <- address sandbox-storage -1103 # initialize sandbox with a max-depth of 3 -1104 initialize-sandbox-with sandbox, "7" -1105 # eval -1106 edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1107 # setup: screen -1108 var screen-on-stack: screen -1109 var screen/edi: (addr screen) <- address screen-on-stack -1110 initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics -1111 # -1112 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1113 # skip one line of padding -1114 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/pre0-0" -1115 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " | ", "F - test-run-preserves-trace-view-on-rerun/pre0-0/cursor" -1116 check-screen-row screen, 2/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre0-1" -1117 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre0-1/cursor" -1118 check-screen-row screen, 3/y, " => 7 ", "F - test-run-preserves-trace-view-on-rerun/pre0-2" -1119 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre0-2/cursor" -1120 # move cursor into trace -1121 edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1122 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1123 # -1124 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/pre1-0" -1125 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre1-0/cursor" -1126 check-screen-row screen, 2/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre1-1" -1127 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||| ", "F - test-run-preserves-trace-view-on-rerun/pre1-1/cursor" -1128 check-screen-row screen, 3/y, " => 7 ", "F - test-run-preserves-trace-view-on-rerun/pre1-2" -1129 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre1-2/cursor" -1130 # expand -1131 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1132 clear-screen screen -1133 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1134 # -1135 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/pre2-0" -1136 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-0/cursor" -1137 check-screen-row screen, 2/y, " 1 tokenize ", "F - test-run-preserves-trace-view-on-rerun/pre2-1" -1138 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " |||||||||| ", "F - test-run-preserves-trace-view-on-rerun/pre2-1/cursor" -1139 check-screen-row screen, 3/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre2-2" -1140 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-2/cursor" -1141 check-screen-row screen, 4/y, " 1 parse ", "F - test-run-preserves-trace-view-on-rerun/pre2-3" -1142 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-3/cursor" -1143 check-screen-row screen, 5/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre2-4" -1144 check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-4/cursor" -1145 check-screen-row screen, 6/y, " 1 macroexpand 7 ", "F - test-run-preserves-trace-view-on-rerun/pre2-5" -1146 check-background-color-in-screen-row screen, 7/bg=cursor, 6/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-5/cursor" -1147 check-screen-row screen, 7/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre2-6" -1148 check-background-color-in-screen-row screen, 7/bg=cursor, 7/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-6/cursor" -1149 check-screen-row screen, 8/y, " 1 => 7 ", "F - test-run-preserves-trace-view-on-rerun/pre2-7" -1150 check-background-color-in-screen-row screen, 7/bg=cursor, 8/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre2-7/cursor" -1151 # move cursor down below the macroexpand line and expand -1152 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1153 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1154 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1155 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1156 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1157 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1158 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1159 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1160 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1161 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1162 # -1163 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/pre3-0" -1164 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-0/cursor" -1165 check-screen-row screen, 2/y, " 1 tokenize ", "F - test-run-preserves-trace-view-on-rerun/pre3-1" -1166 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-1/cursor" -1167 check-screen-row screen, 3/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre3-2" -1168 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-2/cursor" -1169 check-screen-row screen, 4/y, " 1 parse ", "F - test-run-preserves-trace-view-on-rerun/pre3-3" -1170 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-3/cursor" -1171 check-screen-row screen, 5/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre3-4" -1172 check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-4/cursor" -1173 check-screen-row screen, 6/y, " 1 macroexpand 7 ", "F - test-run-preserves-trace-view-on-rerun/pre3-5" -1174 check-background-color-in-screen-row screen, 7/bg=cursor, 6/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-5/cursor" -1175 check-screen-row screen, 7/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre3-6" -1176 check-background-color-in-screen-row screen, 7/bg=cursor, 7/y, " ||| ", "F - test-run-preserves-trace-view-on-rerun/pre3-6/cursor" -1177 check-screen-row screen, 8/y, " 1 => 7 ", "F - test-run-preserves-trace-view-on-rerun/pre3-7" -1178 check-background-color-in-screen-row screen, 7/bg=cursor, 8/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-7/cursor" -1179 # expand -1180 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk, 0/no-tweak-screen -1181 clear-screen screen -1182 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor -1183 # cursor line is expanded -1184 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/expand-0" -1185 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-0/cursor" -1186 check-screen-row screen, 2/y, " 1 tokenize ", "F - test-run-preserves-trace-view-on-rerun/expand-1" -1187 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-1/cursor" -1188 check-screen-row screen, 3/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/expand-2" -1189 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-2/cursor" -1190 check-screen-row screen, 4/y, " 1 parse ", "F - test-run-preserves-trace-view-on-rerun/expand-3" -1191 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-3/cursor" -1192 check-screen-row screen, 5/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/expand-4" -1193 check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-4/cursor" -1194 check-screen-row screen, 6/y, " 1 macroexpand 7 ", "F - test-run-preserves-trace-view-on-rerun/expand-5" -1195 check-background-color-in-screen-row screen, 7/bg=cursor, 6/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-5/cursor" -1196 check-screen-row screen, 7/y, " 2 macroexpand-iter 7 ", "F - test-run-preserves-trace-view-on-rerun/expand-6" -1197 check-background-color-in-screen-row screen, 7/bg=cursor, 7/y, " |||||||||||||||||||| ", "F - test-run-preserves-trace-view-on-rerun/expand-6/cursor" -1198 check-screen-row screen, 8/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/expand-7" -1199 check-background-color-in-screen-row screen, 7/bg=cursor, 8/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-7/cursor" -1200 } +1087 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk +1088 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1089 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk +1090 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1091 edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk +1092 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1093 # +1094 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/pre3-0" +1095 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-0/cursor" +1096 check-screen-row screen, 2/y, " 1 tokenize ", "F - test-run-preserves-trace-view-on-rerun/pre3-1" +1097 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-1/cursor" +1098 check-screen-row screen, 3/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre3-2" +1099 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-2/cursor" +1100 check-screen-row screen, 4/y, " 1 parse ", "F - test-run-preserves-trace-view-on-rerun/pre3-3" +1101 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-3/cursor" +1102 check-screen-row screen, 5/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre3-4" +1103 check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-4/cursor" +1104 check-screen-row screen, 6/y, " 1 macroexpand 7 ", "F - test-run-preserves-trace-view-on-rerun/pre3-5" +1105 check-background-color-in-screen-row screen, 7/bg=cursor, 6/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-5/cursor" +1106 check-screen-row screen, 7/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/pre3-6" +1107 check-background-color-in-screen-row screen, 7/bg=cursor, 7/y, " ||| ", "F - test-run-preserves-trace-view-on-rerun/pre3-6/cursor" +1108 check-screen-row screen, 8/y, " 1 => 7 ", "F - test-run-preserves-trace-view-on-rerun/pre3-7" +1109 check-background-color-in-screen-row screen, 7/bg=cursor, 8/y, " ", "F - test-run-preserves-trace-view-on-rerun/pre3-7/cursor" +1110 # expand +1111 edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk +1112 clear-screen screen +1113 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor +1114 # cursor line is expanded +1115 check-screen-row screen, 1/y, " 7 ", "F - test-run-preserves-trace-view-on-rerun/expand-0" +1116 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-0/cursor" +1117 check-screen-row screen, 2/y, " 1 tokenize ", "F - test-run-preserves-trace-view-on-rerun/expand-1" +1118 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-1/cursor" +1119 check-screen-row screen, 3/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/expand-2" +1120 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-2/cursor" +1121 check-screen-row screen, 4/y, " 1 parse ", "F - test-run-preserves-trace-view-on-rerun/expand-3" +1122 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-3/cursor" +1123 check-screen-row screen, 5/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/expand-4" +1124 check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-4/cursor" +1125 check-screen-row screen, 6/y, " 1 macroexpand 7 ", "F - test-run-preserves-trace-view-on-rerun/expand-5" +1126 check-background-color-in-screen-row screen, 7/bg=cursor, 6/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-5/cursor" +1127 check-screen-row screen, 7/y, " 2 macroexpand-iter 7 ", "F - test-run-preserves-trace-view-on-rerun/expand-6" +1128 check-background-color-in-screen-row screen, 7/bg=cursor, 7/y, " |||||||||||||||||||| ", "F - test-run-preserves-trace-view-on-rerun/expand-6/cursor" +1129 check-screen-row screen, 8/y, " ... ", "F - test-run-preserves-trace-view-on-rerun/expand-7" +1130 check-background-color-in-screen-row screen, 7/bg=cursor, 8/y, " ", "F - test-run-preserves-trace-view-on-rerun/expand-7/cursor" +1131 } diff --git a/html/shell/tokenize.mu.html b/html/shell/tokenize.mu.html index 46eb9a77..39730066 100644 --- a/html/shell/tokenize.mu.html +++ b/html/shell/tokenize.mu.html @@ -16,6 +16,7 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } .Delimiter { color: #c000c0; } +.muRegEdx { color: #878700; } .muRegEbx { color: #8787af; } .muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } @@ -27,7 +28,6 @@ a { color:inherit; } .muComment { color: #005faf; } .muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } --> @@ -63,990 +63,1133 @@ if ('onhashchange' in window) { https://github.com/akkartik/mu/blob/main/shell/tokenize.mu
-  1 # We reuse the cell data structure for tokenization
-  2 # Token cells are special, though. They have no type, they're always atoms,
-  3 # they always have text-data.
-  4 
-  5 fn tokenize in: (addr gap-buffer), out: (addr stream cell), trace: (addr trace) {
-  6   trace-text trace, "tokenize", "tokenize"
-  7   trace-lower trace
-  8   rewind-gap-buffer in
-  9   var token-storage: cell
- 10   var token/edx: (addr cell) <- address token-storage
- 11   {
- 12     skip-whitespace-from-gap-buffer in
- 13     var done?/eax: boolean <- gap-buffer-scan-done? in
- 14     compare done?, 0/false
- 15     break-if-!=
- 16     #
- 17     next-token in, token, trace
- 18     var error?/eax: boolean <- has-errors? trace
- 19     compare error?, 0/false
- 20     {
- 21       break-if-=
- 22       return
- 23     }
- 24     var skip?/eax: boolean <- comment-token? token
- 25     compare skip?, 0/false
- 26     loop-if-!=
- 27     write-to-stream out, token  # shallow-copy text-data
- 28     loop
- 29   }
- 30   trace-higher trace
- 31 }
- 32 
- 33 fn test-tokenize-quote {
- 34   var in-storage: gap-buffer
- 35   var in/esi: (addr gap-buffer) <- address in-storage
- 36   initialize-gap-buffer-with in, "'(a)"
- 37   #
- 38   var stream-storage: (stream cell 0x10)
- 39   var stream/edi: (addr stream cell) <- address stream-storage
- 40   #
- 41   var trace-storage: trace
- 42   var trace/edx: (addr trace) <- address trace-storage
- 43   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
- 44   tokenize in, stream, trace
- 45   #
- 46   var curr-token-storage: cell
- 47   var curr-token/ebx: (addr cell) <- address curr-token-storage
- 48   read-from-stream stream, curr-token
- 49   var quote?/eax: boolean <- quote-token? curr-token
- 50   check quote?, "F - test-tokenize-quote: quote"
- 51   read-from-stream stream, curr-token
- 52   var open-paren?/eax: boolean <- open-paren-token? curr-token
- 53   check open-paren?, "F - test-tokenize-quote: open paren"
- 54   read-from-stream stream, curr-token  # skip a
- 55   read-from-stream stream, curr-token
- 56   var close-paren?/eax: boolean <- close-paren-token? curr-token
- 57   check close-paren?, "F - test-tokenize-quote: close paren"
- 58 }
- 59 
- 60 fn test-tokenize-backquote {
- 61   var in-storage: gap-buffer
- 62   var in/esi: (addr gap-buffer) <- address in-storage
- 63   initialize-gap-buffer-with in, "`(a)"
- 64   #
- 65   var stream-storage: (stream cell 0x10)
- 66   var stream/edi: (addr stream cell) <- address stream-storage
- 67   #
- 68   var trace-storage: trace
- 69   var trace/edx: (addr trace) <- address trace-storage
- 70   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
- 71   tokenize in, stream, trace
- 72   #
- 73   var curr-token-storage: cell
- 74   var curr-token/ebx: (addr cell) <- address curr-token-storage
- 75   read-from-stream stream, curr-token
- 76   var backquote?/eax: boolean <- backquote-token? curr-token
- 77   check backquote?, "F - test-tokenize-backquote: backquote"
- 78   read-from-stream stream, curr-token
- 79   var open-paren?/eax: boolean <- open-paren-token? curr-token
- 80   check open-paren?, "F - test-tokenize-backquote: open paren"
- 81   read-from-stream stream, curr-token  # skip a
- 82   read-from-stream stream, curr-token
- 83   var close-paren?/eax: boolean <- close-paren-token? curr-token
- 84   check close-paren?, "F - test-tokenize-backquote: close paren"
- 85 }
- 86 
- 87 fn test-tokenize-unquote {
- 88   var in-storage: gap-buffer
- 89   var in/esi: (addr gap-buffer) <- address in-storage
- 90   initialize-gap-buffer-with in, ",(a)"
- 91   #
- 92   var stream-storage: (stream cell 0x10)
- 93   var stream/edi: (addr stream cell) <- address stream-storage
- 94   #
- 95   var trace-storage: trace
- 96   var trace/edx: (addr trace) <- address trace-storage
- 97   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
- 98   tokenize in, stream, trace
- 99   #
-100   var curr-token-storage: cell
-101   var curr-token/ebx: (addr cell) <- address curr-token-storage
-102   read-from-stream stream, curr-token
-103   var unquote?/eax: boolean <- unquote-token? curr-token
-104   check unquote?, "F - test-tokenize-unquote: unquote"
-105   read-from-stream stream, curr-token
-106   var open-paren?/eax: boolean <- open-paren-token? curr-token
-107   check open-paren?, "F - test-tokenize-unquote: open paren"
-108   read-from-stream stream, curr-token  # skip a
-109   read-from-stream stream, curr-token
-110   var close-paren?/eax: boolean <- close-paren-token? curr-token
-111   check close-paren?, "F - test-tokenize-unquote: close paren"
-112 }
-113 
-114 fn test-tokenize-unquote-splice {
-115   var in-storage: gap-buffer
-116   var in/esi: (addr gap-buffer) <- address in-storage
-117   initialize-gap-buffer-with in, ",@a"
-118   #
-119   var stream-storage: (stream cell 0x10)
-120   var stream/edi: (addr stream cell) <- address stream-storage
-121   #
-122   var trace-storage: trace
-123   var trace/edx: (addr trace) <- address trace-storage
-124   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
-125   tokenize in, stream, trace
-126   #
-127   var curr-token-storage: cell
-128   var curr-token/ebx: (addr cell) <- address curr-token-storage
-129   read-from-stream stream, curr-token
-130   var unquote-splice?/eax: boolean <- unquote-splice-token? curr-token
-131   check unquote-splice?, "F - test-tokenize-unquote-splice: unquote-splice"
-132 }
-133 
-134 fn test-tokenize-dotted-list {
-135   var in-storage: gap-buffer
-136   var in/esi: (addr gap-buffer) <- address in-storage
-137   initialize-gap-buffer-with in, "(a . b)"
-138   #
-139   var stream-storage: (stream cell 0x10)
-140   var stream/edi: (addr stream cell) <- address stream-storage
-141   #
-142   var trace-storage: trace
-143   var trace/edx: (addr trace) <- address trace-storage
-144   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
-145   tokenize in, stream, trace
-146   #
-147   var curr-token-storage: cell
-148   var curr-token/ebx: (addr cell) <- address curr-token-storage
-149   read-from-stream stream, curr-token
-150   var open-paren?/eax: boolean <- open-paren-token? curr-token
-151   check open-paren?, "F - test-tokenize-dotted-list: open paren"
-152   read-from-stream stream, curr-token  # skip a
-153   read-from-stream stream, curr-token
-154   var dot?/eax: boolean <- dot-token? curr-token
-155   check dot?, "F - test-tokenize-dotted-list: dot"
-156   read-from-stream stream, curr-token  # skip b
-157   read-from-stream stream, curr-token
-158   var close-paren?/eax: boolean <- close-paren-token? curr-token
-159   check close-paren?, "F - test-tokenize-dotted-list: close paren"
-160 }
-161 
-162 fn test-tokenize-stream-literal {
-163   var in-storage: gap-buffer
-164   var in/esi: (addr gap-buffer) <- address in-storage
-165   initialize-gap-buffer-with in, "[abc def]"
-166   #
-167   var stream-storage: (stream cell 0x10)
-168   var stream/edi: (addr stream cell) <- address stream-storage
-169   #
-170   var trace-storage: trace
-171   var trace/edx: (addr trace) <- address trace-storage
-172   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
-173   tokenize in, stream, trace
-174   #
-175   var curr-token-storage: cell
-176   var curr-token/ebx: (addr cell) <- address curr-token-storage
-177   read-from-stream stream, curr-token
-178   var stream?/eax: boolean <- stream-token? curr-token
-179   check stream?, "F - test-tokenize-stream-literal: type"
-180   var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
-181   var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
-182   var data-equal?/eax: boolean <- stream-data-equal? curr-token-data, "abc def"
-183   check data-equal?, "F - test-tokenize-stream-literal"
-184   var empty?/eax: boolean <- stream-empty? stream
-185   check empty?, "F - test-tokenize-stream-literal: empty?"
-186 }
-187 
-188 fn test-tokenize-stream-literal-in-tree {
-189   var in-storage: gap-buffer
-190   var in/esi: (addr gap-buffer) <- address in-storage
-191   initialize-gap-buffer-with in, "([abc def])"
-192   #
-193   var stream-storage: (stream cell 0x10)
-194   var stream/edi: (addr stream cell) <- address stream-storage
-195   #
-196   var trace-storage: trace
-197   var trace/edx: (addr trace) <- address trace-storage
-198   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
-199   tokenize in, stream, trace
-200   #
-201   var curr-token-storage: cell
-202   var curr-token/ebx: (addr cell) <- address curr-token-storage
-203   read-from-stream stream, curr-token
-204   var bracket?/eax: boolean <- bracket-token? curr-token
-205   check bracket?, "F - test-tokenize-stream-literal-in-tree: open paren"
-206   read-from-stream stream, curr-token
-207   var stream?/eax: boolean <- stream-token? curr-token
-208   check stream?, "F - test-tokenize-stream-literal-in-tree: type"
-209   var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
-210   var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
-211   var data-equal?/eax: boolean <- stream-data-equal? curr-token-data, "abc def"
-212   check data-equal?, "F - test-tokenize-stream-literal-in-tree"
-213   read-from-stream stream, curr-token
-214   var bracket?/eax: boolean <- bracket-token? curr-token
-215   check bracket?, "F - test-tokenize-stream-literal-in-tree: close paren"
-216   var empty?/eax: boolean <- stream-empty? stream
-217   check empty?, "F - test-tokenize-stream-literal-in-tree: empty?"
-218 }
-219 
-220 fn next-token in: (addr gap-buffer), _out-cell: (addr cell), trace: (addr trace) {
-221   trace-text trace, "tokenize", "next-token"
-222   trace-lower trace
-223   var _g/eax: grapheme <- peek-from-gap-buffer in
-224   var g/ecx: grapheme <- copy _g
-225   {
-226     var stream-storage: (stream byte 0x40)
-227     var stream/esi: (addr stream byte) <- address stream-storage
-228     write stream, "next: "
-229     var gval/eax: int <- copy g
-230     write-int32-hex stream, gval
-231     trace trace, "tokenize", stream
-232   }
-233   var out-cell/eax: (addr cell) <- copy _out-cell
-234   {
-235     var out-cell-type/eax: (addr int) <- get out-cell, type
-236     copy-to *out-cell-type, 0/uninitialized
-237   }
-238   var out-ah/edi: (addr handle stream byte) <- get out-cell, text-data
-239   $next-token:allocate: {
-240     # Allocate a large buffer if it's a stream.
-241     # Sometimes a whole function definition will need to fit in it.
-242     compare g, 0x5b/open-square-bracket
-243     {
-244       break-if-!=
-245       populate-stream out-ah, 0x400/max-definition-size=1KB
-246       break $next-token:allocate
-247     }
-248     populate-stream out-ah, 0x40
-249   }
-250   var _out/eax: (addr stream byte) <- lookup *out-ah
-251   var out/edi: (addr stream byte) <- copy _out
-252   clear-stream out
-253   $next-token:case: {
-254     # open square brackets begin streams
-255     {
-256       compare g, 0x5b/open-square-bracket
-257       break-if-!=
-258       var dummy/eax: grapheme <- read-from-gap-buffer in  # skip open bracket
-259       next-stream-token in, out, trace
-260       var out-cell/eax: (addr cell) <- copy _out-cell
-261       # streams set the type
-262       var out-cell-type/eax: (addr int) <- get out-cell, type
-263       copy-to *out-cell-type, 3/stream
-264       break $next-token:case
-265     }
-266     # comment
-267     {
-268       compare g, 0x23/comment
-269       break-if-!=
-270       rest-of-line in, out, trace
-271       break $next-token:case
-272     }
-273     # digit
-274     {
-275       var digit?/eax: boolean <- decimal-digit? g
-276       compare digit?, 0/false
-277       break-if-=
-278       next-number-token in, out, trace
-279       break $next-token:case
-280     }
-281     # other symbol char
-282     {
-283       var symbol?/eax: boolean <- symbol-grapheme? g
-284       compare symbol?, 0/false
-285       break-if-=
-286       next-symbol-token in, out, trace
-287       break $next-token:case
-288     }
-289     # unbalanced close square brackets are errors
-290     {
-291       compare g, 0x5d/close-square-bracket
-292       break-if-!=
-293       error trace, "unbalanced ']'"
-294       return
-295     }
-296     # other brackets are always single-char tokens
-297     {
-298       var bracket?/eax: boolean <- bracket-grapheme? g
-299       compare bracket?, 0/false
-300       break-if-=
-301       var g/eax: grapheme <- read-from-gap-buffer in
-302       next-bracket-token g, out, trace
-303       break $next-token:case
-304     }
-305     # non-symbol operators
-306     {
-307       var operator?/eax: boolean <- operator-grapheme? g
-308       compare operator?, 0/false
-309       break-if-=
-310       next-operator-token in, out, trace
-311       break $next-token:case
-312     }
-313     # quote
-314     {
-315       compare g, 0x27/single-quote
-316       break-if-!=
-317       var g/eax: grapheme <- read-from-gap-buffer in  # consume
-318       write-grapheme out, g
-319       break $next-token:case
-320     }
-321     # backquote
-322     {
-323       compare g, 0x60/backquote
-324       break-if-!=
-325       var g/eax: grapheme <- read-from-gap-buffer in  # consume
-326       write-grapheme out, g
-327       break $next-token:case
-328     }
-329     # unquote
-330     {
-331       compare g, 0x2c/comma
-332       break-if-!=
-333       var g/eax: grapheme <- read-from-gap-buffer in  # consume
-334       write-grapheme out, g
-335       # check for unquote-splice
-336       {
-337         var g2/eax: grapheme <- peek-from-gap-buffer in
-338         compare g2, 0x40/at-sign
-339         break-if-!=
-340         g2 <- read-from-gap-buffer in
-341         write-grapheme out, g2
-342       }
-343       break $next-token:case
-344     }
-345     abort "unknown token type"
-346   }
-347   trace-higher trace
-348   var stream-storage: (stream byte 0x400)  # maximum possible token size (next-stream-token)
-349   var stream/eax: (addr stream byte) <- address stream-storage
-350   write stream, "=> "
-351   rewind-stream out
-352   write-stream stream, out
-353   trace trace, "tokenize", stream
-354 }
-355 
-356 fn next-symbol-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
-357   trace-text trace, "tokenize", "looking for a symbol"
-358   trace-lower trace
-359   $next-symbol-token:loop: {
-360     var done?/eax: boolean <- gap-buffer-scan-done? in
-361     compare done?, 0/false
-362     break-if-!=
-363     var g/eax: grapheme <- peek-from-gap-buffer in
-364     {
-365       var stream-storage: (stream byte 0x40)
-366       var stream/esi: (addr stream byte) <- address stream-storage
-367       write stream, "next: "
-368       var gval/eax: int <- copy g
-369       write-int32-hex stream, gval
-370       trace trace, "tokenize", stream
-371     }
-372     # if non-symbol, return
-373     {
-374       var symbol-grapheme?/eax: boolean <- symbol-grapheme? g
-375       compare symbol-grapheme?, 0/false
-376       break-if-!=
-377       trace-text trace, "tokenize", "stop"
-378       break $next-symbol-token:loop
-379     }
-380     var g/eax: grapheme <- read-from-gap-buffer in
-381     write-grapheme out, g
-382     loop
-383   }
-384   trace-higher trace
-385   var stream-storage: (stream byte 0x40)
-386   var stream/esi: (addr stream byte) <- address stream-storage
-387   write stream, "=> "
-388   rewind-stream out
-389   write-stream stream, out
-390   trace trace, "tokenize", stream
-391 }
-392 
-393 fn next-operator-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
-394   trace-text trace, "tokenize", "looking for a operator"
-395   trace-lower trace
-396   $next-operator-token:loop: {
-397     var done?/eax: boolean <- gap-buffer-scan-done? in
-398     compare done?, 0/false
-399     break-if-!=
-400     var g/eax: grapheme <- peek-from-gap-buffer in
-401     {
-402       var stream-storage: (stream byte 0x40)
-403       var stream/esi: (addr stream byte) <- address stream-storage
-404       write stream, "next: "
-405       var gval/eax: int <- copy g
-406       write-int32-hex stream, gval
-407       trace trace, "tokenize", stream
-408     }
-409     # if non-operator, return
-410     {
-411       var operator-grapheme?/eax: boolean <- operator-grapheme? g
-412       compare operator-grapheme?, 0/false
-413       break-if-!=
-414       trace-text trace, "tokenize", "stop"
-415       break $next-operator-token:loop
-416     }
-417     var g/eax: grapheme <- read-from-gap-buffer in
-418     write-grapheme out, g
-419     loop
-420   }
-421   trace-higher trace
-422   var stream-storage: (stream byte 0x40)
-423   var stream/esi: (addr stream byte) <- address stream-storage
-424   write stream, "=> "
-425   rewind-stream out
-426   write-stream stream, out
-427   trace trace, "tokenize", stream
-428 }
-429 
-430 fn next-number-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
-431   trace-text trace, "tokenize", "looking for a number"
-432   trace-lower trace
-433   $next-number-token:loop: {
-434     var done?/eax: boolean <- gap-buffer-scan-done? in
-435     compare done?, 0/false
-436     break-if-!=
-437     var g/eax: grapheme <- peek-from-gap-buffer in
-438     {
-439       var stream-storage: (stream byte 0x40)
-440       var stream/esi: (addr stream byte) <- address stream-storage
-441       write stream, "next: "
-442       var gval/eax: int <- copy g
-443       write-int32-hex stream, gval
-444       trace trace, "tokenize", stream
-445     }
-446     # if not symbol grapheme, return
-447     {
-448       var symbol-grapheme?/eax: boolean <- symbol-grapheme? g
-449       compare symbol-grapheme?, 0/false
-450       break-if-!=
-451       trace-text trace, "tokenize", "stop"
-452       break $next-number-token:loop
-453     }
-454     # if not digit grapheme, abort
-455     {
-456       var digit?/eax: boolean <- decimal-digit? g
-457       compare digit?, 0/false
-458       break-if-!=
-459       error trace, "invalid number"
-460       return
-461     }
-462     trace-text trace, "tokenize", "append"
-463     var g/eax: grapheme <- read-from-gap-buffer in
-464     write-grapheme out, g
-465     loop
-466   }
-467   trace-higher trace
-468 }
-469 
-470 fn next-stream-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
-471   trace-text trace, "tokenize", "stream"
-472   {
-473     var empty?/eax: boolean <- gap-buffer-scan-done? in
-474     compare empty?, 0/false
-475     {
-476       break-if-=
-477       error trace, "unbalanced '['"
-478       return
-479     }
-480     var g/eax: grapheme <- read-from-gap-buffer in
-481     compare g, 0x5d/close-square-bracket
-482     break-if-=
-483     write-grapheme out, g
-484     loop
-485   }
-486   var stream-storage: (stream byte 0x400)  # max-definition-size
-487   var stream/esi: (addr stream byte) <- address stream-storage
-488   write stream, "=> "
-489   rewind-stream out
-490   write-stream stream, out
-491   trace trace, "tokenize", stream
-492 }
-493 
-494 fn next-bracket-token g: grapheme, out: (addr stream byte), trace: (addr trace) {
-495   trace-text trace, "tokenize", "bracket"
-496   write-grapheme out, g
-497   var stream-storage: (stream byte 0x40)
-498   var stream/esi: (addr stream byte) <- address stream-storage
-499   write stream, "=> "
-500   rewind-stream out
-501   write-stream stream, out
-502   trace trace, "tokenize", stream
-503 }
-504 
-505 fn rest-of-line in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
-506   trace-text trace, "tokenize", "comment"
-507   {
-508     var empty?/eax: boolean <- gap-buffer-scan-done? in
-509     compare empty?, 0/false
-510     {
-511       break-if-=
-512       return
-513     }
-514     var g/eax: grapheme <- read-from-gap-buffer in
-515     compare g, 0xa/newline
-516     break-if-=
-517     write-grapheme out, g
-518     loop
-519   }
-520   var stream-storage: (stream byte 0x80)
-521   var stream/esi: (addr stream byte) <- address stream-storage
-522   write stream, "=> "
-523   rewind-stream out
-524   write-stream stream, out
-525   trace trace, "tokenize", stream
-526 }
-527 
-528 fn symbol-grapheme? g: grapheme -> _/eax: boolean {
-529   ## whitespace
-530   compare g, 9/tab
-531   {
-532     break-if-!=
-533     return 0/false
-534   }
-535   compare g, 0xa/newline
-536   {
-537     break-if-!=
-538     return 0/false
-539   }
-540   compare g, 0x20/space
-541   {
-542     break-if-!=
-543     return 0/false
-544   }
-545   ## quotes
-546   compare g, 0x22/double-quote
-547   {
-548     break-if-!=
-549     return 0/false
-550   }
-551   compare g, 0x60/backquote
-552   {
-553     break-if-!=
-554     return 0/false
-555   }
-556   ## brackets
-557   compare g, 0x28/open-paren
-558   {
-559     break-if-!=
-560     return 0/false
-561   }
-562   compare g, 0x29/close-paren
-563   {
-564     break-if-!=
-565     return 0/false
-566   }
-567   compare g, 0x5b/open-square-bracket
-568   {
-569     break-if-!=
-570     return 0/false
-571   }
-572   compare g, 0x5d/close-square-bracket
-573   {
-574     break-if-!=
-575     return 0/false
-576   }
-577   compare g, 0x7b/open-curly-bracket
-578   {
-579     break-if-!=
-580     return 0/false
-581   }
-582   compare g, 0x7d/close-curly-bracket
-583   {
-584     break-if-!=
-585     return 0/false
-586   }
-587   # - other punctuation
-588   # '!' is a symbol char
-589   compare g, 0x23/hash
-590   {
-591     break-if-!=
-592     return 0/false
-593   }
-594   # '$' is a symbol char
-595   compare g, 0x25/percent
-596   {
-597     break-if-!=
-598     return 0/false
-599   }
-600   compare g, 0x26/ampersand
-601   {
-602     break-if-!=
-603     return 0/false
-604   }
-605   compare g, 0x27/single-quote
-606   {
-607     break-if-!=
-608     return 0/false
-609   }
-610   compare g, 0x60/backquote
-611   {
-612     break-if-!=
-613     return 0/false
-614   }
-615   compare g, 0x2c/comma
-616   {
-617     break-if-!=
-618     return 0/false
-619   }
-620   compare g, 0x40/at-sign
-621   {
-622     break-if-!=
-623     return 0/false
-624   }
-625   compare g, 0x2a/asterisk
-626   {
-627     break-if-!=
-628     return 0/false
-629   }
-630   compare g, 0x2b/plus
-631   {
-632     break-if-!=
-633     return 0/false
-634   }
-635   compare g, 0x2d/dash  # '-' not allowed in symbols
-636   {
-637     break-if-!=
-638     return 0/false
-639   }
-640   compare g, 0x2e/period
-641   {
-642     break-if-!=
-643     return 0/false
-644   }
-645   compare g, 0x2f/slash
-646   {
-647     break-if-!=
-648     return 0/false
-649   }
-650   compare g, 0x3a/colon
-651   {
-652     break-if-!=
-653     return 0/false
-654   }
-655   compare g, 0x3b/semi-colon
-656   {
-657     break-if-!=
-658     return 0/false
-659   }
-660   compare g, 0x3c/less-than
-661   {
-662     break-if-!=
-663     return 0/false
-664   }
-665   compare g, 0x3d/equal
-666   {
-667     break-if-!=
-668     return 0/false
-669   }
-670   compare g, 0x3e/greater-than
-671   {
-672     break-if-!=
-673     return 0/false
-674   }
-675   # '?' is a symbol char
-676   compare g, 0x5c/backslash
-677   {
-678     break-if-!=
-679     return 0/false
-680   }
-681   compare g, 0x5e/caret
-682   {
-683     break-if-!=
-684     return 0/false
-685   }
-686   # '_' is a symbol char
-687   compare g, 0x7c/vertical-line
-688   {
-689     break-if-!=
-690     return 0/false
-691   }
-692   compare g, 0x7e/tilde
-693   {
-694     break-if-!=
-695     return 0/false
-696   }
-697   return 1/true
-698 }
-699 
-700 fn bracket-grapheme? g: grapheme -> _/eax: boolean {
-701   compare g, 0x28/open-paren
-702   {
-703     break-if-!=
-704     return 1/true
-705   }
-706   compare g, 0x29/close-paren
-707   {
-708     break-if-!=
-709     return 1/true
-710   }
-711   compare g, 0x5b/open-square-bracket
-712   {
-713     break-if-!=
-714     return 1/true
-715   }
-716   compare g, 0x5d/close-square-bracket
-717   {
-718     break-if-!=
-719     return 1/true
-720   }
-721   compare g, 0x7b/open-curly-bracket
-722   {
-723     break-if-!=
-724     return 1/true
-725   }
-726   compare g, 0x7d/close-curly-bracket
-727   {
-728     break-if-!=
-729     return 1/true
-730   }
-731   return 0/false
-732 }
-733 
-734 fn operator-grapheme? g: grapheme -> _/eax: boolean {
-735   # '$' is a symbol char
-736   compare g, 0x25/percent
-737   {
-738     break-if-!=
-739     return 1/false
-740   }
-741   compare g, 0x26/ampersand
-742   {
-743     break-if-!=
-744     return 1/true
-745   }
-746   compare g, 0x27/single-quote
-747   {
-748     break-if-!=
-749     return 0/true
-750   }
-751   compare g, 0x60/backquote
-752   {
-753     break-if-!=
-754     return 0/false
-755   }
-756   compare g, 0x2c/comma
-757   {
-758     break-if-!=
-759     return 0/false
-760   }
-761   compare g, 0x40/at-sign
-762   {
-763     break-if-!=
-764     return 0/false
-765   }
-766   compare g, 0x2a/asterisk
-767   {
-768     break-if-!=
-769     return 1/true
-770   }
-771   compare g, 0x2b/plus
-772   {
-773     break-if-!=
-774     return 1/true
-775   }
-776   compare g, 0x2d/dash  # '-' not allowed in symbols
-777   {
-778     break-if-!=
-779     return 1/true
-780   }
-781   compare g, 0x2e/period
-782   {
-783     break-if-!=
-784     return 1/true
-785   }
-786   compare g, 0x2f/slash
-787   {
-788     break-if-!=
-789     return 1/true
-790   }
-791   compare g, 0x3a/colon
-792   {
-793     break-if-!=
-794     return 1/true
-795   }
-796   compare g, 0x3b/semi-colon
-797   {
-798     break-if-!=
-799     return 1/true
-800   }
-801   compare g, 0x3c/less-than
-802   {
-803     break-if-!=
-804     return 1/true
-805   }
-806   compare g, 0x3d/equal
-807   {
-808     break-if-!=
-809     return 1/true
-810   }
-811   compare g, 0x3e/greater-than
-812   {
-813     break-if-!=
-814     return 1/true
-815   }
-816   # '?' is a symbol char
-817   compare g, 0x5c/backslash
-818   {
-819     break-if-!=
-820     return 1/true
-821   }
-822   compare g, 0x5e/caret
-823   {
-824     break-if-!=
-825     return 1/true
-826   }
-827   # '_' is a symbol char
-828   compare g, 0x7c/vertical-line
-829   {
-830     break-if-!=
-831     return 1/true
-832   }
-833   compare g, 0x7e/tilde
-834   {
-835     break-if-!=
-836     return 1/true
-837   }
-838   return 0/false
-839 }
-840 
-841 fn number-token? _in: (addr cell) -> _/eax: boolean {
-842   var in/eax: (addr cell) <- copy _in
-843   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-844   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
-845   rewind-stream in-data
-846   var g/eax: grapheme <- read-grapheme in-data
-847   var result/eax: boolean <- decimal-digit? g
-848   return result
-849 }
-850 
-851 fn bracket-token? _in: (addr cell) -> _/eax: boolean {
-852   var in/eax: (addr cell) <- copy _in
-853   {
-854     var in-type/eax: (addr int) <- get in, type
-855     compare *in-type, 3/stream
-856     break-if-!=
-857     # streams are never paren tokens
-858     return 0/false
-859   }
-860   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-861   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
-862   rewind-stream in-data
-863   var g/eax: grapheme <- read-grapheme in-data
-864   var result/eax: boolean <- bracket-grapheme? g
-865   return result
-866 }
-867 
-868 fn quote-token? _in: (addr cell) -> _/eax: boolean {
-869   var in/eax: (addr cell) <- copy _in
-870   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-871   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
-872   rewind-stream in-data
-873   var result/eax: boolean <- stream-data-equal? in-data, "'"
-874   return result
-875 }
-876 
-877 fn backquote-token? _in: (addr cell) -> _/eax: boolean {
-878   var in/eax: (addr cell) <- copy _in
-879   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-880   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
-881   rewind-stream in-data
-882   var result/eax: boolean <- stream-data-equal? in-data, "`"
-883   return result
-884 }
-885 
-886 fn unquote-token? _in: (addr cell) -> _/eax: boolean {
-887   var in/eax: (addr cell) <- copy _in
-888   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-889   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
-890   rewind-stream in-data
-891   var result/eax: boolean <- stream-data-equal? in-data, ","
-892   return result
-893 }
-894 
-895 fn unquote-splice-token? _in: (addr cell) -> _/eax: boolean {
-896   var in/eax: (addr cell) <- copy _in
-897   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-898   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
-899   rewind-stream in-data
-900   var result/eax: boolean <- stream-data-equal? in-data, ",@"
-901   return result
-902 }
-903 
-904 fn open-paren-token? _in: (addr cell) -> _/eax: boolean {
-905   var in/eax: (addr cell) <- copy _in
-906   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-907   var _in-data/eax: (addr stream byte) <- lookup *in-data-ah
-908   var in-data/ecx: (addr stream byte) <- copy _in-data
-909   rewind-stream in-data
-910   var g/eax: grapheme <- read-grapheme in-data
-911   compare g, 0x28/open-paren
-912   {
-913     break-if-!=
-914     var result/eax: boolean <- stream-empty? in-data
-915     return result
-916   }
-917   return 0/false
-918 }
-919 
-920 fn close-paren-token? _in: (addr cell) -> _/eax: boolean {
-921   var in/eax: (addr cell) <- copy _in
-922   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-923   var _in-data/eax: (addr stream byte) <- lookup *in-data-ah
-924   var in-data/ecx: (addr stream byte) <- copy _in-data
-925   rewind-stream in-data
-926   var g/eax: grapheme <- read-grapheme in-data
-927   compare g, 0x29/close-paren
-928   {
-929     break-if-!=
-930     var result/eax: boolean <- stream-empty? in-data
-931     return result
-932   }
-933   return 0/false
-934 }
-935 
-936 fn dot-token? _in: (addr cell) -> _/eax: boolean {
-937   var in/eax: (addr cell) <- copy _in
-938   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-939   var _in-data/eax: (addr stream byte) <- lookup *in-data-ah
-940   var in-data/ecx: (addr stream byte) <- copy _in-data
-941   rewind-stream in-data
-942   var g/eax: grapheme <- read-grapheme in-data
-943   compare g, 0x2e/dot
-944   {
-945     break-if-!=
-946     var result/eax: boolean <- stream-empty? in-data
-947     return result
-948   }
-949   return 0/false
-950 }
-951 
-952 fn test-dot-token {
-953   var tmp-storage: (handle cell)
-954   var tmp-ah/eax: (addr handle cell) <- address tmp-storage
-955   new-symbol tmp-ah, "."
-956   var tmp/eax: (addr cell) <- lookup *tmp-ah
-957   var result/eax: boolean <- dot-token? tmp
-958   check result, "F - test-dot-token"
-959 }
-960 
-961 fn stream-token? _in: (addr cell) -> _/eax: boolean {
-962   var in/eax: (addr cell) <- copy _in
-963   var in-type/eax: (addr int) <- get in, type
-964   compare *in-type, 3/stream
-965   {
-966     break-if-=
-967     return 0/false
-968   }
-969   return 1/true
-970 }
-971 
-972 fn comment-token? _in: (addr cell) -> _/eax: boolean {
-973   var in/eax: (addr cell) <- copy _in
-974   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
-975   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
-976   rewind-stream in-data
-977   var g/eax: grapheme <- read-grapheme in-data
-978   compare g, 0x23/hash
-979   {
-980     break-if-=
-981     return 0/false
-982   }
-983   return 1/true
-984 }
+   1 # We reuse the cell data structure for tokenization
+   2 # Token cells are special, though. They have no type, they're always atoms,
+   3 # they always have text-data.
+   4 
+   5 fn tokenize in: (addr gap-buffer), out: (addr stream cell), trace: (addr trace) {
+   6   trace-text trace, "tokenize", "tokenize"
+   7   trace-lower trace
+   8   rewind-gap-buffer in
+   9   var token-storage: cell
+  10   var token/edx: (addr cell) <- address token-storage
+  11   {
+  12     skip-whitespace-from-gap-buffer in
+  13     var done?/eax: boolean <- gap-buffer-scan-done? in
+  14     compare done?, 0/false
+  15     break-if-!=
+  16     #
+  17     next-token in, token, trace
+  18     var error?/eax: boolean <- has-errors? trace
+  19     compare error?, 0/false
+  20     {
+  21       break-if-=
+  22       return
+  23     }
+  24     var skip?/eax: boolean <- comment-token? token
+  25     compare skip?, 0/false
+  26     loop-if-!=
+  27     write-to-stream out, token  # shallow-copy text-data
+  28     loop
+  29   }
+  30   trace-higher trace
+  31 }
+  32 
+  33 fn test-tokenize-number {
+  34   var in-storage: gap-buffer
+  35   var in/esi: (addr gap-buffer) <- address in-storage
+  36   initialize-gap-buffer-with in, "123 a"
+  37   #
+  38   var stream-storage: (stream cell 0x10)
+  39   var stream/edi: (addr stream cell) <- address stream-storage
+  40   #
+  41   var trace-storage: trace
+  42   var trace/edx: (addr trace) <- address trace-storage
+  43   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+  44   tokenize in, stream, trace
+  45   #
+  46   var curr-token-storage: cell
+  47   var curr-token/ebx: (addr cell) <- address curr-token-storage
+  48   read-from-stream stream, curr-token
+  49   var number?/eax: boolean <- number-token? curr-token
+  50   check number?, "F - test-tokenize-number"
+  51   var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
+  52   var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
+  53   check-stream-equal curr-token-data, "123", "F - test-tokenize-number: value"
+  54 }
+  55 
+  56 fn test-tokenize-negative-number {
+  57   var in-storage: gap-buffer
+  58   var in/esi: (addr gap-buffer) <- address in-storage
+  59   initialize-gap-buffer-with in, "-123 a"
+  60   #
+  61   var stream-storage: (stream cell 0x10)
+  62   var stream/edi: (addr stream cell) <- address stream-storage
+  63   #
+  64   var trace-storage: trace
+  65   var trace/edx: (addr trace) <- address trace-storage
+  66   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+  67   tokenize in, stream, trace
+  68   #
+  69   var curr-token-storage: cell
+  70   var curr-token/ebx: (addr cell) <- address curr-token-storage
+  71   read-from-stream stream, curr-token
+  72   var number?/eax: boolean <- number-token? curr-token
+  73   check number?, "F - test-tokenize-negative-number"
+  74   var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
+  75   var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
+  76   check-stream-equal curr-token-data, "-123", "F - test-tokenize-negative-number: value"
+  77 }
+  78 
+  79 fn test-tokenize-number-followed-by-hyphen {
+  80   var in-storage: gap-buffer
+  81   var in/esi: (addr gap-buffer) <- address in-storage
+  82   initialize-gap-buffer-with in, "123-4 a"
+  83   #
+  84   var stream-storage: (stream cell 0x10)
+  85   var stream/edi: (addr stream cell) <- address stream-storage
+  86   #
+  87   var trace-storage: trace
+  88   var trace/edx: (addr trace) <- address trace-storage
+  89   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+  90   tokenize in, stream, trace
+  91   #
+  92   var curr-token-storage: cell
+  93   var curr-token/ebx: (addr cell) <- address curr-token-storage
+  94   read-from-stream stream, curr-token
+  95   var number?/eax: boolean <- number-token? curr-token
+  96   check number?, "F - test-tokenize-number-followed-by-hyphen"
+  97   var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
+  98   var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
+  99   check-stream-equal curr-token-data, "123", "F - test-tokenize-number-followed-by-hyphen: value"
+ 100 }
+ 101 
+ 102 fn test-tokenize-quote {
+ 103   var in-storage: gap-buffer
+ 104   var in/esi: (addr gap-buffer) <- address in-storage
+ 105   initialize-gap-buffer-with in, "'(a)"
+ 106   #
+ 107   var stream-storage: (stream cell 0x10)
+ 108   var stream/edi: (addr stream cell) <- address stream-storage
+ 109   #
+ 110   var trace-storage: trace
+ 111   var trace/edx: (addr trace) <- address trace-storage
+ 112   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 113   tokenize in, stream, trace
+ 114   #
+ 115   var curr-token-storage: cell
+ 116   var curr-token/ebx: (addr cell) <- address curr-token-storage
+ 117   read-from-stream stream, curr-token
+ 118   var quote?/eax: boolean <- quote-token? curr-token
+ 119   check quote?, "F - test-tokenize-quote: quote"
+ 120   read-from-stream stream, curr-token
+ 121   var open-paren?/eax: boolean <- open-paren-token? curr-token
+ 122   check open-paren?, "F - test-tokenize-quote: open paren"
+ 123   read-from-stream stream, curr-token  # skip a
+ 124   read-from-stream stream, curr-token
+ 125   var close-paren?/eax: boolean <- close-paren-token? curr-token
+ 126   check close-paren?, "F - test-tokenize-quote: close paren"
+ 127 }
+ 128 
+ 129 fn test-tokenize-backquote {
+ 130   var in-storage: gap-buffer
+ 131   var in/esi: (addr gap-buffer) <- address in-storage
+ 132   initialize-gap-buffer-with in, "`(a)"
+ 133   #
+ 134   var stream-storage: (stream cell 0x10)
+ 135   var stream/edi: (addr stream cell) <- address stream-storage
+ 136   #
+ 137   var trace-storage: trace
+ 138   var trace/edx: (addr trace) <- address trace-storage
+ 139   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 140   tokenize in, stream, trace
+ 141   #
+ 142   var curr-token-storage: cell
+ 143   var curr-token/ebx: (addr cell) <- address curr-token-storage
+ 144   read-from-stream stream, curr-token
+ 145   var backquote?/eax: boolean <- backquote-token? curr-token
+ 146   check backquote?, "F - test-tokenize-backquote: backquote"
+ 147   read-from-stream stream, curr-token
+ 148   var open-paren?/eax: boolean <- open-paren-token? curr-token
+ 149   check open-paren?, "F - test-tokenize-backquote: open paren"
+ 150   read-from-stream stream, curr-token  # skip a
+ 151   read-from-stream stream, curr-token
+ 152   var close-paren?/eax: boolean <- close-paren-token? curr-token
+ 153   check close-paren?, "F - test-tokenize-backquote: close paren"
+ 154 }
+ 155 
+ 156 fn test-tokenize-unquote {
+ 157   var in-storage: gap-buffer
+ 158   var in/esi: (addr gap-buffer) <- address in-storage
+ 159   initialize-gap-buffer-with in, ",(a)"
+ 160   #
+ 161   var stream-storage: (stream cell 0x10)
+ 162   var stream/edi: (addr stream cell) <- address stream-storage
+ 163   #
+ 164   var trace-storage: trace
+ 165   var trace/edx: (addr trace) <- address trace-storage
+ 166   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 167   tokenize in, stream, trace
+ 168   #
+ 169   var curr-token-storage: cell
+ 170   var curr-token/ebx: (addr cell) <- address curr-token-storage
+ 171   read-from-stream stream, curr-token
+ 172   var unquote?/eax: boolean <- unquote-token? curr-token
+ 173   check unquote?, "F - test-tokenize-unquote: unquote"
+ 174   read-from-stream stream, curr-token
+ 175   var open-paren?/eax: boolean <- open-paren-token? curr-token
+ 176   check open-paren?, "F - test-tokenize-unquote: open paren"
+ 177   read-from-stream stream, curr-token  # skip a
+ 178   read-from-stream stream, curr-token
+ 179   var close-paren?/eax: boolean <- close-paren-token? curr-token
+ 180   check close-paren?, "F - test-tokenize-unquote: close paren"
+ 181 }
+ 182 
+ 183 fn test-tokenize-unquote-splice {
+ 184   var in-storage: gap-buffer
+ 185   var in/esi: (addr gap-buffer) <- address in-storage
+ 186   initialize-gap-buffer-with in, ",@a"
+ 187   #
+ 188   var stream-storage: (stream cell 0x10)
+ 189   var stream/edi: (addr stream cell) <- address stream-storage
+ 190   #
+ 191   var trace-storage: trace
+ 192   var trace/edx: (addr trace) <- address trace-storage
+ 193   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 194   tokenize in, stream, trace
+ 195   #
+ 196   var curr-token-storage: cell
+ 197   var curr-token/ebx: (addr cell) <- address curr-token-storage
+ 198   read-from-stream stream, curr-token
+ 199   var unquote-splice?/eax: boolean <- unquote-splice-token? curr-token
+ 200   check unquote-splice?, "F - test-tokenize-unquote-splice: unquote-splice"
+ 201 }
+ 202 
+ 203 fn test-tokenize-dotted-list {
+ 204   var in-storage: gap-buffer
+ 205   var in/esi: (addr gap-buffer) <- address in-storage
+ 206   initialize-gap-buffer-with in, "(a . b)"
+ 207   #
+ 208   var stream-storage: (stream cell 0x10)
+ 209   var stream/edi: (addr stream cell) <- address stream-storage
+ 210   #
+ 211   var trace-storage: trace
+ 212   var trace/edx: (addr trace) <- address trace-storage
+ 213   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 214   tokenize in, stream, trace
+ 215   #
+ 216   var curr-token-storage: cell
+ 217   var curr-token/ebx: (addr cell) <- address curr-token-storage
+ 218   read-from-stream stream, curr-token
+ 219   var open-paren?/eax: boolean <- open-paren-token? curr-token
+ 220   check open-paren?, "F - test-tokenize-dotted-list: open paren"
+ 221   read-from-stream stream, curr-token  # skip a
+ 222   read-from-stream stream, curr-token
+ 223   var dot?/eax: boolean <- dot-token? curr-token
+ 224   check dot?, "F - test-tokenize-dotted-list: dot"
+ 225   read-from-stream stream, curr-token  # skip b
+ 226   read-from-stream stream, curr-token
+ 227   var close-paren?/eax: boolean <- close-paren-token? curr-token
+ 228   check close-paren?, "F - test-tokenize-dotted-list: close paren"
+ 229 }
+ 230 
+ 231 fn test-tokenize-stream-literal {
+ 232   var in-storage: gap-buffer
+ 233   var in/esi: (addr gap-buffer) <- address in-storage
+ 234   initialize-gap-buffer-with in, "[abc def]"
+ 235   #
+ 236   var stream-storage: (stream cell 0x10)
+ 237   var stream/edi: (addr stream cell) <- address stream-storage
+ 238   #
+ 239   var trace-storage: trace
+ 240   var trace/edx: (addr trace) <- address trace-storage
+ 241   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 242   tokenize in, stream, trace
+ 243   #
+ 244   var curr-token-storage: cell
+ 245   var curr-token/ebx: (addr cell) <- address curr-token-storage
+ 246   read-from-stream stream, curr-token
+ 247   var stream?/eax: boolean <- stream-token? curr-token
+ 248   check stream?, "F - test-tokenize-stream-literal: type"
+ 249   var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
+ 250   var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
+ 251   var data-equal?/eax: boolean <- stream-data-equal? curr-token-data, "abc def"
+ 252   check data-equal?, "F - test-tokenize-stream-literal"
+ 253   var empty?/eax: boolean <- stream-empty? stream
+ 254   check empty?, "F - test-tokenize-stream-literal: empty?"
+ 255 }
+ 256 
+ 257 fn test-tokenize-stream-literal-in-tree {
+ 258   var in-storage: gap-buffer
+ 259   var in/esi: (addr gap-buffer) <- address in-storage
+ 260   initialize-gap-buffer-with in, "([abc def])"
+ 261   #
+ 262   var stream-storage: (stream cell 0x10)
+ 263   var stream/edi: (addr stream cell) <- address stream-storage
+ 264   #
+ 265   var trace-storage: trace
+ 266   var trace/edx: (addr trace) <- address trace-storage
+ 267   initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
+ 268   tokenize in, stream, trace
+ 269   #
+ 270   var curr-token-storage: cell
+ 271   var curr-token/ebx: (addr cell) <- address curr-token-storage
+ 272   read-from-stream stream, curr-token
+ 273   var bracket?/eax: boolean <- bracket-token? curr-token
+ 274   check bracket?, "F - test-tokenize-stream-literal-in-tree: open paren"
+ 275   read-from-stream stream, curr-token
+ 276   var stream?/eax: boolean <- stream-token? curr-token
+ 277   check stream?, "F - test-tokenize-stream-literal-in-tree: type"
+ 278   var curr-token-data-ah/eax: (addr handle stream byte) <- get curr-token, text-data
+ 279   var curr-token-data/eax: (addr stream byte) <- lookup *curr-token-data-ah
+ 280   var data-equal?/eax: boolean <- stream-data-equal? curr-token-data, "abc def"
+ 281   check data-equal?, "F - test-tokenize-stream-literal-in-tree"
+ 282   read-from-stream stream, curr-token
+ 283   var bracket?/eax: boolean <- bracket-token? curr-token
+ 284   check bracket?, "F - test-tokenize-stream-literal-in-tree: close paren"
+ 285   var empty?/eax: boolean <- stream-empty? stream
+ 286   check empty?, "F - test-tokenize-stream-literal-in-tree: empty?"
+ 287 }
+ 288 
+ 289 fn next-token in: (addr gap-buffer), _out-cell: (addr cell), trace: (addr trace) {
+ 290   trace-text trace, "tokenize", "next-token"
+ 291   trace-lower trace
+ 292   var _g/eax: grapheme <- peek-from-gap-buffer in
+ 293   var g/ecx: grapheme <- copy _g
+ 294   {
+ 295     var should-trace?/eax: boolean <- should-trace? trace
+ 296     compare should-trace?, 0/false
+ 297     break-if-=
+ 298     var stream-storage: (stream byte 0x40)
+ 299     var stream/esi: (addr stream byte) <- address stream-storage
+ 300     write stream, "next: "
+ 301     var gval/eax: int <- copy g
+ 302     write-int32-hex stream, gval
+ 303     trace trace, "tokenize", stream
+ 304   }
+ 305   var out-cell/eax: (addr cell) <- copy _out-cell
+ 306   {
+ 307     var out-cell-type/eax: (addr int) <- get out-cell, type
+ 308     copy-to *out-cell-type, 0/uninitialized
+ 309   }
+ 310   var out-ah/edi: (addr handle stream byte) <- get out-cell, text-data
+ 311   $next-token:allocate: {
+ 312     # Allocate a large buffer if it's a stream.
+ 313     # Sometimes a whole function definition will need to fit in it.
+ 314     compare g, 0x5b/open-square-bracket
+ 315     {
+ 316       break-if-!=
+ 317       populate-stream out-ah, 0x400/max-definition-size=1KB
+ 318       break $next-token:allocate
+ 319     }
+ 320     populate-stream out-ah, 0x40
+ 321   }
+ 322   var _out/eax: (addr stream byte) <- lookup *out-ah
+ 323   var out/edi: (addr stream byte) <- copy _out
+ 324   clear-stream out
+ 325   $next-token:case: {
+ 326     # open square brackets begin streams
+ 327     {
+ 328       compare g, 0x5b/open-square-bracket
+ 329       break-if-!=
+ 330       var dummy/eax: grapheme <- read-from-gap-buffer in  # skip open bracket
+ 331       next-stream-token in, out, trace
+ 332       var out-cell/eax: (addr cell) <- copy _out-cell
+ 333       # streams set the type
+ 334       var out-cell-type/eax: (addr int) <- get out-cell, type
+ 335       copy-to *out-cell-type, 3/stream
+ 336       break $next-token:case
+ 337     }
+ 338     # comment
+ 339     {
+ 340       compare g, 0x23/comment
+ 341       break-if-!=
+ 342       rest-of-line in, out, trace
+ 343       break $next-token:case
+ 344     }
+ 345     # special-case: '-'
+ 346     {
+ 347       compare g, 0x2d/minus
+ 348       break-if-!=
+ 349       var dummy/eax: grapheme <- read-from-gap-buffer in  # skip '-'
+ 350       var g2/eax: grapheme <- peek-from-gap-buffer in
+ 351       put-back-from-gap-buffer in
+ 352       var digit?/eax: boolean <- decimal-digit? g2
+ 353       compare digit?, 0/false
+ 354       break-if-=
+ 355       next-number-token in, out, trace
+ 356       break $next-token:case
+ 357     }
+ 358     # digit
+ 359     {
+ 360       var digit?/eax: boolean <- decimal-digit? g
+ 361       compare digit?, 0/false
+ 362       break-if-=
+ 363       next-number-token in, out, trace
+ 364       break $next-token:case
+ 365     }
+ 366     # other symbol char
+ 367     {
+ 368       var symbol?/eax: boolean <- symbol-grapheme? g
+ 369       compare symbol?, 0/false
+ 370       break-if-=
+ 371       next-symbol-token in, out, trace
+ 372       break $next-token:case
+ 373     }
+ 374     # unbalanced close square brackets are errors
+ 375     {
+ 376       compare g, 0x5d/close-square-bracket
+ 377       break-if-!=
+ 378       error trace, "unbalanced ']'"
+ 379       return
+ 380     }
+ 381     # other brackets are always single-char tokens
+ 382     {
+ 383       var bracket?/eax: boolean <- bracket-grapheme? g
+ 384       compare bracket?, 0/false
+ 385       break-if-=
+ 386       var g/eax: grapheme <- read-from-gap-buffer in
+ 387       next-bracket-token g, out, trace
+ 388       break $next-token:case
+ 389     }
+ 390     # non-symbol operators
+ 391     {
+ 392       var operator?/eax: boolean <- operator-grapheme? g
+ 393       compare operator?, 0/false
+ 394       break-if-=
+ 395       next-operator-token in, out, trace
+ 396       break $next-token:case
+ 397     }
+ 398     # quote
+ 399     {
+ 400       compare g, 0x27/single-quote
+ 401       break-if-!=
+ 402       var g/eax: grapheme <- read-from-gap-buffer in  # consume
+ 403       write-grapheme out, g
+ 404       break $next-token:case
+ 405     }
+ 406     # backquote
+ 407     {
+ 408       compare g, 0x60/backquote
+ 409       break-if-!=
+ 410       var g/eax: grapheme <- read-from-gap-buffer in  # consume
+ 411       write-grapheme out, g
+ 412       break $next-token:case
+ 413     }
+ 414     # unquote
+ 415     {
+ 416       compare g, 0x2c/comma
+ 417       break-if-!=
+ 418       var g/eax: grapheme <- read-from-gap-buffer in  # consume
+ 419       write-grapheme out, g
+ 420       # check for unquote-splice
+ 421       {
+ 422         var g2/eax: grapheme <- peek-from-gap-buffer in
+ 423         compare g2, 0x40/at-sign
+ 424         break-if-!=
+ 425         g2 <- read-from-gap-buffer in
+ 426         write-grapheme out, g2
+ 427       }
+ 428       break $next-token:case
+ 429     }
+ 430     abort "unknown token type"
+ 431   }
+ 432   trace-higher trace
+ 433   {
+ 434     var should-trace?/eax: boolean <- should-trace? trace
+ 435     compare should-trace?, 0/false
+ 436     break-if-=
+ 437     var stream-storage: (stream byte 0x400)  # maximum possible token size (next-stream-token)
+ 438     var stream/eax: (addr stream byte) <- address stream-storage
+ 439     write stream, "=> "
+ 440     rewind-stream out
+ 441     write-stream stream, out
+ 442     trace trace, "tokenize", stream
+ 443   }
+ 444 }
+ 445 
+ 446 fn next-symbol-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
+ 447   trace-text trace, "tokenize", "looking for a symbol"
+ 448   trace-lower trace
+ 449   $next-symbol-token:loop: {
+ 450     var done?/eax: boolean <- gap-buffer-scan-done? in
+ 451     compare done?, 0/false
+ 452     break-if-!=
+ 453     var g/eax: grapheme <- peek-from-gap-buffer in
+ 454     {
+ 455       {
+ 456         var should-trace?/eax: boolean <- should-trace? trace
+ 457         compare should-trace?, 0/false
+ 458       }
+ 459       break-if-=
+ 460       var stream-storage: (stream byte 0x40)
+ 461       var stream/esi: (addr stream byte) <- address stream-storage
+ 462       write stream, "next: "
+ 463       var gval/eax: int <- copy g
+ 464       write-int32-hex stream, gval
+ 465       trace trace, "tokenize", stream
+ 466     }
+ 467     # if non-symbol, return
+ 468     {
+ 469       var symbol-grapheme?/eax: boolean <- symbol-grapheme? g
+ 470       compare symbol-grapheme?, 0/false
+ 471       break-if-!=
+ 472       trace-text trace, "tokenize", "stop"
+ 473       break $next-symbol-token:loop
+ 474     }
+ 475     var g/eax: grapheme <- read-from-gap-buffer in
+ 476     write-grapheme out, g
+ 477     loop
+ 478   }
+ 479   trace-higher trace
+ 480   {
+ 481     var should-trace?/eax: boolean <- should-trace? trace
+ 482     compare should-trace?, 0/false
+ 483     break-if-=
+ 484     var stream-storage: (stream byte 0x40)
+ 485     var stream/esi: (addr stream byte) <- address stream-storage
+ 486     write stream, "=> "
+ 487     rewind-stream out
+ 488     write-stream stream, out
+ 489     trace trace, "tokenize", stream
+ 490   }
+ 491 }
+ 492 
+ 493 fn next-operator-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
+ 494   trace-text trace, "tokenize", "looking for a operator"
+ 495   trace-lower trace
+ 496   $next-operator-token:loop: {
+ 497     var done?/eax: boolean <- gap-buffer-scan-done? in
+ 498     compare done?, 0/false
+ 499     break-if-!=
+ 500     var g/eax: grapheme <- peek-from-gap-buffer in
+ 501     {
+ 502       {
+ 503         var should-trace?/eax: boolean <- should-trace? trace
+ 504         compare should-trace?, 0/false
+ 505       }
+ 506       break-if-=
+ 507       var stream-storage: (stream byte 0x40)
+ 508       var stream/esi: (addr stream byte) <- address stream-storage
+ 509       write stream, "next: "
+ 510       var gval/eax: int <- copy g
+ 511       write-int32-hex stream, gval
+ 512       trace trace, "tokenize", stream
+ 513     }
+ 514     # if non-operator, return
+ 515     {
+ 516       var operator-grapheme?/eax: boolean <- operator-grapheme? g
+ 517       compare operator-grapheme?, 0/false
+ 518       break-if-!=
+ 519       trace-text trace, "tokenize", "stop"
+ 520       break $next-operator-token:loop
+ 521     }
+ 522     var g/eax: grapheme <- read-from-gap-buffer in
+ 523     write-grapheme out, g
+ 524     loop
+ 525   }
+ 526   trace-higher trace
+ 527   {
+ 528     var should-trace?/eax: boolean <- should-trace? trace
+ 529     compare should-trace?, 0/false
+ 530     break-if-=
+ 531     var stream-storage: (stream byte 0x40)
+ 532     var stream/esi: (addr stream byte) <- address stream-storage
+ 533     write stream, "=> "
+ 534     rewind-stream out
+ 535     write-stream stream, out
+ 536     trace trace, "tokenize", stream
+ 537   }
+ 538 }
+ 539 
+ 540 fn next-number-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
+ 541   trace-text trace, "tokenize", "looking for a number"
+ 542   trace-lower trace
+ 543   $next-number-token:check-minus: {
+ 544     var g/eax: grapheme <- peek-from-gap-buffer in
+ 545     compare g, 0x2d/minus
+ 546     g <- read-from-gap-buffer in  # consume
+ 547     write-grapheme out, g
+ 548   }
+ 549   $next-number-token:loop: {
+ 550     var done?/eax: boolean <- gap-buffer-scan-done? in
+ 551     compare done?, 0/false
+ 552     break-if-!=
+ 553     var g/eax: grapheme <- peek-from-gap-buffer in
+ 554     {
+ 555       {
+ 556         var should-trace?/eax: boolean <- should-trace? trace
+ 557         compare should-trace?, 0/false
+ 558       }
+ 559       break-if-=
+ 560       var stream-storage: (stream byte 0x40)
+ 561       var stream/esi: (addr stream byte) <- address stream-storage
+ 562       write stream, "next: "
+ 563       var gval/eax: int <- copy g
+ 564       write-int32-hex stream, gval
+ 565       trace trace, "tokenize", stream
+ 566     }
+ 567     # if not symbol grapheme, return
+ 568     {
+ 569       var symbol-grapheme?/eax: boolean <- symbol-grapheme? g
+ 570       compare symbol-grapheme?, 0/false
+ 571       break-if-!=
+ 572       trace-text trace, "tokenize", "stop"
+ 573       break $next-number-token:loop
+ 574     }
+ 575     # if not digit grapheme, abort
+ 576     {
+ 577       var digit?/eax: boolean <- decimal-digit? g
+ 578       compare digit?, 0/false
+ 579       break-if-!=
+ 580       error trace, "invalid number"
+ 581       return
+ 582     }
+ 583     trace-text trace, "tokenize", "append"
+ 584     var g/eax: grapheme <- read-from-gap-buffer in
+ 585     write-grapheme out, g
+ 586     loop
+ 587   }
+ 588   trace-higher trace
+ 589 }
+ 590 
+ 591 fn next-stream-token in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
+ 592   trace-text trace, "tokenize", "stream"
+ 593   {
+ 594     var empty?/eax: boolean <- gap-buffer-scan-done? in
+ 595     compare empty?, 0/false
+ 596     {
+ 597       break-if-=
+ 598       error trace, "unbalanced '['"
+ 599       return
+ 600     }
+ 601     var g/eax: grapheme <- read-from-gap-buffer in
+ 602     compare g, 0x5d/close-square-bracket
+ 603     break-if-=
+ 604     write-grapheme out, g
+ 605     loop
+ 606   }
+ 607   {
+ 608     var should-trace?/eax: boolean <- should-trace? trace
+ 609     compare should-trace?, 0/false
+ 610     break-if-=
+ 611     var stream-storage: (stream byte 0x400)  # max-definition-size
+ 612     var stream/esi: (addr stream byte) <- address stream-storage
+ 613     write stream, "=> "
+ 614     rewind-stream out
+ 615     write-stream stream, out
+ 616     trace trace, "tokenize", stream
+ 617   }
+ 618 }
+ 619 
+ 620 fn next-bracket-token g: grapheme, out: (addr stream byte), trace: (addr trace) {
+ 621   trace-text trace, "tokenize", "bracket"
+ 622   write-grapheme out, g
+ 623   {
+ 624     var should-trace?/eax: boolean <- should-trace? trace
+ 625     compare should-trace?, 0/false
+ 626     break-if-=
+ 627     var stream-storage: (stream byte 0x40)
+ 628     var stream/esi: (addr stream byte) <- address stream-storage
+ 629     write stream, "=> "
+ 630     rewind-stream out
+ 631     write-stream stream, out
+ 632     trace trace, "tokenize", stream
+ 633   }
+ 634 }
+ 635 
+ 636 fn rest-of-line in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
+ 637   trace-text trace, "tokenize", "comment"
+ 638   {
+ 639     var empty?/eax: boolean <- gap-buffer-scan-done? in
+ 640     compare empty?, 0/false
+ 641     {
+ 642       break-if-=
+ 643       return
+ 644     }
+ 645     var g/eax: grapheme <- read-from-gap-buffer in
+ 646     compare g, 0xa/newline
+ 647     break-if-=
+ 648     write-grapheme out, g
+ 649     loop
+ 650   }
+ 651   {
+ 652     var should-trace?/eax: boolean <- should-trace? trace
+ 653     compare should-trace?, 0/false
+ 654     break-if-=
+ 655     var stream-storage: (stream byte 0x80)
+ 656     var stream/esi: (addr stream byte) <- address stream-storage
+ 657     write stream, "=> "
+ 658     rewind-stream out
+ 659     write-stream stream, out
+ 660     trace trace, "tokenize", stream
+ 661   }
+ 662 }
+ 663 
+ 664 fn symbol-grapheme? g: grapheme -> _/eax: boolean {
+ 665   ## whitespace
+ 666   compare g, 9/tab
+ 667   {
+ 668     break-if-!=
+ 669     return 0/false
+ 670   }
+ 671   compare g, 0xa/newline
+ 672   {
+ 673     break-if-!=
+ 674     return 0/false
+ 675   }
+ 676   compare g, 0x20/space
+ 677   {
+ 678     break-if-!=
+ 679     return 0/false
+ 680   }
+ 681   ## quotes
+ 682   compare g, 0x22/double-quote
+ 683   {
+ 684     break-if-!=
+ 685     return 0/false
+ 686   }
+ 687   compare g, 0x60/backquote
+ 688   {
+ 689     break-if-!=
+ 690     return 0/false
+ 691   }
+ 692   ## brackets
+ 693   compare g, 0x28/open-paren
+ 694   {
+ 695     break-if-!=
+ 696     return 0/false
+ 697   }
+ 698   compare g, 0x29/close-paren
+ 699   {
+ 700     break-if-!=
+ 701     return 0/false
+ 702   }
+ 703   compare g, 0x5b/open-square-bracket
+ 704   {
+ 705     break-if-!=
+ 706     return 0/false
+ 707   }
+ 708   compare g, 0x5d/close-square-bracket
+ 709   {
+ 710     break-if-!=
+ 711     return 0/false
+ 712   }
+ 713   compare g, 0x7b/open-curly-bracket
+ 714   {
+ 715     break-if-!=
+ 716     return 0/false
+ 717   }
+ 718   compare g, 0x7d/close-curly-bracket
+ 719   {
+ 720     break-if-!=
+ 721     return 0/false
+ 722   }
+ 723   # - other punctuation
+ 724   # '!' is a symbol char
+ 725   compare g, 0x23/hash
+ 726   {
+ 727     break-if-!=
+ 728     return 0/false
+ 729   }
+ 730   # '$' is a symbol char
+ 731   compare g, 0x25/percent
+ 732   {
+ 733     break-if-!=
+ 734     return 0/false
+ 735   }
+ 736   compare g, 0x26/ampersand
+ 737   {
+ 738     break-if-!=
+ 739     return 0/false
+ 740   }
+ 741   compare g, 0x27/single-quote
+ 742   {
+ 743     break-if-!=
+ 744     return 0/false
+ 745   }
+ 746   compare g, 0x60/backquote
+ 747   {
+ 748     break-if-!=
+ 749     return 0/false
+ 750   }
+ 751   compare g, 0x2c/comma
+ 752   {
+ 753     break-if-!=
+ 754     return 0/false
+ 755   }
+ 756   compare g, 0x40/at-sign
+ 757   {
+ 758     break-if-!=
+ 759     return 0/false
+ 760   }
+ 761   compare g, 0x2a/asterisk
+ 762   {
+ 763     break-if-!=
+ 764     return 0/false
+ 765   }
+ 766   compare g, 0x2b/plus
+ 767   {
+ 768     break-if-!=
+ 769     return 0/false
+ 770   }
+ 771   compare g, 0x2d/dash  # '-' not allowed in symbols
+ 772   {
+ 773     break-if-!=
+ 774     return 0/false
+ 775   }
+ 776   compare g, 0x2e/period
+ 777   {
+ 778     break-if-!=
+ 779     return 0/false
+ 780   }
+ 781   compare g, 0x2f/slash
+ 782   {
+ 783     break-if-!=
+ 784     return 0/false
+ 785   }
+ 786   compare g, 0x3a/colon
+ 787   {
+ 788     break-if-!=
+ 789     return 0/false
+ 790   }
+ 791   compare g, 0x3b/semi-colon
+ 792   {
+ 793     break-if-!=
+ 794     return 0/false
+ 795   }
+ 796   compare g, 0x3c/less-than
+ 797   {
+ 798     break-if-!=
+ 799     return 0/false
+ 800   }
+ 801   compare g, 0x3d/equal
+ 802   {
+ 803     break-if-!=
+ 804     return 0/false
+ 805   }
+ 806   compare g, 0x3e/greater-than
+ 807   {
+ 808     break-if-!=
+ 809     return 0/false
+ 810   }
+ 811   # '?' is a symbol char
+ 812   compare g, 0x5c/backslash
+ 813   {
+ 814     break-if-!=
+ 815     return 0/false
+ 816   }
+ 817   compare g, 0x5e/caret
+ 818   {
+ 819     break-if-!=
+ 820     return 0/false
+ 821   }
+ 822   # '_' is a symbol char
+ 823   compare g, 0x7c/vertical-line
+ 824   {
+ 825     break-if-!=
+ 826     return 0/false
+ 827   }
+ 828   compare g, 0x7e/tilde
+ 829   {
+ 830     break-if-!=
+ 831     return 0/false
+ 832   }
+ 833   return 1/true
+ 834 }
+ 835 
+ 836 fn bracket-grapheme? g: grapheme -> _/eax: boolean {
+ 837   compare g, 0x28/open-paren
+ 838   {
+ 839     break-if-!=
+ 840     return 1/true
+ 841   }
+ 842   compare g, 0x29/close-paren
+ 843   {
+ 844     break-if-!=
+ 845     return 1/true
+ 846   }
+ 847   compare g, 0x5b/open-square-bracket
+ 848   {
+ 849     break-if-!=
+ 850     return 1/true
+ 851   }
+ 852   compare g, 0x5d/close-square-bracket
+ 853   {
+ 854     break-if-!=
+ 855     return 1/true
+ 856   }
+ 857   compare g, 0x7b/open-curly-bracket
+ 858   {
+ 859     break-if-!=
+ 860     return 1/true
+ 861   }
+ 862   compare g, 0x7d/close-curly-bracket
+ 863   {
+ 864     break-if-!=
+ 865     return 1/true
+ 866   }
+ 867   return 0/false
+ 868 }
+ 869 
+ 870 fn operator-grapheme? g: grapheme -> _/eax: boolean {
+ 871   # '$' is a symbol char
+ 872   compare g, 0x25/percent
+ 873   {
+ 874     break-if-!=
+ 875     return 1/false
+ 876   }
+ 877   compare g, 0x26/ampersand
+ 878   {
+ 879     break-if-!=
+ 880     return 1/true
+ 881   }
+ 882   compare g, 0x27/single-quote
+ 883   {
+ 884     break-if-!=
+ 885     return 0/true
+ 886   }
+ 887   compare g, 0x60/backquote
+ 888   {
+ 889     break-if-!=
+ 890     return 0/false
+ 891   }
+ 892   compare g, 0x2c/comma
+ 893   {
+ 894     break-if-!=
+ 895     return 0/false
+ 896   }
+ 897   compare g, 0x40/at-sign
+ 898   {
+ 899     break-if-!=
+ 900     return 0/false
+ 901   }
+ 902   compare g, 0x2a/asterisk
+ 903   {
+ 904     break-if-!=
+ 905     return 1/true
+ 906   }
+ 907   compare g, 0x2b/plus
+ 908   {
+ 909     break-if-!=
+ 910     return 1/true
+ 911   }
+ 912   compare g, 0x2d/dash  # '-' not allowed in symbols
+ 913   {
+ 914     break-if-!=
+ 915     return 1/true
+ 916   }
+ 917   compare g, 0x2e/period
+ 918   {
+ 919     break-if-!=
+ 920     return 1/true
+ 921   }
+ 922   compare g, 0x2f/slash
+ 923   {
+ 924     break-if-!=
+ 925     return 1/true
+ 926   }
+ 927   compare g, 0x3a/colon
+ 928   {
+ 929     break-if-!=
+ 930     return 1/true
+ 931   }
+ 932   compare g, 0x3b/semi-colon
+ 933   {
+ 934     break-if-!=
+ 935     return 1/true
+ 936   }
+ 937   compare g, 0x3c/less-than
+ 938   {
+ 939     break-if-!=
+ 940     return 1/true
+ 941   }
+ 942   compare g, 0x3d/equal
+ 943   {
+ 944     break-if-!=
+ 945     return 1/true
+ 946   }
+ 947   compare g, 0x3e/greater-than
+ 948   {
+ 949     break-if-!=
+ 950     return 1/true
+ 951   }
+ 952   # '?' is a symbol char
+ 953   compare g, 0x5c/backslash
+ 954   {
+ 955     break-if-!=
+ 956     return 1/true
+ 957   }
+ 958   compare g, 0x5e/caret
+ 959   {
+ 960     break-if-!=
+ 961     return 1/true
+ 962   }
+ 963   # '_' is a symbol char
+ 964   compare g, 0x7c/vertical-line
+ 965   {
+ 966     break-if-!=
+ 967     return 1/true
+ 968   }
+ 969   compare g, 0x7e/tilde
+ 970   {
+ 971     break-if-!=
+ 972     return 1/true
+ 973   }
+ 974   return 0/false
+ 975 }
+ 976 
+ 977 fn number-token? _in: (addr cell) -> _/eax: boolean {
+ 978   var in/eax: (addr cell) <- copy _in
+ 979   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+ 980   var _in-data/eax: (addr stream byte) <- lookup *in-data-ah
+ 981   var in-data/ecx: (addr stream byte) <- copy _in-data
+ 982   rewind-stream in-data
+ 983   var g/eax: grapheme <- read-grapheme in-data
+ 984   # if '-', read another
+ 985   {
+ 986     compare g, 0x2d/minus
+ 987     break-if-!=
+ 988     g <- read-grapheme in-data
+ 989   }
+ 990   var result/eax: boolean <- decimal-digit? g
+ 991   return result
+ 992 }
+ 993 
+ 994 fn bracket-token? _in: (addr cell) -> _/eax: boolean {
+ 995   var in/eax: (addr cell) <- copy _in
+ 996   {
+ 997     var in-type/eax: (addr int) <- get in, type
+ 998     compare *in-type, 3/stream
+ 999     break-if-!=
+1000     # streams are never paren tokens
+1001     return 0/false
+1002   }
+1003   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1004   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1005   rewind-stream in-data
+1006   var g/eax: grapheme <- read-grapheme in-data
+1007   var result/eax: boolean <- bracket-grapheme? g
+1008   return result
+1009 }
+1010 
+1011 fn quote-token? _in: (addr cell) -> _/eax: boolean {
+1012   var in/eax: (addr cell) <- copy _in
+1013   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1014   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1015   rewind-stream in-data
+1016   var result/eax: boolean <- stream-data-equal? in-data, "'"
+1017   return result
+1018 }
+1019 
+1020 fn backquote-token? _in: (addr cell) -> _/eax: boolean {
+1021   var in/eax: (addr cell) <- copy _in
+1022   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1023   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1024   rewind-stream in-data
+1025   var result/eax: boolean <- stream-data-equal? in-data, "`"
+1026   return result
+1027 }
+1028 
+1029 fn unquote-token? _in: (addr cell) -> _/eax: boolean {
+1030   var in/eax: (addr cell) <- copy _in
+1031   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1032   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1033   rewind-stream in-data
+1034   var result/eax: boolean <- stream-data-equal? in-data, ","
+1035   return result
+1036 }
+1037 
+1038 fn unquote-splice-token? _in: (addr cell) -> _/eax: boolean {
+1039   var in/eax: (addr cell) <- copy _in
+1040   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1041   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1042   rewind-stream in-data
+1043   var result/eax: boolean <- stream-data-equal? in-data, ",@"
+1044   return result
+1045 }
+1046 
+1047 fn open-paren-token? _in: (addr cell) -> _/eax: boolean {
+1048   var in/eax: (addr cell) <- copy _in
+1049   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1050   var _in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1051   var in-data/ecx: (addr stream byte) <- copy _in-data
+1052   rewind-stream in-data
+1053   var g/eax: grapheme <- read-grapheme in-data
+1054   compare g, 0x28/open-paren
+1055   {
+1056     break-if-!=
+1057     var result/eax: boolean <- stream-empty? in-data
+1058     return result
+1059   }
+1060   return 0/false
+1061 }
+1062 
+1063 fn close-paren-token? _in: (addr cell) -> _/eax: boolean {
+1064   var in/eax: (addr cell) <- copy _in
+1065   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1066   var _in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1067   var in-data/ecx: (addr stream byte) <- copy _in-data
+1068   rewind-stream in-data
+1069   var g/eax: grapheme <- read-grapheme in-data
+1070   compare g, 0x29/close-paren
+1071   {
+1072     break-if-!=
+1073     var result/eax: boolean <- stream-empty? in-data
+1074     return result
+1075   }
+1076   return 0/false
+1077 }
+1078 
+1079 fn dot-token? _in: (addr cell) -> _/eax: boolean {
+1080   var in/eax: (addr cell) <- copy _in
+1081   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1082   var _in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1083   var in-data/ecx: (addr stream byte) <- copy _in-data
+1084   rewind-stream in-data
+1085   var g/eax: grapheme <- read-grapheme in-data
+1086   compare g, 0x2e/dot
+1087   {
+1088     break-if-!=
+1089     var result/eax: boolean <- stream-empty? in-data
+1090     return result
+1091   }
+1092   return 0/false
+1093 }
+1094 
+1095 fn test-dot-token {
+1096   var tmp-storage: (handle cell)
+1097   var tmp-ah/eax: (addr handle cell) <- address tmp-storage
+1098   new-symbol tmp-ah, "."
+1099   var tmp/eax: (addr cell) <- lookup *tmp-ah
+1100   var result/eax: boolean <- dot-token? tmp
+1101   check result, "F - test-dot-token"
+1102 }
+1103 
+1104 fn stream-token? _in: (addr cell) -> _/eax: boolean {
+1105   var in/eax: (addr cell) <- copy _in
+1106   var in-type/eax: (addr int) <- get in, type
+1107   compare *in-type, 3/stream
+1108   {
+1109     break-if-=
+1110     return 0/false
+1111   }
+1112   return 1/true
+1113 }
+1114 
+1115 fn comment-token? _in: (addr cell) -> _/eax: boolean {
+1116   var in/eax: (addr cell) <- copy _in
+1117   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
+1118   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
+1119   rewind-stream in-data
+1120   var g/eax: grapheme <- read-grapheme in-data
+1121   compare g, 0x23/hash
+1122   {
+1123     break-if-=
+1124     return 0/false
+1125   }
+1126   return 1/true
+1127 }
 
diff --git a/html/shell/trace.mu.html b/html/shell/trace.mu.html index 56a78d1f..6151a9de 100644 --- a/html/shell/trace.mu.html +++ b/html/shell/trace.mu.html @@ -17,6 +17,7 @@ a { color:inherit; } .LineNr { } .Delimiter { color: #c000c0; } .CommentedCode { color: #8a8a8a; } +.muRegEdx { color: #878700; } .muRegEbx { color: #8787af; } .muRegEsi { color: #87d787; } .muRegEdi { color: #87ffd7; } @@ -28,7 +29,6 @@ a { color:inherit; } .muComment { color: #005faf; } .muRegEax { color: #875f00; } .muRegEcx { color: #af875f; } -.muRegEdx { color: #878700; } --> @@ -239,7 +239,7 @@ if ('onhashchange' in window) { 173 write message, " - find a smaller sub-computation to test,\n" 174 write message, " - allocate more space to the trace in initialize-sandbox\n" 175 write message, " (shell/sandbox.mu), or\n" - 176 write message, " - move the computation to 'main' and run it using ctrl-r" + 176 write message, " - move the computation to 'main' and run it using ctrl-r" 177 initialize-trace-line 0/depth, "error", message, dest 178 increment *index-addr 179 return @@ -483,10 +483,10 @@ if ('onhashchange' in window) { 417 var i/edx: int <- copy 0 418 var max-addr/ebx: (addr int) <- get self, first-free 419 var max/ebx: int <- copy *max-addr - 420 $dump-trace:loop: { + 420 $dump-trace-with-label:loop: { 421 compare i, max 422 break-if->= - 423 $dump-trace:iter: { + 423 $dump-trace-with-label:iter: { 424 var offset/ebx: (offset trace-line) <- compute-offset trace, i 425 var curr/ebx: (addr trace-line) <- index trace, offset 426 var curr-label-ah/eax: (addr handle array byte) <- get curr, label @@ -554,11 +554,11 @@ if ('onhashchange' in window) { 488 { 489 var width/eax: int <- copy 0 490 var height/ecx: int <- copy 0 - 491 width, height <- screen-size screen + 491 width, height <- screen-size screen 492 compare width, 0x80 493 break-if-< $render-trace:render-depth 494 } - 495 set-cursor-position screen, 0x70/x, y + 495 set-cursor-position screen, 0x70/x, y 496 draw-text-rightward-from-cursor-over-full-screen screen, "trace depth: ", 0x17/fg, 0xc5/bg=blue-bg 497 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen, *max-depth, 0x7/fg, 0xc5/bg=blue-bg 498 } @@ -791,13 +791,13 @@ if ('onhashchange' in window) { 725 # setup: screen 726 var screen-on-stack: screen 727 var screen/edi: (addr screen) <- address screen-on-stack - 728 initialize-screen screen, 5/width, 4/height, 0/no-pixel-graphics + 728 initialize-screen screen, 5/width, 4/height, 0/no-pixel-graphics 729 # 730 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 5/xmax, 4/ymax, 0/no-cursor 731 # 732 check-ints-equal y, 0, "F - test-render-trace-empty/cursor" 733 check-screen-row screen, 0/y, " ", "F - test-render-trace-empty" - 734 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-render-trace-empty/bg" + 734 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-render-trace-empty/bg" 735 } 736 737 fn test-render-trace-empty-2 { @@ -807,13 +807,13 @@ if ('onhashchange' in window) { 741 # setup: screen 742 var screen-on-stack: screen 743 var screen/edi: (addr screen) <- address screen-on-stack - 744 initialize-screen screen, 5/width, 4/height, 0/no-pixel-graphics + 744 initialize-screen screen, 5/width, 4/height, 0/no-pixel-graphics 745 # 746 var y/ecx: int <- render-trace screen, t, 0/xmin, 2/ymin, 5/xmax, 4/ymax, 0/no-cursor # cursor below top row 747 # 748 check-ints-equal y, 2, "F - test-render-trace-empty-2/cursor" 749 check-screen-row screen, 2/y, " ", "F - test-render-trace-empty-2" - 750 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-render-trace-empty-2/bg" + 750 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-render-trace-empty-2/bg" 751 } 752 753 fn test-render-trace-empty-3 { @@ -823,15 +823,15 @@ if ('onhashchange' in window) { 757 # setup: screen 758 var screen-on-stack: screen 759 var screen/edi: (addr screen) <- address screen-on-stack - 760 initialize-screen screen, 5/width, 4/height, 0/no-pixel-graphics + 760 initialize-screen screen, 5/width, 4/height, 0/no-pixel-graphics 761 # 762 var y/ecx: int <- render-trace screen, t, 0/xmin, 2/ymin, 5/xmax, 4/ymax, 1/show-cursor # try show cursor 763 # still no cursor to show 764 check-ints-equal y, 2, "F - test-render-trace-empty-3/cursor" 765 check-screen-row screen, 1/y, " ", "F - test-render-trace-empty-3/line-above-cursor" - 766 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-render-trace-empty-3/bg-for-line-above-cursor" + 766 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-render-trace-empty-3/bg-for-line-above-cursor" 767 check-screen-row screen, 2/y, " ", "F - test-render-trace-empty-3" - 768 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-render-trace-empty-3/bg" + 768 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-render-trace-empty-3/bg" 769 } 770 771 fn test-render-trace-collapsed-by-default { @@ -842,7 +842,7 @@ if ('onhashchange' in window) { 776 # setup: screen 777 var screen-on-stack: screen 778 var screen/edi: (addr screen) <- address screen-on-stack - 779 initialize-screen screen, 5/width, 4/height, 0/no-pixel-graphics + 779 initialize-screen screen, 5/width, 4/height, 0/no-pixel-graphics 780 # 781 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 5/xmax, 4/ymax, 0/no-cursor 782 # @@ -858,7 +858,7 @@ if ('onhashchange' in window) { 792 # setup: screen 793 var screen-on-stack: screen 794 var screen/edi: (addr screen) <- address screen-on-stack - 795 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics + 795 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics 796 # 797 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 0/no-cursor 798 # @@ -876,7 +876,7 @@ if ('onhashchange' in window) { 810 # setup: screen 811 var screen-on-stack: screen 812 var screen/edi: (addr screen) <- address screen-on-stack - 813 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics + 813 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics 814 # 815 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 0/no-cursor 816 # @@ -895,7 +895,7 @@ if ('onhashchange' in window) { 829 # setup: screen 830 var screen-on-stack: screen 831 var screen/edi: (addr screen) <- address screen-on-stack - 832 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics + 832 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics 833 # 834 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 0/no-cursor 835 # @@ -915,7 +915,7 @@ if ('onhashchange' in window) { 849 # setup: screen 850 var screen-on-stack: screen 851 var screen/edi: (addr screen) <- address screen-on-stack - 852 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics + 852 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics 853 # 854 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 0/no-cursor 855 # @@ -936,30 +936,30 @@ if ('onhashchange' in window) { 870 # setup: screen 871 var screen-on-stack: screen 872 var screen/edi: (addr screen) <- address screen-on-stack - 873 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics + 873 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics 874 # 875 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 1/show-cursor 876 # 877 check-screen-row screen, 0/y, "... ", "F - test-render-trace-cursor-in-single-line/0" - 878 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-render-trace-cursor-in-single-line/0/cursor" + 878 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-render-trace-cursor-in-single-line/0/cursor" 879 check-screen-row screen, 1/y, "error ", "F - test-render-trace-cursor-in-single-line/1" - 880 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-render-trace-cursor-in-single-line/1/cursor" + 880 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-render-trace-cursor-in-single-line/1/cursor" 881 check-screen-row screen, 2/y, "... ", "F - test-render-trace-cursor-in-single-line/2" - 882 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-render-trace-cursor-in-single-line/2/cursor" + 882 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-render-trace-cursor-in-single-line/2/cursor" 883 } 884 885 fn render-trace-menu screen: (addr screen) { 886 var width/eax: int <- copy 0 887 var height/ecx: int <- copy 0 - 888 width, height <- screen-size screen + 888 width, height <- screen-size screen 889 var y/ecx: int <- copy height 890 y <- decrement 891 var height/edx: int <- copy y 892 height <- increment - 893 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg - 894 set-cursor-position screen, 0/x, y + 893 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg + 894 set-cursor-position screen, 0/x, y 895 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight - 896 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg + 896 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg 897 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight 898 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg 899 draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 3/bg=keyboard @@ -1242,36 +1242,36 @@ if ('onhashchange' in window) { 1176 # setup: screen 1177 var screen-on-stack: screen 1178 var screen/edi: (addr screen) <- address screen-on-stack -1179 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics +1179 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics 1180 # 1181 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 1/show-cursor 1182 # 1183 check-screen-row screen, 0/y, "... ", "F - test-cursor-down-and-up-within-trace/pre-0" -1184 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-cursor-down-and-up-within-trace/pre-0/cursor" +1184 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-cursor-down-and-up-within-trace/pre-0/cursor" 1185 check-screen-row screen, 1/y, "error ", "F - test-cursor-down-and-up-within-trace/pre-1" -1186 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-cursor-down-and-up-within-trace/pre-1/cursor" +1186 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-cursor-down-and-up-within-trace/pre-1/cursor" 1187 check-screen-row screen, 2/y, "... ", "F - test-cursor-down-and-up-within-trace/pre-2" -1188 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-cursor-down-and-up-within-trace/pre-2/cursor" +1188 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-cursor-down-and-up-within-trace/pre-2/cursor" 1189 # cursor down 1190 edit-trace t, 0x6a/j 1191 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 1/show-cursor 1192 # 1193 check-screen-row screen, 0/y, "... ", "F - test-cursor-down-and-up-within-trace/down-0" -1194 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-cursor-down-and-up-within-trace/down-0/cursor" +1194 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-cursor-down-and-up-within-trace/down-0/cursor" 1195 check-screen-row screen, 1/y, "error ", "F - test-cursor-down-and-up-within-trace/down-1" -1196 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "||||| ", "F - test-cursor-down-and-up-within-trace/down-1/cursor" +1196 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "||||| ", "F - test-cursor-down-and-up-within-trace/down-1/cursor" 1197 check-screen-row screen, 2/y, "... ", "F - test-cursor-down-and-up-within-trace/down-2" -1198 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-cursor-down-and-up-within-trace/down-2/cursor" +1198 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-cursor-down-and-up-within-trace/down-2/cursor" 1199 # cursor up 1200 edit-trace t, 0x6b/k 1201 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 1/show-cursor 1202 # 1203 check-screen-row screen, 0/y, "... ", "F - test-cursor-down-and-up-within-trace/up-0" -1204 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-cursor-down-and-up-within-trace/up-0/cursor" +1204 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-cursor-down-and-up-within-trace/up-0/cursor" 1205 check-screen-row screen, 1/y, "error ", "F - test-cursor-down-and-up-within-trace/up-1" -1206 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-cursor-down-and-up-within-trace/up-1/cursor" +1206 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-cursor-down-and-up-within-trace/up-1/cursor" 1207 check-screen-row screen, 2/y, "... ", "F - test-cursor-down-and-up-within-trace/up-2" -1208 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-cursor-down-and-up-within-trace/up-2/cursor" +1208 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-cursor-down-and-up-within-trace/up-2/cursor" 1209 } 1210 1211 fn test-cursor-down-past-bottom-of-trace { @@ -1285,16 +1285,16 @@ if ('onhashchange' in window) { 1219 # setup: screen 1220 var screen-on-stack: screen 1221 var screen/edi: (addr screen) <- address screen-on-stack -1222 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics +1222 initialize-screen screen, 0xa/width, 4/height, 0/no-pixel-graphics 1223 # 1224 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 1/show-cursor 1225 # 1226 check-screen-row screen, 0/y, "... ", "F - test-cursor-down-past-bottom-of-trace/pre-0" -1227 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-cursor-down-past-bottom-of-trace/pre-0/cursor" +1227 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-cursor-down-past-bottom-of-trace/pre-0/cursor" 1228 check-screen-row screen, 1/y, "error ", "F - test-cursor-down-past-bottom-of-trace/pre-1" -1229 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-cursor-down-past-bottom-of-trace/pre-1/cursor" +1229 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-cursor-down-past-bottom-of-trace/pre-1/cursor" 1230 check-screen-row screen, 2/y, "... ", "F - test-cursor-down-past-bottom-of-trace/pre-2" -1231 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-cursor-down-past-bottom-of-trace/pre-2/cursor" +1231 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-cursor-down-past-bottom-of-trace/pre-2/cursor" 1232 # cursor down several times 1233 edit-trace t, 0x6a/j 1234 edit-trace t, 0x6a/j @@ -1305,11 +1305,11 @@ if ('onhashchange' in window) { 1239 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0xa/xmax, 4/ymax, 1/show-cursor 1240 # cursor clamps at bottom 1241 check-screen-row screen, 0/y, "... ", "F - test-cursor-down-past-bottom-of-trace/down-0" -1242 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-cursor-down-past-bottom-of-trace/down-0/cursor" +1242 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-cursor-down-past-bottom-of-trace/down-0/cursor" 1243 check-screen-row screen, 1/y, "error ", "F - test-cursor-down-past-bottom-of-trace/down-1" -1244 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-cursor-down-past-bottom-of-trace/down-1/cursor" +1244 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-cursor-down-past-bottom-of-trace/down-1/cursor" 1245 check-screen-row screen, 2/y, "... ", "F - test-cursor-down-past-bottom-of-trace/down-2" -1246 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "||| ", "F - test-cursor-down-past-bottom-of-trace/down-2/cursor" +1246 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "||| ", "F - test-cursor-down-past-bottom-of-trace/down-2/cursor" 1247 } 1248 1249 fn test-expand-within-trace { @@ -1322,24 +1322,24 @@ if ('onhashchange' in window) { 1256 # setup: screen 1257 var screen-on-stack: screen 1258 var screen/edi: (addr screen) <- address screen-on-stack -1259 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1259 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1260 # 1261 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1262 # 1263 check-screen-row screen, 0/y, "... ", "F - test-expand-within-trace/pre-0" -1264 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-expand-within-trace/pre-0/cursor" +1264 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-expand-within-trace/pre-0/cursor" 1265 check-screen-row screen, 1/y, " ", "F - test-expand-within-trace/pre-1" -1266 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-expand-within-trace/pre-1/cursor" +1266 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-expand-within-trace/pre-1/cursor" 1267 # expand 1268 edit-trace t, 0xa/enter 1269 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1270 # 1271 check-screen-row screen, 0/y, "1 line 1 ", "F - test-expand-within-trace/expand-0" -1272 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-expand-within-trace/expand-0/cursor" +1272 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-expand-within-trace/expand-0/cursor" 1273 check-screen-row screen, 1/y, "1 line 2 ", "F - test-expand-within-trace/expand-1" -1274 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-expand-within-trace/expand-1/cursor" +1274 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-expand-within-trace/expand-1/cursor" 1275 check-screen-row screen, 2/y, " ", "F - test-expand-within-trace/expand-2" -1276 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-expand-within-trace/expand-2/cursor" +1276 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-expand-within-trace/expand-2/cursor" 1277 } 1278 1279 fn test-trace-expand-skips-lower-depth { @@ -1353,24 +1353,24 @@ if ('onhashchange' in window) { 1287 # setup: screen 1288 var screen-on-stack: screen 1289 var screen/edi: (addr screen) <- address screen-on-stack -1290 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1290 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1291 # 1292 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1293 # 1294 check-screen-row screen, 0/y, "... ", "F - test-trace-expand-skips-lower-depth/pre-0" -1295 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-expand-skips-lower-depth/pre-0/cursor" +1295 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-expand-skips-lower-depth/pre-0/cursor" 1296 check-screen-row screen, 1/y, " ", "F - test-trace-expand-skips-lower-depth/pre-1" -1297 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-skips-lower-depth/pre-1/cursor" +1297 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-skips-lower-depth/pre-1/cursor" 1298 # expand 1299 edit-trace t, 0xa/enter 1300 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1301 # 1302 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-expand-skips-lower-depth/expand-0" -1303 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-expand-skips-lower-depth/expand-0/cursor" +1303 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-expand-skips-lower-depth/expand-0/cursor" 1304 check-screen-row screen, 1/y, "... ", "F - test-trace-expand-skips-lower-depth/expand-1" -1305 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-skips-lower-depth/expand-1/cursor" +1305 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-skips-lower-depth/expand-1/cursor" 1306 check-screen-row screen, 2/y, " ", "F - test-trace-expand-skips-lower-depth/expand-2" -1307 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-skips-lower-depth/expand-2/cursor" +1307 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-skips-lower-depth/expand-2/cursor" 1308 } 1309 1310 fn test-trace-expand-continues-past-lower-depth { @@ -1386,25 +1386,25 @@ if ('onhashchange' in window) { 1320 # setup: screen 1321 var screen-on-stack: screen 1322 var screen/edi: (addr screen) <- address screen-on-stack -1323 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1323 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1324 # 1325 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1326 # 1327 check-screen-row screen, 0/y, "... ", "F - test-trace-expand-continues-past-lower-depth/pre-0" -1328 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-expand-continues-past-lower-depth/pre-0/cursor" +1328 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-expand-continues-past-lower-depth/pre-0/cursor" 1329 check-screen-row screen, 1/y, " ", "F - test-trace-expand-continues-past-lower-depth/pre-1" -1330 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-continues-past-lower-depth/pre-1/cursor" +1330 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-continues-past-lower-depth/pre-1/cursor" 1331 # expand 1332 edit-trace t, 0xa/enter 1333 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1334 # 1335 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-expand-continues-past-lower-depth/expand-0" -1336 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-expand-continues-past-lower-depth/expand-0/cursor" +1336 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-expand-continues-past-lower-depth/expand-0/cursor" 1337 # TODO: might be too wasteful to show every place where lines are hidden 1338 check-screen-row screen, 1/y, "... ", "F - test-trace-expand-continues-past-lower-depth/expand-1" -1339 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-continues-past-lower-depth/expand-1/cursor" +1339 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-continues-past-lower-depth/expand-1/cursor" 1340 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-expand-continues-past-lower-depth/expand-2" -1341 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-continues-past-lower-depth/expand-2/cursor" +1341 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-continues-past-lower-depth/expand-2/cursor" 1342 } 1343 1344 fn test-trace-expand-stops-at-higher-depth { @@ -1425,28 +1425,28 @@ if ('onhashchange' in window) { 1359 # setup: screen 1360 var screen-on-stack: screen 1361 var screen/edi: (addr screen) <- address screen-on-stack -1362 initialize-screen screen, 0x10/width, 8/height, 0/no-pixel-graphics +1362 initialize-screen screen, 0x10/width, 8/height, 0/no-pixel-graphics 1363 # 1364 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 8/ymax, 1/show-cursor 1365 # 1366 check-screen-row screen, 0/y, "... ", "F - test-trace-expand-stops-at-higher-depth/pre-0" -1367 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-expand-stops-at-higher-depth/pre-0/cursor" +1367 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-expand-stops-at-higher-depth/pre-0/cursor" 1368 check-screen-row screen, 1/y, " ", "F - test-trace-expand-stops-at-higher-depth/pre-1" -1369 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-stops-at-higher-depth/pre-1/cursor" +1369 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-stops-at-higher-depth/pre-1/cursor" 1370 # expand 1371 edit-trace t, 0xa/enter 1372 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 8/ymax, 1/show-cursor 1373 # 1374 check-screen-row screen, 0/y, "2 line 1.1 ", "F - test-trace-expand-stops-at-higher-depth/expand-0" -1375 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||||| ", "F - test-trace-expand-stops-at-higher-depth/expand-0/cursor" +1375 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||||| ", "F - test-trace-expand-stops-at-higher-depth/expand-0/cursor" 1376 check-screen-row screen, 1/y, "... ", "F - test-trace-expand-stops-at-higher-depth/expand-1" -1377 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-1/cursor" +1377 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-1/cursor" 1378 check-screen-row screen, 2/y, "2 line 1.2 ", "F - test-trace-expand-stops-at-higher-depth/expand-2" -1379 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-2/cursor" +1379 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-2/cursor" 1380 check-screen-row screen, 3/y, "... ", "F - test-trace-expand-stops-at-higher-depth/expand-3" -1381 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-3/cursor" +1381 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-3/cursor" 1382 check-screen-row screen, 4/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-4" -1383 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-4/cursor" +1383 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-trace-expand-stops-at-higher-depth/expand-4/cursor" 1384 } 1385 1386 fn test-trace-expand-twice { @@ -1462,45 +1462,45 @@ if ('onhashchange' in window) { 1396 # setup: screen 1397 var screen-on-stack: screen 1398 var screen/edi: (addr screen) <- address screen-on-stack -1399 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1399 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1400 # 1401 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1402 # 1403 check-screen-row screen, 0/y, "... ", "F - test-trace-expand-twice/pre-0" -1404 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-expand-twice/pre-0/cursor" +1404 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-expand-twice/pre-0/cursor" 1405 check-screen-row screen, 1/y, " ", "F - test-trace-expand-twice/pre-1" -1406 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-twice/pre-1/cursor" +1406 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-twice/pre-1/cursor" 1407 # expand 1408 edit-trace t, 0xa/enter 1409 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1410 # 1411 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-expand-twice/expand-0" -1412 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-expand-twice/expand-0/cursor" +1412 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-expand-twice/expand-0/cursor" 1413 check-screen-row screen, 1/y, "... ", "F - test-trace-expand-twice/expand-1" -1414 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-twice/expand-1/cursor" +1414 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-expand-twice/expand-1/cursor" 1415 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-expand-twice/expand-2" -1416 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-twice/expand-2/cursor" +1416 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-twice/expand-2/cursor" 1417 # cursor down 1418 edit-trace t, 0x6a/j 1419 # hack: we need to render here to make this test pass; we're mixing state management with rendering 1420 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1421 # 1422 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-expand-twice/down-0" -1423 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-expand-twice/down-0/cursor" +1423 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-expand-twice/down-0/cursor" 1424 check-screen-row screen, 1/y, "... ", "F - test-trace-expand-twice/down-1" -1425 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "||| ", "F - test-trace-expand-twice/down-1/cursor" +1425 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "||| ", "F - test-trace-expand-twice/down-1/cursor" 1426 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-expand-twice/down-2" -1427 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-twice/down-2/cursor" +1427 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-twice/down-2/cursor" 1428 # expand again 1429 edit-trace t, 0xa/enter 1430 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1431 # 1432 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-expand-twice/expand2-0" -1433 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-expand-twice/expand2-0/cursor" +1433 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-expand-twice/expand2-0/cursor" 1434 check-screen-row screen, 1/y, "2 line 1.1 ", "F - test-trace-expand-twice/expand2-1" -1435 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "|||||||||| ", "F - test-trace-expand-twice/expand2-1/cursor" +1435 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "|||||||||| ", "F - test-trace-expand-twice/expand2-1/cursor" 1436 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-expand-twice/expand2-2" -1437 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-twice/expand2-2/cursor" +1437 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-expand-twice/expand2-2/cursor" 1438 } 1439 1440 fn test-trace-refresh-cursor { @@ -1514,35 +1514,35 @@ if ('onhashchange' in window) { 1448 # setup: screen 1449 var screen-on-stack: screen 1450 var screen/edi: (addr screen) <- address screen-on-stack -1451 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1451 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1452 # 1453 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1454 # 1455 check-screen-row screen, 0/y, "... ", "F - test-trace-refresh-cursor/pre-0" -1456 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-refresh-cursor/pre-0/cursor" +1456 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-refresh-cursor/pre-0/cursor" 1457 check-screen-row screen, 1/y, " ", "F - test-trace-refresh-cursor/pre-1" -1458 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-refresh-cursor/pre-1/cursor" +1458 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-refresh-cursor/pre-1/cursor" 1459 # expand 1460 edit-trace t, 0xa/enter 1461 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1462 # 1463 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-refresh-cursor/expand-0" -1464 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-refresh-cursor/expand-0/cursor" +1464 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-refresh-cursor/expand-0/cursor" 1465 check-screen-row screen, 1/y, "1 line 2 ", "F - test-trace-refresh-cursor/expand-1" -1466 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-refresh-cursor/expand-1/cursor" +1466 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-refresh-cursor/expand-1/cursor" 1467 check-screen-row screen, 2/y, "1 line 3 ", "F - test-trace-refresh-cursor/expand-2" -1468 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-refresh-cursor/expand-2/cursor" +1468 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-refresh-cursor/expand-2/cursor" 1469 # cursor down 1470 edit-trace t, 0x6a/j 1471 edit-trace t, 0x6a/j 1472 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1473 # 1474 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-refresh-cursor/down-0" -1475 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-refresh-cursor/down-0/cursor" +1475 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-refresh-cursor/down-0/cursor" 1476 check-screen-row screen, 1/y, "1 line 2 ", "F - test-trace-refresh-cursor/down-1" -1477 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-refresh-cursor/down-1/cursor" +1477 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-refresh-cursor/down-1/cursor" 1478 check-screen-row screen, 2/y, "1 line 3 ", "F - test-trace-refresh-cursor/down-2" -1479 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-refresh-cursor/down-2/cursor" +1479 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-refresh-cursor/down-2/cursor" 1480 # recreate trace 1481 clear-trace t 1482 trace-text t, "l", "line 1" @@ -1551,11 +1551,11 @@ if ('onhashchange' in window) { 1485 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1486 # cursor remains unchanged 1487 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-refresh-cursor/refresh-0" -1488 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-refresh-cursor/refresh-0/cursor" +1488 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-refresh-cursor/refresh-0/cursor" 1489 check-screen-row screen, 1/y, "1 line 2 ", "F - test-trace-refresh-cursor/refresh-1" -1490 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-refresh-cursor/refresh-1/cursor" +1490 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-refresh-cursor/refresh-1/cursor" 1491 check-screen-row screen, 2/y, "1 line 3 ", "F - test-trace-refresh-cursor/refresh-2" -1492 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-refresh-cursor/refresh-2/cursor" +1492 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-refresh-cursor/refresh-2/cursor" 1493 } 1494 1495 fn test-trace-preserve-cursor-on-refresh { @@ -1569,35 +1569,35 @@ if ('onhashchange' in window) { 1503 # setup: screen 1504 var screen-on-stack: screen 1505 var screen/edi: (addr screen) <- address screen-on-stack -1506 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1506 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1507 # 1508 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1509 # 1510 check-screen-row screen, 0/y, "... ", "F - test-trace-preserve-cursor-on-refresh/pre-0" -1511 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-preserve-cursor-on-refresh/pre-0/cursor" +1511 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-preserve-cursor-on-refresh/pre-0/cursor" 1512 check-screen-row screen, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/pre-1" -1513 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/pre-1/cursor" +1513 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/pre-1/cursor" 1514 # expand 1515 edit-trace t, 0xa/enter 1516 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1517 # 1518 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-preserve-cursor-on-refresh/expand-0" -1519 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-preserve-cursor-on-refresh/expand-0/cursor" +1519 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-preserve-cursor-on-refresh/expand-0/cursor" 1520 check-screen-row screen, 1/y, "1 line 2 ", "F - test-trace-preserve-cursor-on-refresh/expand-1" -1521 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/expand-1/cursor" +1521 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/expand-1/cursor" 1522 check-screen-row screen, 2/y, "1 line 3 ", "F - test-trace-preserve-cursor-on-refresh/expand-2" -1523 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-preserve-cursor-on-refresh/expand-2/cursor" +1523 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-preserve-cursor-on-refresh/expand-2/cursor" 1524 # cursor down 1525 edit-trace t, 0x6a/j 1526 edit-trace t, 0x6a/j 1527 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1528 # 1529 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-preserve-cursor-on-refresh/down-0" -1530 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-preserve-cursor-on-refresh/down-0/cursor" +1530 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-preserve-cursor-on-refresh/down-0/cursor" 1531 check-screen-row screen, 1/y, "1 line 2 ", "F - test-trace-preserve-cursor-on-refresh/down-1" -1532 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/down-1/cursor" +1532 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/down-1/cursor" 1533 check-screen-row screen, 2/y, "1 line 3 ", "F - test-trace-preserve-cursor-on-refresh/down-2" -1534 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-preserve-cursor-on-refresh/down-2/cursor" +1534 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-preserve-cursor-on-refresh/down-2/cursor" 1535 # recreate trace with slightly different lines 1536 clear-trace t 1537 trace-text t, "l", "line 4" @@ -1606,11 +1606,11 @@ if ('onhashchange' in window) { 1540 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1541 # cursor remains unchanged 1542 check-screen-row screen, 0/y, "1 line 4 ", "F - test-trace-preserve-cursor-on-refresh/refresh-0" -1543 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-preserve-cursor-on-refresh/refresh-0/cursor" +1543 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-preserve-cursor-on-refresh/refresh-0/cursor" 1544 check-screen-row screen, 1/y, "1 line 5 ", "F - test-trace-preserve-cursor-on-refresh/refresh-1" -1545 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/refresh-1/cursor" +1545 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-preserve-cursor-on-refresh/refresh-1/cursor" 1546 check-screen-row screen, 2/y, "1 line 3 ", "F - test-trace-preserve-cursor-on-refresh/refresh-2" -1547 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-preserve-cursor-on-refresh/refresh-2/cursor" +1547 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-preserve-cursor-on-refresh/refresh-2/cursor" 1548 } 1549 1550 fn test-trace-keep-cursor-visible-on-refresh { @@ -1624,50 +1624,50 @@ if ('onhashchange' in window) { 1558 # setup: screen 1559 var screen-on-stack: screen 1560 var screen/edi: (addr screen) <- address screen-on-stack -1561 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1561 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1562 # 1563 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1564 # 1565 check-screen-row screen, 0/y, "... ", "F - test-trace-keep-cursor-visible-on-refresh/pre-0" -1566 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-keep-cursor-visible-on-refresh/pre-0/cursor" +1566 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-keep-cursor-visible-on-refresh/pre-0/cursor" 1567 check-screen-row screen, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/pre-1" -1568 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/pre-1/cursor" +1568 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/pre-1/cursor" 1569 # expand 1570 edit-trace t, 0xa/enter 1571 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1572 # 1573 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-keep-cursor-visible-on-refresh/expand-0" -1574 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-keep-cursor-visible-on-refresh/expand-0/cursor" +1574 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-keep-cursor-visible-on-refresh/expand-0/cursor" 1575 check-screen-row screen, 1/y, "1 line 2 ", "F - test-trace-keep-cursor-visible-on-refresh/expand-1" -1576 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/expand-1/cursor" +1576 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/expand-1/cursor" 1577 check-screen-row screen, 2/y, "1 line 3 ", "F - test-trace-keep-cursor-visible-on-refresh/expand-2" -1578 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/expand-2/cursor" +1578 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/expand-2/cursor" 1579 # cursor down 1580 edit-trace t, 0x6a/j 1581 edit-trace t, 0x6a/j 1582 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1583 # 1584 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-keep-cursor-visible-on-refresh/down-0" -1585 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/down-0/cursor" +1585 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/down-0/cursor" 1586 check-screen-row screen, 1/y, "1 line 2 ", "F - test-trace-keep-cursor-visible-on-refresh/down-1" -1587 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/down-1/cursor" +1587 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/down-1/cursor" 1588 check-screen-row screen, 2/y, "1 line 3 ", "F - test-trace-keep-cursor-visible-on-refresh/down-2" -1589 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-keep-cursor-visible-on-refresh/down-2/cursor" +1589 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-keep-cursor-visible-on-refresh/down-2/cursor" 1590 # recreate trace with entirely different lines 1591 clear-trace t 1592 trace-text t, "l", "line 4" 1593 trace-text t, "l", "line 5" 1594 trace-text t, "l", "line 6" 1595 mark-lines-dirty t -1596 clear-screen screen +1596 clear-screen screen 1597 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1598 # trace collapses, and cursor bumps up 1599 check-screen-row screen, 0/y, "... ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-0" -1600 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-0/cursor" +1600 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-0/cursor" 1601 check-screen-row screen, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-1" -1602 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-1/cursor" +1602 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-1/cursor" 1603 check-screen-row screen, 2/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-2" -1604 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-2/cursor" +1604 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-keep-cursor-visible-on-refresh/refresh-2/cursor" 1605 } 1606 1607 fn test-trace-collapse-at-top { @@ -1683,35 +1683,35 @@ if ('onhashchange' in window) { 1617 # setup: screen 1618 var screen-on-stack: screen 1619 var screen/edi: (addr screen) <- address screen-on-stack -1620 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1620 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1621 # 1622 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1623 # 1624 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse-at-top/pre-0" -1625 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-at-top/pre-0/cursor" +1625 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-at-top/pre-0/cursor" 1626 check-screen-row screen, 1/y, " ", "F - test-trace-collapse-at-top/pre-1" -1627 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-at-top/pre-1/cursor" +1627 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-at-top/pre-1/cursor" 1628 # expand 1629 edit-trace t, 0xa/enter 1630 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1631 # 1632 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-collapse-at-top/expand-0" -1633 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse-at-top/expand-0/cursor" +1633 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse-at-top/expand-0/cursor" 1634 check-screen-row screen, 1/y, "... ", "F - test-trace-collapse-at-top/expand-1" -1635 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-at-top/expand-1/cursor" +1635 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-at-top/expand-1/cursor" 1636 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-collapse-at-top/expand-2" -1637 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-at-top/expand-2/cursor" +1637 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-at-top/expand-2/cursor" 1638 # collapse 1639 edit-trace t, 8/backspace 1640 # hack: we need to render here to make this test pass; we're mixing state management with rendering -1641 clear-screen screen +1641 clear-screen screen 1642 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1643 # 1644 check-ints-equal y, 1, "F - test-trace-collapse-at-top/post-0/y" 1645 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse-at-top/post-0" -1646 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-at-top/post-0/cursor" +1646 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-at-top/post-0/cursor" 1647 check-screen-row screen, 1/y, " ", "F - test-trace-collapse-at-top/post-1" -1648 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-at-top/post-1/cursor" +1648 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-at-top/post-1/cursor" 1649 } 1650 1651 fn test-trace-collapse { @@ -1724,35 +1724,35 @@ if ('onhashchange' in window) { 1658 # setup: screen 1659 var screen-on-stack: screen 1660 var screen/edi: (addr screen) <- address screen-on-stack -1661 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1661 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1662 # 1663 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1664 # 1665 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse/pre-0" -1666 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse/pre-0/cursor" +1666 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse/pre-0/cursor" 1667 check-screen-row screen, 1/y, " ", "F - test-trace-collapse/pre-1" -1668 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse/pre-1/cursor" +1668 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse/pre-1/cursor" 1669 # expand 1670 edit-trace t, 0xa/enter 1671 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1672 # 1673 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-collapse/expand-0" -1674 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse/expand-0/cursor" +1674 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse/expand-0/cursor" 1675 check-screen-row screen, 1/y, "1 line 2 ", "F - test-trace-collapse/expand-1" -1676 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse/expand-1/cursor" +1676 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse/expand-1/cursor" 1677 # cursor down 1678 edit-trace t, 0x6a/j 1679 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1680 # collapse 1681 edit-trace t, 8/backspace -1682 clear-screen screen +1682 clear-screen screen 1683 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1684 # 1685 check-ints-equal y, 1, "F - test-trace-collapse/post-0/y" 1686 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse/post-0" -1687 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse/post-0/cursor" +1687 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse/post-0/cursor" 1688 check-screen-row screen, 1/y, " ", "F - test-trace-collapse/post-1" -1689 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse/post-1/cursor" +1689 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse/post-1/cursor" 1690 } 1691 1692 fn test-trace-collapse-skips-invisible-lines { @@ -1768,24 +1768,24 @@ if ('onhashchange' in window) { 1702 # setup: screen 1703 var screen-on-stack: screen 1704 var screen/edi: (addr screen) <- address screen-on-stack -1705 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1705 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1706 # 1707 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1708 # 1709 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse-skips-invisible-lines/pre-0" -1710 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-skips-invisible-lines/pre-0/cursor" +1710 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-skips-invisible-lines/pre-0/cursor" 1711 check-screen-row screen, 1/y, " ", "F - test-trace-collapse-skips-invisible-lines/pre-1" -1712 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-skips-invisible-lines/pre-1/cursor" +1712 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-skips-invisible-lines/pre-1/cursor" 1713 # expand 1714 edit-trace t, 0xa/enter 1715 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1716 # two visible lines with an invisible line in between 1717 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-collapse-skips-invisible-lines/expand-0" -1718 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse-skips-invisible-lines/expand-0/cursor" +1718 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse-skips-invisible-lines/expand-0/cursor" 1719 check-screen-row screen, 1/y, "... ", "F - test-trace-collapse-skips-invisible-lines/expand-1" -1720 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-skips-invisible-lines/expand-1/cursor" +1720 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-skips-invisible-lines/expand-1/cursor" 1721 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-collapse-skips-invisible-lines/expand-2" -1722 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-skips-invisible-lines/expand-2/cursor" +1722 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-skips-invisible-lines/expand-2/cursor" 1723 # cursor down to second visible line 1724 edit-trace t, 0x6a/j 1725 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor @@ -1793,16 +1793,16 @@ if ('onhashchange' in window) { 1727 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1728 # collapse 1729 edit-trace t, 8/backspace -1730 clear-screen screen +1730 clear-screen screen 1731 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1732 # 1733 check-ints-equal y, 1, "F - test-trace-collapse-skips-invisible-lines/post-0/y" 1734 var cursor-y/eax: (addr int) <- get t, cursor-y 1735 check-ints-equal *cursor-y, 0, "F - test-trace-collapse-skips-invisible-lines/post-0/cursor-y" 1736 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse-skips-invisible-lines/post-0" -1737 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-skips-invisible-lines/post-0/cursor" +1737 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-skips-invisible-lines/post-0/cursor" 1738 check-screen-row screen, 1/y, " ", "F - test-trace-collapse-skips-invisible-lines/post-1" -1739 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-skips-invisible-lines/post-1/cursor" +1739 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-skips-invisible-lines/post-1/cursor" 1740 } 1741 1742 fn test-trace-collapse-two-levels { @@ -1818,24 +1818,24 @@ if ('onhashchange' in window) { 1752 # setup: screen 1753 var screen-on-stack: screen 1754 var screen/edi: (addr screen) <- address screen-on-stack -1755 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1755 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1756 # 1757 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1758 # 1759 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse-two-levels/pre-0" -1760 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-two-levels/pre-0/cursor" +1760 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-two-levels/pre-0/cursor" 1761 check-screen-row screen, 1/y, " ", "F - test-trace-collapse-two-levels/pre-1" -1762 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-two-levels/pre-1/cursor" +1762 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-two-levels/pre-1/cursor" 1763 # expand 1764 edit-trace t, 0xa/enter 1765 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1766 # two visible lines with an invisible line in between 1767 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-collapse-two-levels/expand-0" -1768 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse-two-levels/expand-0/cursor" +1768 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse-two-levels/expand-0/cursor" 1769 check-screen-row screen, 1/y, "... ", "F - test-trace-collapse-two-levels/expand-1" -1770 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-two-levels/expand-1/cursor" +1770 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-two-levels/expand-1/cursor" 1771 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-collapse-two-levels/expand-2" -1772 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-two-levels/expand-2/cursor" +1772 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-two-levels/expand-2/cursor" 1773 # cursor down to ellipses 1774 edit-trace t, 0x6a/j 1775 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor @@ -1844,26 +1844,26 @@ if ('onhashchange' in window) { 1778 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1779 # two visible lines with an invisible line in between 1780 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-collapse-two-levels/expand2-0" -1781 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-collapse-two-levels/expand2-0/cursor" +1781 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-collapse-two-levels/expand2-0/cursor" 1782 check-screen-row screen, 1/y, "2 line 1.1 ", "F - test-trace-collapse-two-levels/expand2-1" -1783 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "|||||||||| ", "F - test-trace-collapse-two-levels/expand2-1/cursor" +1783 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "|||||||||| ", "F - test-trace-collapse-two-levels/expand2-1/cursor" 1784 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-collapse-two-levels/expand2-2" -1785 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-two-levels/expand2-2/cursor" +1785 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-two-levels/expand2-2/cursor" 1786 # cursor down to second visible line 1787 edit-trace t, 0x6a/j 1788 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1789 # collapse 1790 edit-trace t, 8/backspace -1791 clear-screen screen +1791 clear-screen screen 1792 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1793 # 1794 check-ints-equal y, 1, "F - test-trace-collapse-two-levels/post-0/y" 1795 var cursor-y/eax: (addr int) <- get t, cursor-y 1796 check-ints-equal *cursor-y, 0, "F - test-trace-collapse-two-levels/post-0/cursor-y" 1797 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse-two-levels/post-0" -1798 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-two-levels/post-0/cursor" +1798 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-two-levels/post-0/cursor" 1799 check-screen-row screen, 1/y, " ", "F - test-trace-collapse-two-levels/post-1" -1800 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-two-levels/post-1/cursor" +1800 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-two-levels/post-1/cursor" 1801 } 1802 1803 fn test-trace-collapse-nested-level { @@ -1883,26 +1883,26 @@ if ('onhashchange' in window) { 1817 # setup: screen 1818 var screen-on-stack: screen 1819 var screen/edi: (addr screen) <- address screen-on-stack -1820 initialize-screen screen, 0x10/width, 8/height, 0/no-pixel-graphics +1820 initialize-screen screen, 0x10/width, 8/height, 0/no-pixel-graphics 1821 # 1822 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 8/ymax, 1/show-cursor 1823 # 1824 check-screen-row screen, 0/y, "... ", "F - test-trace-collapse-nested-level/pre-0" -1825 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-nested-level/pre-0/cursor" +1825 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-collapse-nested-level/pre-0/cursor" 1826 check-screen-row screen, 1/y, " ", "F - test-trace-collapse-nested-level/pre-1" -1827 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-nested-level/pre-1/cursor" +1827 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-nested-level/pre-1/cursor" 1828 # expand 1829 edit-trace t, 0xa/enter 1830 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 8/ymax, 1/show-cursor 1831 # two visible lines with an invisible line in between 1832 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-collapse-nested-level/expand-0" -1833 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse-nested-level/expand-0/cursor" +1833 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-collapse-nested-level/expand-0/cursor" 1834 check-screen-row screen, 1/y, "... ", "F - test-trace-collapse-nested-level/expand-1" -1835 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-nested-level/expand-1/cursor" +1835 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-nested-level/expand-1/cursor" 1836 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-collapse-nested-level/expand-2" -1837 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-nested-level/expand-2/cursor" +1837 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-nested-level/expand-2/cursor" 1838 check-screen-row screen, 3/y, "... ", "F - test-trace-collapse-nested-level/expand-3" -1839 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-collapse-nested-level/expand-3/cursor" +1839 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-collapse-nested-level/expand-3/cursor" 1840 # cursor down to bottom 1841 edit-trace t, 0x6a/j 1842 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 8/ymax, 1/show-cursor @@ -1915,31 +1915,31 @@ if ('onhashchange' in window) { 1849 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 8/ymax, 1/show-cursor 1850 # two visible lines with an invisible line in between 1851 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-collapse-nested-level/expand2-0" -1852 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-collapse-nested-level/expand2-0/cursor" +1852 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-collapse-nested-level/expand2-0/cursor" 1853 check-screen-row screen, 1/y, "... ", "F - test-trace-collapse-nested-level/expand2-1" -1854 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-nested-level/expand2-1/cursor" +1854 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-nested-level/expand2-1/cursor" 1855 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-collapse-nested-level/expand2-2" -1856 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-nested-level/expand2-2/cursor" +1856 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-collapse-nested-level/expand2-2/cursor" 1857 check-screen-row screen, 3/y, "2 line 2.1 ", "F - test-trace-collapse-nested-level/expand2-3" -1858 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "|||||||||| ", "F - test-trace-collapse-nested-level/expand2-3/cursor" +1858 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "|||||||||| ", "F - test-trace-collapse-nested-level/expand2-3/cursor" 1859 check-screen-row screen, 4/y, "2 line 2.2 ", "F - test-trace-collapse-nested-level/expand2-4" -1860 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-trace-collapse-nested-level/expand2-4/cursor" +1860 check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, " ", "F - test-trace-collapse-nested-level/expand2-4/cursor" 1861 # collapse 1862 edit-trace t, 8/backspace -1863 clear-screen screen +1863 clear-screen screen 1864 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 8/ymax, 1/show-cursor 1865 # 1866 check-ints-equal y, 4, "F - test-trace-collapse-nested-level/post-0/y" 1867 var cursor-y/eax: (addr int) <- get t, cursor-y 1868 check-ints-equal *cursor-y, 2, "F - test-trace-collapse-nested-level/post-0/cursor-y" 1869 check-screen-row screen, 0/y, "1 line 1 ", "F - test-trace-collapse-nested-level/post-0" -1870 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-collapse-nested-level/post-0/cursor" +1870 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-trace-collapse-nested-level/post-0/cursor" 1871 check-screen-row screen, 1/y, "... ", "F - test-trace-collapse-nested-level/post-1" -1872 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-nested-level/post-1/cursor" +1872 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-collapse-nested-level/post-1/cursor" 1873 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-collapse-nested-level/post-2" -1874 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-collapse-nested-level/post-2/cursor" +1874 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|||||||| ", "F - test-trace-collapse-nested-level/post-2/cursor" 1875 check-screen-row screen, 3/y, "... ", "F - test-trace-collapse-nested-level/post-3" -1876 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-collapse-nested-level/post-3/cursor" +1876 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-collapse-nested-level/post-3/cursor" 1877 } 1878 1879 fn scroll-down _self: (addr trace) { @@ -2057,106 +2057,106 @@ if ('onhashchange' in window) { 1991 # setup: screen 1992 var screen-on-stack: screen 1993 var screen/edi: (addr screen) <- address screen-on-stack -1994 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics +1994 initialize-screen screen, 0x10/width, 4/height, 0/no-pixel-graphics 1995 # pre-render 1996 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 1997 # 1998 check-screen-row screen, 0/y, "... ", "F - test-trace-scroll/pre-0" -1999 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-scroll/pre-0/cursor" +1999 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "||| ", "F - test-trace-scroll/pre-0/cursor" 2000 check-screen-row screen, 1/y, " ", "F - test-trace-scroll/pre-1" -2001 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/pre-1/cursor" +2001 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/pre-1/cursor" 2002 check-screen-row screen, 2/y, " ", "F - test-trace-scroll/pre-2" -2003 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/pre-2/cursor" +2003 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/pre-2/cursor" 2004 check-screen-row screen, 3/y, " ", "F - test-trace-scroll/pre-3" -2005 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/pre-3/cursor" +2005 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/pre-3/cursor" 2006 # expand 2007 edit-trace t, 0xa/enter -2008 clear-screen screen +2008 clear-screen screen 2009 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 2010 # 2011 check-screen-row screen, 0/y, "1 line 0 ", "F - test-trace-scroll/expand-0" -2012 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/expand-0/cursor" +2012 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/expand-0/cursor" 2013 check-screen-row screen, 1/y, "1 line 1 ", "F - test-trace-scroll/expand-1" -2014 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/expand-1/cursor" +2014 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/expand-1/cursor" 2015 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-scroll/expand-2" -2016 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/expand-2/cursor" +2016 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/expand-2/cursor" 2017 check-screen-row screen, 3/y, "1 line 3 ", "F - test-trace-scroll/expand-3" -2018 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/expand-3/cursor" +2018 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/expand-3/cursor" 2019 # scroll up 2020 # hack: we must have rendered before this point; we're mixing state management with rendering 2021 edit-trace t, 2/ctrl-b -2022 clear-screen screen +2022 clear-screen screen 2023 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 2024 # no change since we're already at the top 2025 check-screen-row screen, 0/y, "1 line 0 ", "F - test-trace-scroll/up0-0" -2026 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/up0-0/cursor" +2026 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/up0-0/cursor" 2027 check-screen-row screen, 1/y, "1 line 1 ", "F - test-trace-scroll/up0-1" -2028 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/up0-1/cursor" +2028 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/up0-1/cursor" 2029 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-scroll/up0-2" -2030 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/up0-2/cursor" +2030 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/up0-2/cursor" 2031 check-screen-row screen, 3/y, "1 line 3 ", "F - test-trace-scroll/up0-3" -2032 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/up0-3/cursor" +2032 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/up0-3/cursor" 2033 # scroll down 2034 edit-trace t, 6/ctrl-f -2035 clear-screen screen +2035 clear-screen screen 2036 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 2037 check-screen-row screen, 0/y, "1 line 4 ", "F - test-trace-scroll/down1-0" -2038 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/down1-0/cursor" +2038 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/down1-0/cursor" 2039 check-screen-row screen, 1/y, "1 line 5 ", "F - test-trace-scroll/down1-1" -2040 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/down1-1/cursor" +2040 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/down1-1/cursor" 2041 check-screen-row screen, 2/y, "1 line 6 ", "F - test-trace-scroll/down1-2" -2042 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/down1-2/cursor" +2042 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/down1-2/cursor" 2043 check-screen-row screen, 3/y, "1 line 7 ", "F - test-trace-scroll/down1-3" -2044 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/down1-3/cursor" +2044 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/down1-3/cursor" 2045 # scroll down 2046 edit-trace t, 6/ctrl-f -2047 clear-screen screen +2047 clear-screen screen 2048 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 2049 check-screen-row screen, 0/y, "1 line 8 ", "F - test-trace-scroll/down2-0" -2050 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/down2-0/cursor" +2050 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/down2-0/cursor" 2051 check-screen-row screen, 1/y, "1 line 9 ", "F - test-trace-scroll/down2-1" -2052 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/down2-1/cursor" +2052 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/down2-1/cursor" 2053 check-screen-row screen, 2/y, " ", "F - test-trace-scroll/down2-2" -2054 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/down2-2/cursor" +2054 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/down2-2/cursor" 2055 check-screen-row screen, 3/y, " ", "F - test-trace-scroll/down2-3" -2056 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/down2-3/cursor" +2056 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/down2-3/cursor" 2057 # scroll down 2058 edit-trace t, 6/ctrl-f -2059 clear-screen screen +2059 clear-screen screen 2060 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 2061 # no change since we're already at the bottom 2062 check-screen-row screen, 0/y, "1 line 8 ", "F - test-trace-scroll/down3-0" -2063 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/down3-0/cursor" +2063 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/down3-0/cursor" 2064 check-screen-row screen, 1/y, "1 line 9 ", "F - test-trace-scroll/down3-1" -2065 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/down3-1/cursor" +2065 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/down3-1/cursor" 2066 check-screen-row screen, 2/y, " ", "F - test-trace-scroll/down3-2" -2067 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/down3-2/cursor" +2067 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/down3-2/cursor" 2068 check-screen-row screen, 3/y, " ", "F - test-trace-scroll/down3-3" -2069 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/down3-3/cursor" +2069 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/down3-3/cursor" 2070 # scroll up 2071 edit-trace t, 2/ctrl-b -2072 clear-screen screen +2072 clear-screen screen 2073 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 2074 check-screen-row screen, 0/y, "1 line 4 ", "F - test-trace-scroll/up1-0" -2075 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/up1-0/cursor" +2075 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/up1-0/cursor" 2076 check-screen-row screen, 1/y, "1 line 5 ", "F - test-trace-scroll/up1-1" -2077 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/up1-1/cursor" +2077 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/up1-1/cursor" 2078 check-screen-row screen, 2/y, "1 line 6 ", "F - test-trace-scroll/up1-2" -2079 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/up1-2/cursor" +2079 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/up1-2/cursor" 2080 check-screen-row screen, 3/y, "1 line 7 ", "F - test-trace-scroll/up1-3" -2081 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/up1-3/cursor" +2081 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/up1-3/cursor" 2082 # scroll up 2083 edit-trace t, 2/ctrl-b -2084 clear-screen screen +2084 clear-screen screen 2085 var y/ecx: int <- render-trace screen, t, 0/xmin, 0/ymin, 0x10/xmax, 4/ymax, 1/show-cursor 2086 check-screen-row screen, 0/y, "1 line 0 ", "F - test-trace-scroll/up2-0" -2087 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/up2-0/cursor" +2087 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "|||||||| ", "F - test-trace-scroll/up2-0/cursor" 2088 check-screen-row screen, 1/y, "1 line 1 ", "F - test-trace-scroll/up2-1" -2089 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/up2-1/cursor" +2089 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-trace-scroll/up2-1/cursor" 2090 check-screen-row screen, 2/y, "1 line 2 ", "F - test-trace-scroll/up2-2" -2091 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/up2-2/cursor" +2091 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-trace-scroll/up2-2/cursor" 2092 check-screen-row screen, 3/y, "1 line 3 ", "F - test-trace-scroll/up2-3" -2093 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/up2-3/cursor" +2093 check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ", "F - test-trace-scroll/up2-3/cursor" 2094 } 2095 2096 # saving and restoring trace indices -- cgit 1.4.1-2-gfad0