From 6488bfcf851023e1b8e84be6ebbb793f895f3d0f Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 18 Nov 2019 12:50:01 -0800 Subject: [PATCH] 5753 Binaries are now identical again. There's a little hack here that we should clean up at some point. But it requires more thought. Ordering compiler phases is hard. So far we're only at the start of the slippery slope into that abyss. --- apps/assort | Bin 42893 -> 42893 bytes apps/assort.subx | 12 +- apps/dquotes.subx | 9 + apps/mu | Bin 51632 -> 51644 bytes html/apps/assort.subx.html | 12 +- html/apps/dquotes.subx.html | 2999 ++++++++++++++++++----------------- ntranslate | 19 +- 7 files changed, 1541 insertions(+), 1510 deletions(-) diff --git a/apps/assort b/apps/assort index 6070fdc07d38bda7d198e3c2356a18832bd13965..0cd18ecfbdb1801285e72735336d40deb10a1a53 100755 GIT binary patch delta 24 gcmeA@&(wRKX~ULurpRxTx25|taeUj%p3!Cx0FC1czW@LL delta 24 gcmeA@&(wRKX~ULuCc*2Ix25|t9k{lcJ)_MY0F0;#@Bjb+ diff --git a/apps/assort.subx b/apps/assort.subx index e78cde41..c3a98a87 100644 --- a/apps/assort.subx +++ b/apps/assort.subx @@ -459,13 +459,13 @@ read-segments: # in : (address buffered-file), table : (address stream {string, # clear-stream(line) # read-line-buffered(in, line) # if (line->write == 0) break # end of file - # var word-slice = next-word(line) + # var word-slice = next-word-or-string(line) # if slice-empty?(word-slice) # whitespace # continue # if slice-starts-with?(word-slice, "#") # comment # continue # if slice-equal?(word-slice, "==") - # var segment-name = next-word(line) + # var segment-name = next-word-or-string(line) # segment-slot = leaky-get-or-insert-slice(table, segment-name, row-size=8) # curr-segment = *segment-slot # if curr-segment != 0 @@ -557,12 +557,12 @@ $read-segments:check0: #? # . . discard args #? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp #? # }}} - # next-word(line, word-slice) + # next-word-or-string(line, word-slice) # . . push args 52/push-edx 51/push-ecx # . . call - e8/call next-word/disp32 + e8/call next-word-or-string/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp $read-segments:check1: @@ -667,12 +667,12 @@ $read-segments:check-for-segment-header: # . if (eax == 0) goto check3 3d/compare-eax-and 0/imm32 0f 84/jump-if-equal $read-segments:regular-line/disp32 - # segment-name = next-word(line) + # segment-name = next-word-or-string(line) # . . push args 52/push-edx 51/push-ecx # . . call - e8/call next-word/disp32 + e8/call next-word-or-string/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp #? # dump segment name {{{ diff --git a/apps/dquotes.subx b/apps/dquotes.subx index 7e6318cb..8220f582 100644 --- a/apps/dquotes.subx +++ b/apps/dquotes.subx @@ -86,7 +86,16 @@ subx-dquotes: # in : (address buffered-file), out : (address buffered-file) # pseudocode: # var line : (stream byte 512) # var new-data-segment : (handle stream byte) = new-stream(Heap, Segment-size, 1) + # # write(new-data-segment, "== data\n") + # # TODO: When it was originally written dquotes ran before assort, so + # # it assumes lots of segment headers, and emits a new segment of its + # # own. We've since had to reorder the phases (see the explanation + # # for a.assort2 in ntranslate). We could clean up a.assort2 if we + # # conditionally emit the previous line. But this would require + # # teaching dquotes to parse segment headers, so maybe that's not + # # best.. + # # while true # clear-stream(line) # read-line-buffered(in, line) diff --git a/apps/mu b/apps/mu index 3d1738c8e4b575409db29ec49f77c3413188c3ea..55bb80ce9ed3690b3d2e8dbc78823b3cdc4bb9dd 100755 GIT binary patch delta 8475 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 W^sFr$+nWmU#}Xj>m@gbU8uDL}TQD&I delta 8453 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 # clear-stream(line) 460 # read-line-buffered(in, line) 461 # if (line->write == 0) break # end of file -462 # var word-slice = next-word(line) +462 # var word-slice = next-word-or-string(line) 463 # if slice-empty?(word-slice) # whitespace 464 # continue 465 # if slice-starts-with?(word-slice, "#") # comment 466 # continue 467 # if slice-equal?(word-slice, "==") -468 # var segment-name = next-word(line) +468 # var segment-name = next-word-or-string(line) 469 # segment-slot = leaky-get-or-insert-slice(table, segment-name, row-size=8) 470 # curr-segment = *segment-slot 471 # if curr-segment != 0 @@ -539,12 +539,12 @@ if ('onhashchange' in window) { 525 81 7/subop/compare 0/mod/indirect 1/rm32/ecx . . . . . 0/imm32 # compare *ecx 526 0f 84/jump-if-equal $read-segments:break/disp32 527 +-- 33 lines: #? # dump line ----------------------------------------------------------------------------------------------------------------------------- -560 # next-word(line, word-slice) +560 # next-word-or-string(line, word-slice) 561 # . . push args 562 52/push-edx 563 51/push-ecx 564 # . . call -565 e8/call next-word/disp32 +565 e8/call next-word-or-string/disp32 566 # . . discard args 567 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 568 $read-segments:check1: @@ -586,12 +586,12 @@ if ('onhashchange' in window) { 667 # . if (eax == 0) goto check3 668 3d/compare-eax-and 0/imm32 669 0f 84/jump-if-equal $read-segments:regular-line/disp32 -670 # segment-name = next-word(line) +670 # segment-name = next-word-or-string(line) 671 # . . push args 672 52/push-edx 673 51/push-ecx 674 # . . call -675 e8/call next-word/disp32 +675 e8/call next-word-or-string/disp32 676 # . . discard args 677 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 678 +-- 40 lines: #? # dump segment name --------------------------------------------------------------------------------------------------------------------- diff --git a/html/apps/dquotes.subx.html b/html/apps/dquotes.subx.html index 0b26ede2..6c3cb607 100644 --- a/html/apps/dquotes.subx.html +++ b/html/apps/dquotes.subx.html @@ -149,1627 +149,1636 @@ if ('onhashchange' in window) { 86 # pseudocode: 87 # var line : (stream byte 512) 88 # var new-data-segment : (handle stream byte) = new-stream(Heap, Segment-size, 1) - 89 # write(new-data-segment, "== data\n") - 90 # while true - 91 # clear-stream(line) - 92 # read-line-buffered(in, line) - 93 # if (line->write == 0) break # end of file - 94 # while true - 95 # var word-slice = next-word-or-string(line) - 96 # if slice-empty?(word-slice) # end of line - 97 # break - 98 # if slice-starts-with?(word-slice, "#") # comment - 99 # continue - 100 # if slice-starts-with?(word-slice, '"') # string literal <== what we're here for - 101 # process-string-literal(word-slice, out, new-data-segment) - 102 # else - 103 # write-slice-buffered(out, word-slice) - 104 # write(out, " ") - 105 # write(out, "\n\n") - 106 # write-stream-data(out, new-data-segment) - 107 # flush(out) - 108 # - 109 # . prologue - 110 55/push-ebp - 111 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 112 # . save registers - 113 50/push-eax - 114 51/push-ecx - 115 52/push-edx - 116 53/push-ebx - 117 56/push-esi - 118 57/push-edi - 119 # var line/ecx : (address stream byte) = stream(512) - 120 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp - 121 68/push 0x200/imm32/length - 122 68/push 0/imm32/read - 123 68/push 0/imm32/write - 124 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 125 # var word-slice/edx = {0, 0} - 126 68/push 0/imm32/end - 127 68/push 0/imm32/start - 128 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx - 129 # new-data-segment/edi = new-stream(Heap, Segment-size, 1) - 130 # . eax = new-stream(Heap, Segment-size, 1) - 131 # . . push args - 132 68/push 1/imm32 - 133 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Segment-size/disp32 # push *Segment-size - 134 68/push Heap/imm32 - 135 # . . call - 136 e8/call new-stream/disp32 - 137 # . . discard args - 138 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 139 # . edi = eax - 140 89/copy 3/mod/direct 7/rm32/edi . . . 0/r32/eax . . # copy eax to edi - 141 # write(new-data-segment, "== data\n") - 142 # . . push args - 143 68/push "== data\n"/imm32 - 144 57/push-edi - 145 # . . call - 146 e8/call write/disp32 - 147 # . . discard args - 148 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 149 $subx-dquotes:line-loop: - 150 # clear-stream(line) + 89 # + 90 # write(new-data-segment, "== data\n") + 91 # # TODO: When it was originally written dquotes ran before assort, so + 92 # # it assumes lots of segment headers, and emits a new segment of its + 93 # # own. We've since had to reorder the phases (see the explanation + 94 # # for a.assort2 in ntranslate). We could clean up a.assort2 if we + 95 # # conditionally emit the previous line. But this would require + 96 # # teaching dquotes to parse segment headers, so maybe that's not + 97 # # best.. + 98 # + 99 # while true + 100 # clear-stream(line) + 101 # read-line-buffered(in, line) + 102 # if (line->write == 0) break # end of file + 103 # while true + 104 # var word-slice = next-word-or-string(line) + 105 # if slice-empty?(word-slice) # end of line + 106 # break + 107 # if slice-starts-with?(word-slice, "#") # comment + 108 # continue + 109 # if slice-starts-with?(word-slice, '"') # string literal <== what we're here for + 110 # process-string-literal(word-slice, out, new-data-segment) + 111 # else + 112 # write-slice-buffered(out, word-slice) + 113 # write(out, " ") + 114 # write(out, "\n\n") + 115 # write-stream-data(out, new-data-segment) + 116 # flush(out) + 117 # + 118 # . prologue + 119 55/push-ebp + 120 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 121 # . save registers + 122 50/push-eax + 123 51/push-ecx + 124 52/push-edx + 125 53/push-ebx + 126 56/push-esi + 127 57/push-edi + 128 # var line/ecx : (address stream byte) = stream(512) + 129 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp + 130 68/push 0x200/imm32/length + 131 68/push 0/imm32/read + 132 68/push 0/imm32/write + 133 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 134 # var word-slice/edx = {0, 0} + 135 68/push 0/imm32/end + 136 68/push 0/imm32/start + 137 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx + 138 # new-data-segment/edi = new-stream(Heap, Segment-size, 1) + 139 # . eax = new-stream(Heap, Segment-size, 1) + 140 # . . push args + 141 68/push 1/imm32 + 142 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Segment-size/disp32 # push *Segment-size + 143 68/push Heap/imm32 + 144 # . . call + 145 e8/call new-stream/disp32 + 146 # . . discard args + 147 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 148 # . edi = eax + 149 89/copy 3/mod/direct 7/rm32/edi . . . 0/r32/eax . . # copy eax to edi + 150 # write(new-data-segment, "== data\n") 151 # . . push args - 152 51/push-ecx - 153 # . . call - 154 e8/call clear-stream/disp32 - 155 # . . discard args - 156 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 157 # read-line-buffered(in, line) - 158 # . . push args - 159 51/push-ecx - 160 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 161 # . . call - 162 e8/call read-line-buffered/disp32 - 163 # . . discard args - 164 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 165 $subx-dquotes:check0: - 166 # if (line->write == 0) break - 167 81 7/subop/compare 0/mod/indirect 1/rm32/ecx . . . . . 0/imm32 # compare *ecx - 168 0f 84/jump-if-equal $subx-dquotes:break/disp32 - 169 $subx-dquotes:word-loop: - 170 # next-word-or-string(line, word-slice) - 171 # . . push args - 172 52/push-edx - 173 51/push-ecx - 174 # . . call - 175 e8/call next-word-or-string/disp32 - 176 # . . discard args - 177 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 178 $subx-dquotes:check1: - 179 # if (slice-empty?(word-slice)) break - 180 # . eax = slice-empty?(word-slice) - 181 # . . push args - 182 52/push-edx + 152 68/push "== data\n"/imm32 + 153 57/push-edi + 154 # . . call + 155 e8/call write/disp32 + 156 # . . discard args + 157 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 158 $subx-dquotes:line-loop: + 159 # clear-stream(line) + 160 # . . push args + 161 51/push-ecx + 162 # . . call + 163 e8/call clear-stream/disp32 + 164 # . . discard args + 165 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 166 # read-line-buffered(in, line) + 167 # . . push args + 168 51/push-ecx + 169 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 170 # . . call + 171 e8/call read-line-buffered/disp32 + 172 # . . discard args + 173 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 174 $subx-dquotes:check0: + 175 # if (line->write == 0) break + 176 81 7/subop/compare 0/mod/indirect 1/rm32/ecx . . . . . 0/imm32 # compare *ecx + 177 0f 84/jump-if-equal $subx-dquotes:break/disp32 + 178 $subx-dquotes:word-loop: + 179 # next-word-or-string(line, word-slice) + 180 # . . push args + 181 52/push-edx + 182 51/push-ecx 183 # . . call - 184 e8/call slice-empty?/disp32 + 184 e8/call next-word-or-string/disp32 185 # . . discard args - 186 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 187 # . if (eax != 0) break - 188 3d/compare-eax-and 0/imm32 - 189 0f 85/jump-if-not-equal $subx-dquotes:next-line/disp32 - 190 $subx-dquotes:check-for-comment: - 191 # if (slice-starts-with?(word-slice, "#")) continue - 192 # . start/esi = word-slice->start - 193 8b/copy 0/mod/indirect 2/rm32/edx . . . 6/r32/esi . . # copy *edx to esi - 194 # . c/eax = *start - 195 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax - 196 8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL - 197 # . if (eax == '#') continue - 198 3d/compare-eax-and 0x23/imm32/hash - 199 74/jump-if-equal $subx-dquotes:word-loop/disp8 - 200 $subx-dquotes:check-for-string-literal: - 201 # if (slice-starts-with?(word-slice, '"')) continue - 202 3d/compare-eax-and 0x22/imm32/dquote - 203 75/jump-if-not-equal $subx-dquotes:regular-word/disp8 - 204 $subx-dquotes:string-literal: - 205 # process-string-literal(word-slice, out, new-data-segment) - 206 # . . push args - 207 57/push-edi - 208 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 209 52/push-edx - 210 # . . call - 211 e8/call process-string-literal/disp32 - 212 # . . discard args - 213 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 214 # continue - 215 eb/jump $subx-dquotes:next-word/disp8 - 216 $subx-dquotes:regular-word: - 217 # write-slice-buffered(out, word-slice) - 218 # . . push args - 219 52/push-edx - 220 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 221 # . . call - 222 e8/call write-slice-buffered/disp32 - 223 # . . discard args - 224 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 225 # fall through - 226 $subx-dquotes:next-word: - 227 # write-buffered(out, " ") - 228 # . . push args - 229 68/push Space/imm32 - 230 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 231 # . . call - 232 e8/call write-buffered/disp32 - 233 # . . discard args - 234 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 235 # loop - 236 eb/jump $subx-dquotes:word-loop/disp8 - 237 $subx-dquotes:next-line: - 238 # write-buffered(out, "\n") - 239 # . . push args - 240 68/push Newline/imm32 - 241 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 242 # . . call - 243 e8/call write-buffered/disp32 - 244 # . . discard args - 245 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 246 # loop - 247 e9/jump $subx-dquotes:line-loop/disp32 - 248 $subx-dquotes:break: - 249 # write-stream-data(out, new-data-segment) - 250 # . . push args - 251 57/push-edi - 252 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 253 # . . call - 254 e8/call write-stream-data/disp32 - 255 # . . discard args - 256 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 257 # flush(out) - 258 # . . push args - 259 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 260 # . . call - 261 e8/call flush/disp32 - 262 # . . discard args - 263 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 264 $subx-dquotes:end: - 265 # . reclaim locals - 266 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x214/imm32 # add to esp - 267 # . restore registers - 268 5f/pop-to-edi - 269 5e/pop-to-esi - 270 5b/pop-to-ebx - 271 5a/pop-to-edx - 272 59/pop-to-ecx - 273 58/pop-to-eax - 274 # . epilogue - 275 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 276 5d/pop-to-ebp - 277 c3/return - 278 - 279 # Write out 'string-literal' in a new format to 'out-segment', assign it a new - 280 # label, and write the new label out to 'out'. - 281 process-string-literal: # string-literal : (address slice), out : (address buffered-file), out-segment : (address stream) - 282 # pseudocode: - 283 # print(out-segment, "_string#{Next-string-literal}:\n") - 284 # emit-string-literal-data(out-segment, string-literal) - 285 # print(out, "_string#{Next-string-literal}") - 286 # emit-metadata(out, string-literal) - 287 # ++ *Next-string-literal - 288 # - 289 # . prologue - 290 55/push-ebp - 291 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 292 # . save registers - 293 51/push-ecx - 294 # var int32-stream/ecx = stream(10) # number of decimal digits a 32-bit number can have - 295 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa/imm32 # subtract from esp - 296 68/push 0xa/imm32/decimal-digits-in-32bit-number - 297 68/push 0/imm32/read - 298 68/push 0/imm32/write - 299 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 300 # print(out-segment, "_string#{Next-string-literal}:\n") - 301 # . write(out-segment, "_string") - 302 # . . push args - 303 68/push "_string"/imm32 - 304 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 305 # . . call - 306 e8/call write/disp32 - 307 # . . discard args - 308 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 309 # . print-int32-decimal(out-segment, *Next-string-literal) - 310 # . . push args - 311 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-string-literal/disp32 # push *Next-string-literal - 312 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 313 # . . call - 314 e8/call print-int32-decimal/disp32 - 315 # . . discard args - 316 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 317 # . write(out-segment, ":\n") - 318 # . . push args - 319 68/push ":\n"/imm32 - 320 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 321 # . . call - 322 e8/call write/disp32 - 323 # . . discard args - 324 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 325 # emit-string-literal-data(out-segment, string-literal) - 326 # . . push args - 327 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 328 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 329 # . . call - 330 e8/call emit-string-literal-data/disp32 - 331 # . . discard args - 332 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 333 # write(out-segment, "\n") - 334 # . . push args - 335 68/push Newline/imm32 - 336 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 337 # . . call - 338 e8/call write/disp32 - 339 # . . discard args - 340 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 341 # print(out, "_string#{Next-string-literal}") - 342 # . write-buffered(out, "_string") + 186 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 187 $subx-dquotes:check1: + 188 # if (slice-empty?(word-slice)) break + 189 # . eax = slice-empty?(word-slice) + 190 # . . push args + 191 52/push-edx + 192 # . . call + 193 e8/call slice-empty?/disp32 + 194 # . . discard args + 195 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 196 # . if (eax != 0) break + 197 3d/compare-eax-and 0/imm32 + 198 0f 85/jump-if-not-equal $subx-dquotes:next-line/disp32 + 199 $subx-dquotes:check-for-comment: + 200 # if (slice-starts-with?(word-slice, "#")) continue + 201 # . start/esi = word-slice->start + 202 8b/copy 0/mod/indirect 2/rm32/edx . . . 6/r32/esi . . # copy *edx to esi + 203 # . c/eax = *start + 204 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + 205 8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL + 206 # . if (eax == '#') continue + 207 3d/compare-eax-and 0x23/imm32/hash + 208 74/jump-if-equal $subx-dquotes:word-loop/disp8 + 209 $subx-dquotes:check-for-string-literal: + 210 # if (slice-starts-with?(word-slice, '"')) continue + 211 3d/compare-eax-and 0x22/imm32/dquote + 212 75/jump-if-not-equal $subx-dquotes:regular-word/disp8 + 213 $subx-dquotes:string-literal: + 214 # process-string-literal(word-slice, out, new-data-segment) + 215 # . . push args + 216 57/push-edi + 217 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 218 52/push-edx + 219 # . . call + 220 e8/call process-string-literal/disp32 + 221 # . . discard args + 222 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 223 # continue + 224 eb/jump $subx-dquotes:next-word/disp8 + 225 $subx-dquotes:regular-word: + 226 # write-slice-buffered(out, word-slice) + 227 # . . push args + 228 52/push-edx + 229 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 230 # . . call + 231 e8/call write-slice-buffered/disp32 + 232 # . . discard args + 233 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 234 # fall through + 235 $subx-dquotes:next-word: + 236 # write-buffered(out, " ") + 237 # . . push args + 238 68/push Space/imm32 + 239 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 240 # . . call + 241 e8/call write-buffered/disp32 + 242 # . . discard args + 243 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 244 # loop + 245 eb/jump $subx-dquotes:word-loop/disp8 + 246 $subx-dquotes:next-line: + 247 # write-buffered(out, "\n") + 248 # . . push args + 249 68/push Newline/imm32 + 250 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 251 # . . call + 252 e8/call write-buffered/disp32 + 253 # . . discard args + 254 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 255 # loop + 256 e9/jump $subx-dquotes:line-loop/disp32 + 257 $subx-dquotes:break: + 258 # write-stream-data(out, new-data-segment) + 259 # . . push args + 260 57/push-edi + 261 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 262 # . . call + 263 e8/call write-stream-data/disp32 + 264 # . . discard args + 265 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 266 # flush(out) + 267 # . . push args + 268 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 269 # . . call + 270 e8/call flush/disp32 + 271 # . . discard args + 272 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 273 $subx-dquotes:end: + 274 # . reclaim locals + 275 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x214/imm32 # add to esp + 276 # . restore registers + 277 5f/pop-to-edi + 278 5e/pop-to-esi + 279 5b/pop-to-ebx + 280 5a/pop-to-edx + 281 59/pop-to-ecx + 282 58/pop-to-eax + 283 # . epilogue + 284 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 285 5d/pop-to-ebp + 286 c3/return + 287 + 288 # Write out 'string-literal' in a new format to 'out-segment', assign it a new + 289 # label, and write the new label out to 'out'. + 290 process-string-literal: # string-literal : (address slice), out : (address buffered-file), out-segment : (address stream) + 291 # pseudocode: + 292 # print(out-segment, "_string#{Next-string-literal}:\n") + 293 # emit-string-literal-data(out-segment, string-literal) + 294 # print(out, "_string#{Next-string-literal}") + 295 # emit-metadata(out, string-literal) + 296 # ++ *Next-string-literal + 297 # + 298 # . prologue + 299 55/push-ebp + 300 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 301 # . save registers + 302 51/push-ecx + 303 # var int32-stream/ecx = stream(10) # number of decimal digits a 32-bit number can have + 304 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa/imm32 # subtract from esp + 305 68/push 0xa/imm32/decimal-digits-in-32bit-number + 306 68/push 0/imm32/read + 307 68/push 0/imm32/write + 308 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 309 # print(out-segment, "_string#{Next-string-literal}:\n") + 310 # . write(out-segment, "_string") + 311 # . . push args + 312 68/push "_string"/imm32 + 313 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 314 # . . call + 315 e8/call write/disp32 + 316 # . . discard args + 317 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 318 # . print-int32-decimal(out-segment, *Next-string-literal) + 319 # . . push args + 320 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-string-literal/disp32 # push *Next-string-literal + 321 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 322 # . . call + 323 e8/call print-int32-decimal/disp32 + 324 # . . discard args + 325 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 326 # . write(out-segment, ":\n") + 327 # . . push args + 328 68/push ":\n"/imm32 + 329 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 330 # . . call + 331 e8/call write/disp32 + 332 # . . discard args + 333 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 334 # emit-string-literal-data(out-segment, string-literal) + 335 # . . push args + 336 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 337 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 338 # . . call + 339 e8/call emit-string-literal-data/disp32 + 340 # . . discard args + 341 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 342 # write(out-segment, "\n") 343 # . . push args - 344 68/push "_string"/imm32 - 345 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 344 68/push Newline/imm32 + 345 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) 346 # . . call - 347 e8/call write-buffered/disp32 + 347 e8/call write/disp32 348 # . . discard args 349 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 350 # . print-int32-decimal(int32-stream, *Next-string-literal) - 351 # . . push args - 352 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-string-literal/disp32 # push *Next-string-literal - 353 51/push-ecx - 354 # . . call - 355 e8/call print-int32-decimal/disp32 - 356 # . . discard args - 357 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 358 # . write-stream-data(out, int32-stream) - 359 # . . push args - 360 51/push-ecx - 361 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 362 # . . call - 363 e8/call write-stream-data/disp32 - 364 # . . discard args - 365 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 366 # emit-metadata(out, string-literal) - 367 # . . push args - 368 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 369 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 370 # . . call - 371 e8/call emit-metadata/disp32 - 372 # . . discard args - 373 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 374 # ++ *Next-string-literal - 375 ff 0/subop/increment 0/mod/indirect 5/rm32/.disp32 . . . Next-string-literal/disp32 # increment *Num-test-failures - 376 $process-string-literal:end: - 377 # . reclaim locals - 378 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x16/imm32 # add to esp - 379 # . restore registers - 380 59/pop-to-ecx - 381 # . epilogue - 382 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 383 5d/pop-to-ebp - 384 c3/return - 385 - 386 test-subx-dquotes-is-idempotent-by-default: - 387 # . prologue - 388 55/push-ebp - 389 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 390 # setup - 391 # . clear-stream(_test-input-stream) - 392 # . . push args - 393 68/push _test-input-stream/imm32 - 394 # . . call - 395 e8/call clear-stream/disp32 - 396 # . . discard args - 397 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 398 # . clear-stream(_test-input-buffered-file->buffer) - 399 # . . push args - 400 68/push _test-input-buffered-file->buffer/imm32 - 401 # . . call - 402 e8/call clear-stream/disp32 - 403 # . . discard args - 404 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 405 # . clear-stream(_test-output-stream) - 406 # . . push args - 407 68/push _test-output-stream/imm32 - 408 # . . call - 409 e8/call clear-stream/disp32 - 410 # . . discard args - 411 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 412 # . clear-stream(_test-output-buffered-file->buffer) - 413 # . . push args - 414 68/push _test-output-buffered-file->buffer/imm32 - 415 # . . call - 416 e8/call clear-stream/disp32 - 417 # . . discard args - 418 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 419 # initialize input (meta comments in parens) - 420 # # comment 1 - 421 # # comment 2 indented - 422 # == code 0x1 (new segment) - 423 # # comment 3 inside a segment - 424 # 1 - 425 # (empty line) - 426 # 2 3 # comment 4 inline with other contents - 427 # == data 0x2 (new segment) - 428 # 4 5/imm32 - 429 # . write(_test-input-stream, "# comment 1\n") - 430 # . . push args - 431 68/push "# comment 1\n"/imm32 - 432 68/push _test-input-stream/imm32 - 433 # . . call - 434 e8/call write/disp32 - 435 # . . discard args - 436 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 437 # . write(_test-input-stream, " # comment 2 indented\n") - 438 # . . push args - 439 68/push " # comment 2 indented\n"/imm32 - 440 68/push _test-input-stream/imm32 - 441 # . . call - 442 e8/call write/disp32 - 443 # . . discard args - 444 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 445 # . write(_test-input-stream, "== code 0x1\n") - 446 # . . push args - 447 68/push "== code 0x1\n"/imm32 - 448 68/push _test-input-stream/imm32 - 449 # . . call - 450 e8/call write/disp32 - 451 # . . discard args - 452 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 453 # . write(_test-input-stream, "# comment 3 inside a segment\n") - 454 # . . push args - 455 68/push "# comment 3 inside a segment\n"/imm32 - 456 68/push _test-input-stream/imm32 - 457 # . . call - 458 e8/call write/disp32 - 459 # . . discard args - 460 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 461 # . write(_test-input-stream, "1\n") - 462 # . . push args - 463 68/push "1\n"/imm32 - 464 68/push _test-input-stream/imm32 - 465 # . . call - 466 e8/call write/disp32 - 467 # . . discard args - 468 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 469 # . write(_test-input-stream, "\n") # empty line - 470 # . . push args - 471 68/push Newline/imm32 - 472 68/push _test-input-stream/imm32 - 473 # . . call - 474 e8/call write/disp32 - 475 # . . discard args - 476 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 477 # . write(_test-input-stream, "2 3 # comment 4 inline with other contents\n") - 478 # . . push args - 479 68/push "2 3 # comment 4 inline with other contents\n"/imm32 - 480 68/push _test-input-stream/imm32 - 481 # . . call - 482 e8/call write/disp32 - 483 # . . discard args - 484 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 485 # . write(_test-input-stream, "== data 0x2\n") - 486 # . . push args - 487 68/push "== data 0x2\n"/imm32 - 488 68/push _test-input-stream/imm32 - 489 # . . call - 490 e8/call write/disp32 - 491 # . . discard args - 492 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 493 # . write(_test-input-stream, "4 5/imm32\n") - 494 # . . push args - 495 68/push "4 5/imm32\n"/imm32 - 496 68/push _test-input-stream/imm32 - 497 # . . call - 498 e8/call write/disp32 - 499 # . . discard args - 500 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 501 # subx-dquotes(_test-input-buffered-file, _test-output-buffered-file) - 502 # . . push args - 503 68/push _test-output-buffered-file/imm32 - 504 68/push _test-input-buffered-file/imm32 - 505 # . . call - 506 e8/call subx-dquotes/disp32 - 507 # . . discard args - 508 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 509 # . flush(_test-output-buffered-file) - 510 # . . push args - 511 68/push _test-output-buffered-file/imm32 - 512 # . . call - 513 e8/call flush/disp32 - 514 # . . discard args - 515 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 516 # check output - 517 # (comment dropped for now) - 518 # (comment dropped for now) - 519 # == code 0x1 - 520 # (comment dropped for now) - 521 # 1 - 522 # (comment dropped for now) - 523 # 2 3 - 524 # == data 0x2 - 525 # 4 5/imm32 - 526 # We don't care right now what exactly happens to comments. Trailing spaces are also minor details. - 527 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- - 553 # . check-next-stream-line-equal(_test-output-stream, "", msg) - 554 # . . push args - 555 68/push "F - test-subx-dquotes-is-idempotent-by-default/0"/imm32 - 556 68/push ""/imm32 - 557 68/push _test-output-stream/imm32 - 558 # . . call - 559 e8/call check-next-stream-line-equal/disp32 - 560 # . . discard args - 561 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 350 # print(out, "_string#{Next-string-literal}") + 351 # . write-buffered(out, "_string") + 352 # . . push args + 353 68/push "_string"/imm32 + 354 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 355 # . . call + 356 e8/call write-buffered/disp32 + 357 # . . discard args + 358 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 359 # . print-int32-decimal(int32-stream, *Next-string-literal) + 360 # . . push args + 361 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-string-literal/disp32 # push *Next-string-literal + 362 51/push-ecx + 363 # . . call + 364 e8/call print-int32-decimal/disp32 + 365 # . . discard args + 366 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 367 # . write-stream-data(out, int32-stream) + 368 # . . push args + 369 51/push-ecx + 370 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 371 # . . call + 372 e8/call write-stream-data/disp32 + 373 # . . discard args + 374 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 375 # emit-metadata(out, string-literal) + 376 # . . push args + 377 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 378 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 379 # . . call + 380 e8/call emit-metadata/disp32 + 381 # . . discard args + 382 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 383 # ++ *Next-string-literal + 384 ff 0/subop/increment 0/mod/indirect 5/rm32/.disp32 . . . Next-string-literal/disp32 # increment *Num-test-failures + 385 $process-string-literal:end: + 386 # . reclaim locals + 387 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x16/imm32 # add to esp + 388 # . restore registers + 389 59/pop-to-ecx + 390 # . epilogue + 391 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 392 5d/pop-to-ebp + 393 c3/return + 394 + 395 test-subx-dquotes-is-idempotent-by-default: + 396 # . prologue + 397 55/push-ebp + 398 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 399 # setup + 400 # . clear-stream(_test-input-stream) + 401 # . . push args + 402 68/push _test-input-stream/imm32 + 403 # . . call + 404 e8/call clear-stream/disp32 + 405 # . . discard args + 406 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 407 # . clear-stream(_test-input-buffered-file->buffer) + 408 # . . push args + 409 68/push _test-input-buffered-file->buffer/imm32 + 410 # . . call + 411 e8/call clear-stream/disp32 + 412 # . . discard args + 413 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 414 # . clear-stream(_test-output-stream) + 415 # . . push args + 416 68/push _test-output-stream/imm32 + 417 # . . call + 418 e8/call clear-stream/disp32 + 419 # . . discard args + 420 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 421 # . clear-stream(_test-output-buffered-file->buffer) + 422 # . . push args + 423 68/push _test-output-buffered-file->buffer/imm32 + 424 # . . call + 425 e8/call clear-stream/disp32 + 426 # . . discard args + 427 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 428 # initialize input (meta comments in parens) + 429 # # comment 1 + 430 # # comment 2 indented + 431 # == code 0x1 (new segment) + 432 # # comment 3 inside a segment + 433 # 1 + 434 # (empty line) + 435 # 2 3 # comment 4 inline with other contents + 436 # == data 0x2 (new segment) + 437 # 4 5/imm32 + 438 # . write(_test-input-stream, "# comment 1\n") + 439 # . . push args + 440 68/push "# comment 1\n"/imm32 + 441 68/push _test-input-stream/imm32 + 442 # . . call + 443 e8/call write/disp32 + 444 # . . discard args + 445 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 446 # . write(_test-input-stream, " # comment 2 indented\n") + 447 # . . push args + 448 68/push " # comment 2 indented\n"/imm32 + 449 68/push _test-input-stream/imm32 + 450 # . . call + 451 e8/call write/disp32 + 452 # . . discard args + 453 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 454 # . write(_test-input-stream, "== code 0x1\n") + 455 # . . push args + 456 68/push "== code 0x1\n"/imm32 + 457 68/push _test-input-stream/imm32 + 458 # . . call + 459 e8/call write/disp32 + 460 # . . discard args + 461 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 462 # . write(_test-input-stream, "# comment 3 inside a segment\n") + 463 # . . push args + 464 68/push "# comment 3 inside a segment\n"/imm32 + 465 68/push _test-input-stream/imm32 + 466 # . . call + 467 e8/call write/disp32 + 468 # . . discard args + 469 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 470 # . write(_test-input-stream, "1\n") + 471 # . . push args + 472 68/push "1\n"/imm32 + 473 68/push _test-input-stream/imm32 + 474 # . . call + 475 e8/call write/disp32 + 476 # . . discard args + 477 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 478 # . write(_test-input-stream, "\n") # empty line + 479 # . . push args + 480 68/push Newline/imm32 + 481 68/push _test-input-stream/imm32 + 482 # . . call + 483 e8/call write/disp32 + 484 # . . discard args + 485 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 486 # . write(_test-input-stream, "2 3 # comment 4 inline with other contents\n") + 487 # . . push args + 488 68/push "2 3 # comment 4 inline with other contents\n"/imm32 + 489 68/push _test-input-stream/imm32 + 490 # . . call + 491 e8/call write/disp32 + 492 # . . discard args + 493 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 494 # . write(_test-input-stream, "== data 0x2\n") + 495 # . . push args + 496 68/push "== data 0x2\n"/imm32 + 497 68/push _test-input-stream/imm32 + 498 # . . call + 499 e8/call write/disp32 + 500 # . . discard args + 501 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 502 # . write(_test-input-stream, "4 5/imm32\n") + 503 # . . push args + 504 68/push "4 5/imm32\n"/imm32 + 505 68/push _test-input-stream/imm32 + 506 # . . call + 507 e8/call write/disp32 + 508 # . . discard args + 509 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 510 # subx-dquotes(_test-input-buffered-file, _test-output-buffered-file) + 511 # . . push args + 512 68/push _test-output-buffered-file/imm32 + 513 68/push _test-input-buffered-file/imm32 + 514 # . . call + 515 e8/call subx-dquotes/disp32 + 516 # . . discard args + 517 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 518 # . flush(_test-output-buffered-file) + 519 # . . push args + 520 68/push _test-output-buffered-file/imm32 + 521 # . . call + 522 e8/call flush/disp32 + 523 # . . discard args + 524 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 525 # check output + 526 # (comment dropped for now) + 527 # (comment dropped for now) + 528 # == code 0x1 + 529 # (comment dropped for now) + 530 # 1 + 531 # (comment dropped for now) + 532 # 2 3 + 533 # == data 0x2 + 534 # 4 5/imm32 + 535 # We don't care right now what exactly happens to comments. Trailing spaces are also minor details. + 536 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- 562 # . check-next-stream-line-equal(_test-output-stream, "", msg) 563 # . . push args - 564 68/push "F - test-subx-dquotes-is-idempotent-by-default/1"/imm32 + 564 68/push "F - test-subx-dquotes-is-idempotent-by-default/0"/imm32 565 68/push ""/imm32 566 68/push _test-output-stream/imm32 567 # . . call 568 e8/call check-next-stream-line-equal/disp32 569 # . . discard args 570 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 571 # . check-next-stream-line-equal(_test-output-stream, "== code 0x1 ", msg) + 571 # . check-next-stream-line-equal(_test-output-stream, "", msg) 572 # . . push args - 573 68/push "F - test-subx-dquotes-is-idempotent-by-default/2"/imm32 - 574 68/push "== code 0x1 "/imm32 + 573 68/push "F - test-subx-dquotes-is-idempotent-by-default/1"/imm32 + 574 68/push ""/imm32 575 68/push _test-output-stream/imm32 576 # . . call 577 e8/call check-next-stream-line-equal/disp32 578 # . . discard args 579 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 580 # . check-next-stream-line-equal(_test-output-stream, "", msg) + 580 # . check-next-stream-line-equal(_test-output-stream, "== code 0x1 ", msg) 581 # . . push args - 582 68/push "F - test-subx-dquotes-is-idempotent-by-default/3"/imm32 - 583 68/push ""/imm32 + 582 68/push "F - test-subx-dquotes-is-idempotent-by-default/2"/imm32 + 583 68/push "== code 0x1 "/imm32 584 68/push _test-output-stream/imm32 585 # . . call 586 e8/call check-next-stream-line-equal/disp32 587 # . . discard args 588 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 589 # . check-next-stream-line-equal(_test-output-stream, "1 ", msg) + 589 # . check-next-stream-line-equal(_test-output-stream, "", msg) 590 # . . push args - 591 68/push "F - test-subx-dquotes-is-idempotent-by-default/4"/imm32 - 592 68/push "1 "/imm32 + 591 68/push "F - test-subx-dquotes-is-idempotent-by-default/3"/imm32 + 592 68/push ""/imm32 593 68/push _test-output-stream/imm32 594 # . . call 595 e8/call check-next-stream-line-equal/disp32 596 # . . discard args 597 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 598 # . check-next-stream-line-equal(_test-output-stream, "", msg) + 598 # . check-next-stream-line-equal(_test-output-stream, "1 ", msg) 599 # . . push args - 600 68/push "F - test-subx-dquotes-is-idempotent-by-default/5"/imm32 - 601 68/push ""/imm32 + 600 68/push "F - test-subx-dquotes-is-idempotent-by-default/4"/imm32 + 601 68/push "1 "/imm32 602 68/push _test-output-stream/imm32 603 # . . call 604 e8/call check-next-stream-line-equal/disp32 605 # . . discard args 606 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 607 # . check-next-stream-line-equal(_test-output-stream, "2 3 ", msg) + 607 # . check-next-stream-line-equal(_test-output-stream, "", msg) 608 # . . push args - 609 68/push "F - test-subx-dquotes-is-idempotent-by-default/6"/imm32 - 610 68/push "2 3 "/imm32 + 609 68/push "F - test-subx-dquotes-is-idempotent-by-default/5"/imm32 + 610 68/push ""/imm32 611 68/push _test-output-stream/imm32 612 # . . call 613 e8/call check-next-stream-line-equal/disp32 614 # . . discard args 615 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 616 # . check-next-stream-line-equal(_test-output-stream, "== data 0x2 ", msg) + 616 # . check-next-stream-line-equal(_test-output-stream, "2 3 ", msg) 617 # . . push args - 618 68/push "F - test-subx-dquotes-is-idempotent-by-default/7"/imm32 - 619 68/push "== data 0x2 "/imm32 + 618 68/push "F - test-subx-dquotes-is-idempotent-by-default/6"/imm32 + 619 68/push "2 3 "/imm32 620 68/push _test-output-stream/imm32 621 # . . call 622 e8/call check-next-stream-line-equal/disp32 623 # . . discard args 624 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 625 # . check-next-stream-line-equal(_test-output-stream, "4 5/imm32 ", msg) + 625 # . check-next-stream-line-equal(_test-output-stream, "== data 0x2 ", msg) 626 # . . push args - 627 68/push "F - test-subx-dquotes-is-idempotent-by-default/8"/imm32 - 628 68/push "4 5/imm32 "/imm32 + 627 68/push "F - test-subx-dquotes-is-idempotent-by-default/7"/imm32 + 628 68/push "== data 0x2 "/imm32 629 68/push _test-output-stream/imm32 630 # . . call 631 e8/call check-next-stream-line-equal/disp32 632 # . . discard args 633 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 634 # . epilogue - 635 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 636 5d/pop-to-ebp - 637 c3/return - 638 - 639 test-subx-dquotes-processes-string-literals: - 640 # . prologue - 641 55/push-ebp - 642 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 643 # setup - 644 # . clear-stream(_test-input-stream) - 645 # . . push args - 646 68/push _test-input-stream/imm32 - 647 # . . call - 648 e8/call clear-stream/disp32 - 649 # . . discard args - 650 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 651 # . clear-stream(_test-input-buffered-file->buffer) - 652 # . . push args - 653 68/push _test-input-buffered-file->buffer/imm32 - 654 # . . call - 655 e8/call clear-stream/disp32 - 656 # . . discard args - 657 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 658 # . clear-stream(_test-output-stream) - 659 # . . push args - 660 68/push _test-output-stream/imm32 - 661 # . . call - 662 e8/call clear-stream/disp32 - 663 # . . discard args - 664 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 665 # . clear-stream(_test-output-buffered-file->buffer) - 666 # . . push args - 667 68/push _test-output-buffered-file->buffer/imm32 - 668 # . . call - 669 e8/call clear-stream/disp32 - 670 # . . discard args - 671 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 672 # initialize input (meta comments in parens) - 673 # == code (new segment) - 674 # 1 "a"/x - 675 # 2 "bc"/y - 676 68/push "== code 0x1\n"/imm32 - 677 68/push _test-input-stream/imm32 - 678 # . . call - 679 e8/call write/disp32 - 680 # . . discard args - 681 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 682 # . write(_test-input-stream, "1 \"a\"/x\n") - 683 # . . push args - 684 68/push "1 \"a\"/x\n"/imm32 - 685 68/push _test-input-stream/imm32 - 686 # . . call - 687 e8/call write/disp32 - 688 # . . discard args - 689 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 690 # . write(_test-input-stream, "2 \"bc\"/y\n") - 691 # . . push args - 692 68/push "2 \"bc\"/y\n"/imm32 - 693 68/push _test-input-stream/imm32 - 694 # . . call - 695 e8/call write/disp32 - 696 # . . discard args - 697 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 698 # subx-dquotes(_test-input-buffered-file, _test-output-buffered-file) - 699 # . . push args - 700 68/push _test-output-buffered-file/imm32 - 701 68/push _test-input-buffered-file/imm32 - 702 # . . call - 703 e8/call subx-dquotes/disp32 - 704 # . . discard args - 705 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 706 # . flush(_test-output-buffered-file) - 707 # . . push args - 708 68/push _test-output-buffered-file/imm32 - 709 # . . call - 710 e8/call flush/disp32 - 711 # . . discard args - 712 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 713 # check output - 714 # == code 0x1 - 715 # 1 _string1/x - 716 # 2 _string2/y - 717 # == data - 718 # _string1: - 719 # 1/imm32 61/a - 720 # _string2: - 721 # 2/imm32 62/b 63/c - 722 # We don't care right now what exactly happens to comments. Trailing spaces are also minor details. - 723 # - 724 # Open question: how to make this check more robust. - 725 # We don't actually care what the auto-generated string variables are - 726 # called. We just want to make sure instructions using string literals - 727 # switch to a string variable with the right value. - 728 # (Modifying string literals completely off the radar for now.) - 729 +-- 33 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- - 762 # . check-next-stream-line-equal(_test-output-stream, "== code 0x1 ", msg) - 763 # . . push args - 764 68/push "F - test-subx-dquotes-processes-string-literals/0"/imm32 - 765 68/push "== code 0x1 "/imm32 - 766 68/push _test-output-stream/imm32 - 767 # . . call - 768 e8/call check-next-stream-line-equal/disp32 - 769 # . . discard args - 770 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 771 # . check-next-stream-line-equal(_test-output-stream, "1 _string1/x ", msg) + 634 # . check-next-stream-line-equal(_test-output-stream, "4 5/imm32 ", msg) + 635 # . . push args + 636 68/push "F - test-subx-dquotes-is-idempotent-by-default/8"/imm32 + 637 68/push "4 5/imm32 "/imm32 + 638 68/push _test-output-stream/imm32 + 639 # . . call + 640 e8/call check-next-stream-line-equal/disp32 + 641 # . . discard args + 642 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 643 # . epilogue + 644 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 645 5d/pop-to-ebp + 646 c3/return + 647 + 648 test-subx-dquotes-processes-string-literals: + 649 # . prologue + 650 55/push-ebp + 651 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 652 # setup + 653 # . clear-stream(_test-input-stream) + 654 # . . push args + 655 68/push _test-input-stream/imm32 + 656 # . . call + 657 e8/call clear-stream/disp32 + 658 # . . discard args + 659 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 660 # . clear-stream(_test-input-buffered-file->buffer) + 661 # . . push args + 662 68/push _test-input-buffered-file->buffer/imm32 + 663 # . . call + 664 e8/call clear-stream/disp32 + 665 # . . discard args + 666 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 667 # . clear-stream(_test-output-stream) + 668 # . . push args + 669 68/push _test-output-stream/imm32 + 670 # . . call + 671 e8/call clear-stream/disp32 + 672 # . . discard args + 673 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 674 # . clear-stream(_test-output-buffered-file->buffer) + 675 # . . push args + 676 68/push _test-output-buffered-file->buffer/imm32 + 677 # . . call + 678 e8/call clear-stream/disp32 + 679 # . . discard args + 680 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 681 # initialize input (meta comments in parens) + 682 # == code (new segment) + 683 # 1 "a"/x + 684 # 2 "bc"/y + 685 68/push "== code 0x1\n"/imm32 + 686 68/push _test-input-stream/imm32 + 687 # . . call + 688 e8/call write/disp32 + 689 # . . discard args + 690 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 691 # . write(_test-input-stream, "1 \"a\"/x\n") + 692 # . . push args + 693 68/push "1 \"a\"/x\n"/imm32 + 694 68/push _test-input-stream/imm32 + 695 # . . call + 696 e8/call write/disp32 + 697 # . . discard args + 698 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 699 # . write(_test-input-stream, "2 \"bc\"/y\n") + 700 # . . push args + 701 68/push "2 \"bc\"/y\n"/imm32 + 702 68/push _test-input-stream/imm32 + 703 # . . call + 704 e8/call write/disp32 + 705 # . . discard args + 706 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 707 # subx-dquotes(_test-input-buffered-file, _test-output-buffered-file) + 708 # . . push args + 709 68/push _test-output-buffered-file/imm32 + 710 68/push _test-input-buffered-file/imm32 + 711 # . . call + 712 e8/call subx-dquotes/disp32 + 713 # . . discard args + 714 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 715 # . flush(_test-output-buffered-file) + 716 # . . push args + 717 68/push _test-output-buffered-file/imm32 + 718 # . . call + 719 e8/call flush/disp32 + 720 # . . discard args + 721 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 722 # check output + 723 # == code 0x1 + 724 # 1 _string1/x + 725 # 2 _string2/y + 726 # == data + 727 # _string1: + 728 # 1/imm32 61/a + 729 # _string2: + 730 # 2/imm32 62/b 63/c + 731 # We don't care right now what exactly happens to comments. Trailing spaces are also minor details. + 732 # + 733 # Open question: how to make this check more robust. + 734 # We don't actually care what the auto-generated string variables are + 735 # called. We just want to make sure instructions using string literals + 736 # switch to a string variable with the right value. + 737 # (Modifying string literals completely off the radar for now.) + 738 +-- 33 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- + 771 # . check-next-stream-line-equal(_test-output-stream, "== code 0x1 ", msg) 772 # . . push args - 773 68/push "F - test-subx-dquotes-processes-string-literals/1"/imm32 - 774 68/push "1 _string1/x "/imm32 + 773 68/push "F - test-subx-dquotes-processes-string-literals/0"/imm32 + 774 68/push "== code 0x1 "/imm32 775 68/push _test-output-stream/imm32 776 # . . call 777 e8/call check-next-stream-line-equal/disp32 778 # . . discard args 779 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 780 # . check-next-stream-line-equal(_test-output-stream, "2 _string2/y ", msg) + 780 # . check-next-stream-line-equal(_test-output-stream, "1 _string1/x ", msg) 781 # . . push args - 782 68/push "F - test-subx-dquotes-processes-string-literals/2"/imm32 - 783 68/push "2 _string2/y "/imm32 + 782 68/push "F - test-subx-dquotes-processes-string-literals/1"/imm32 + 783 68/push "1 _string1/x "/imm32 784 68/push _test-output-stream/imm32 785 # . . call 786 e8/call check-next-stream-line-equal/disp32 787 # . . discard args 788 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 789 # . check-next-stream-line-equal(_test-output-stream, "== data", msg) + 789 # . check-next-stream-line-equal(_test-output-stream, "2 _string2/y ", msg) 790 # . . push args - 791 68/push "F - test-subx-dquotes-processes-string-literals/3"/imm32 - 792 68/push "== data"/imm32 + 791 68/push "F - test-subx-dquotes-processes-string-literals/2"/imm32 + 792 68/push "2 _string2/y "/imm32 793 68/push _test-output-stream/imm32 794 # . . call 795 e8/call check-next-stream-line-equal/disp32 796 # . . discard args 797 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 798 # . check-next-stream-line-equal(_test-output-stream, "_string1: ", msg) + 798 # . check-next-stream-line-equal(_test-output-stream, "== data", msg) 799 # . . push args - 800 68/push "F - test-subx-dquotes-processes-string-literals/4"/imm32 - 801 68/push "_string1:"/imm32 + 800 68/push "F - test-subx-dquotes-processes-string-literals/3"/imm32 + 801 68/push "== data"/imm32 802 68/push _test-output-stream/imm32 803 # . . call 804 e8/call check-next-stream-line-equal/disp32 805 # . . discard args 806 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 807 # . check-next-stream-line-equal(_test-output-stream, "1/imm32 61/a ", msg) + 807 # . check-next-stream-line-equal(_test-output-stream, "_string1: ", msg) 808 # . . push args - 809 68/push "F - test-subx-dquotes-processes-string-literals/5"/imm32 - 810 68/push "0x00000001/imm32 61/a "/imm32 + 809 68/push "F - test-subx-dquotes-processes-string-literals/4"/imm32 + 810 68/push "_string1:"/imm32 811 68/push _test-output-stream/imm32 812 # . . call 813 e8/call check-next-stream-line-equal/disp32 814 # . . discard args 815 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 816 # . check-next-stream-line-equal(_test-output-stream, "_string2: ", msg) + 816 # . check-next-stream-line-equal(_test-output-stream, "1/imm32 61/a ", msg) 817 # . . push args - 818 68/push "F - test-subx-dquotes-processes-string-literals/6"/imm32 - 819 68/push "_string2:"/imm32 + 818 68/push "F - test-subx-dquotes-processes-string-literals/5"/imm32 + 819 68/push "0x00000001/imm32 61/a "/imm32 820 68/push _test-output-stream/imm32 821 # . . call 822 e8/call check-next-stream-line-equal/disp32 823 # . . discard args 824 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 825 # . check-next-stream-line-equal(_test-output-stream, "2/imm32 62/b 63/c ", msg) + 825 # . check-next-stream-line-equal(_test-output-stream, "_string2: ", msg) 826 # . . push args - 827 68/push "F - test-subx-dquotes-processes-string-literals/7"/imm32 - 828 68/push "0x00000002/imm32 62/b 63/c "/imm32 + 827 68/push "F - test-subx-dquotes-processes-string-literals/6"/imm32 + 828 68/push "_string2:"/imm32 829 68/push _test-output-stream/imm32 830 # . . call 831 e8/call check-next-stream-line-equal/disp32 832 # . . discard args 833 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 834 # . epilogue - 835 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 836 5d/pop-to-ebp - 837 c3/return - 838 - 839 # generate the data segment contents byte by byte for a given slice - 840 emit-string-literal-data: # out : (address stream), word : (address slice) - 841 # pseudocode - 842 # len = string-length-at-start-of-slice(word->start, word->end) - 843 # print(out, "#{len}/imm32 ") - 844 # curr = word->start - 845 # ++curr # skip '"' - 846 # idx = 0 - 847 # while true - 848 # if (curr >= word->end) break - 849 # c = *curr - 850 # if (c == '"') break - 851 # if (c == '\') { - 852 # ++curr - 853 # c = *curr - 854 # if (c == 'n') - 855 # c = newline - 856 # } - 857 # append-byte-hex(out, c) - 858 # if c is alphanumeric: - 859 # write(out, "/") - 860 # append-byte(out, c) - 861 # write(out, " ") - 862 # ++curr - 863 # ++idx - 864 # if idx >= 0x40 - 865 # idx = 0 - 866 # write(out, "\n") - 867 # - 868 # . prologue - 869 55/push-ebp - 870 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 871 # . save registers - 872 50/push-eax - 873 51/push-ecx - 874 52/push-edx - 875 53/push-ebx - 876 56/push-esi - 877 # esi = word - 878 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - 879 # idx/ebx = 0 - 880 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx - 881 # curr/edx = word->start - 882 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx - 883 # max/esi = word->end - 884 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi - 885 $emit-string-literal-data:emit-length: - 886 # len/eax = string-length-at-start-of-slice(word->start, word->end) - 887 # . . push args - 888 56/push-esi - 889 52/push-edx - 890 # . . call - 891 e8/call string-length-at-start-of-slice/disp32 - 892 # . . discard args - 893 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 894 # print(out, "#{len}/imm32 ") - 895 # . print-int32(out, len) + 834 # . check-next-stream-line-equal(_test-output-stream, "2/imm32 62/b 63/c ", msg) + 835 # . . push args + 836 68/push "F - test-subx-dquotes-processes-string-literals/7"/imm32 + 837 68/push "0x00000002/imm32 62/b 63/c "/imm32 + 838 68/push _test-output-stream/imm32 + 839 # . . call + 840 e8/call check-next-stream-line-equal/disp32 + 841 # . . discard args + 842 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 843 # . epilogue + 844 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 845 5d/pop-to-ebp + 846 c3/return + 847 + 848 # generate the data segment contents byte by byte for a given slice + 849 emit-string-literal-data: # out : (address stream), word : (address slice) + 850 # pseudocode + 851 # len = string-length-at-start-of-slice(word->start, word->end) + 852 # print(out, "#{len}/imm32 ") + 853 # curr = word->start + 854 # ++curr # skip '"' + 855 # idx = 0 + 856 # while true + 857 # if (curr >= word->end) break + 858 # c = *curr + 859 # if (c == '"') break + 860 # if (c == '\') { + 861 # ++curr + 862 # c = *curr + 863 # if (c == 'n') + 864 # c = newline + 865 # } + 866 # append-byte-hex(out, c) + 867 # if c is alphanumeric: + 868 # write(out, "/") + 869 # append-byte(out, c) + 870 # write(out, " ") + 871 # ++curr + 872 # ++idx + 873 # if idx >= 0x40 + 874 # idx = 0 + 875 # write(out, "\n") + 876 # + 877 # . prologue + 878 55/push-ebp + 879 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 880 # . save registers + 881 50/push-eax + 882 51/push-ecx + 883 52/push-edx + 884 53/push-ebx + 885 56/push-esi + 886 # esi = word + 887 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi + 888 # idx/ebx = 0 + 889 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx + 890 # curr/edx = word->start + 891 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx + 892 # max/esi = word->end + 893 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi + 894 $emit-string-literal-data:emit-length: + 895 # len/eax = string-length-at-start-of-slice(word->start, word->end) 896 # . . push args - 897 50/push-eax - 898 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 897 56/push-esi + 898 52/push-edx 899 # . . call - 900 e8/call print-int32/disp32 + 900 e8/call string-length-at-start-of-slice/disp32 901 # . . discard args 902 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 903 # . write(out, "/imm32 ") - 904 # . . push args - 905 68/push "/imm32 "/imm32 - 906 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 907 # . . call - 908 e8/call write/disp32 - 909 # . . discard args - 910 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 911 $emit-string-literal-data:loop-init: - 912 # ++curr # skip initial '"' - 913 42/increment-edx - 914 # c/ecx = 0 - 915 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx - 916 $emit-string-literal-data:loop: - 917 # if (curr >= max) break - 918 39/compare 3/mod/direct 2/rm32/edx . . . 6/r32/esi . . # compare edx with esi - 919 0f 83/jump-if-greater-or-equal-unsigned $emit-string-literal-data:end/disp32 - 920 # CL = *curr - 921 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 1/r32/CL . . # copy byte at *edx to CL - 922 # if (c == '"') break - 923 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x22/imm32/dquote # compare ecx - 924 0f 84/jump-if-equal $emit-string-literal-data:end/disp32 - 925 # if (c != '\') goto emit - 926 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x5c/imm32/backslash # compare ecx - 927 75/jump-if-not-equal $emit-string-literal-data:emit/disp8 - 928 # ++curr - 929 42/increment-edx - 930 # if (curr >= max) break - 931 39/compare 3/mod/direct 2/rm32/edx . . . 6/r32/esi . . # compare edx with esi - 932 0f 83/jump-if-greater-or-equal-unsigned $emit-string-literal-data:end/disp32 - 933 # c = *curr - 934 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 1/r32/CL . . # copy byte at *edx to CL - 935 # if (c == 'n') c = newline - 936 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x6e/imm32/n # compare ecx - 937 75/jump-if-not-equal $emit-string-literal-data:emit/disp8 - 938 b9/copy-to-ecx 0x0a/imm32/newline - 939 $emit-string-literal-data:emit: - 940 # append-byte-hex(out, CL) - 941 # . . push args - 942 51/push-ecx - 943 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 944 # . . call - 945 e8/call append-byte-hex/disp32 - 946 # . . discard args - 947 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 948 # if (is-alphanumeric?(*curr)) print(out, "/#{*curr}") - 949 # . eax = is-alphanumeric?(CL) + 903 # print(out, "#{len}/imm32 ") + 904 # . print-int32(out, len) + 905 # . . push args + 906 50/push-eax + 907 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 908 # . . call + 909 e8/call print-int32/disp32 + 910 # . . discard args + 911 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 912 # . write(out, "/imm32 ") + 913 # . . push args + 914 68/push "/imm32 "/imm32 + 915 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 916 # . . call + 917 e8/call write/disp32 + 918 # . . discard args + 919 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 920 $emit-string-literal-data:loop-init: + 921 # ++curr # skip initial '"' + 922 42/increment-edx + 923 # c/ecx = 0 + 924 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx + 925 $emit-string-literal-data:loop: + 926 # if (curr >= max) break + 927 39/compare 3/mod/direct 2/rm32/edx . . . 6/r32/esi . . # compare edx with esi + 928 0f 83/jump-if-greater-or-equal-unsigned $emit-string-literal-data:end/disp32 + 929 # CL = *curr + 930 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 1/r32/CL . . # copy byte at *edx to CL + 931 # if (c == '"') break + 932 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x22/imm32/dquote # compare ecx + 933 0f 84/jump-if-equal $emit-string-literal-data:end/disp32 + 934 # if (c != '\') goto emit + 935 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x5c/imm32/backslash # compare ecx + 936 75/jump-if-not-equal $emit-string-literal-data:emit/disp8 + 937 # ++curr + 938 42/increment-edx + 939 # if (curr >= max) break + 940 39/compare 3/mod/direct 2/rm32/edx . . . 6/r32/esi . . # compare edx with esi + 941 0f 83/jump-if-greater-or-equal-unsigned $emit-string-literal-data:end/disp32 + 942 # c = *curr + 943 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 1/r32/CL . . # copy byte at *edx to CL + 944 # if (c == 'n') c = newline + 945 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x6e/imm32/n # compare ecx + 946 75/jump-if-not-equal $emit-string-literal-data:emit/disp8 + 947 b9/copy-to-ecx 0x0a/imm32/newline + 948 $emit-string-literal-data:emit: + 949 # append-byte-hex(out, CL) 950 # . . push args 951 51/push-ecx - 952 # . . call - 953 e8/call is-alphanumeric?/disp32 - 954 # . . discard args - 955 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 956 # . if (eax == 0) goto char-done - 957 3d/compare-eax-and 0/imm32 - 958 74/jump-if-equal $emit-string-literal-data:char-done/disp8 - 959 # . write(out, "/") - 960 # . . push args - 961 68/push Slash/imm32 - 962 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 963 # . . call - 964 e8/call write/disp32 - 965 # . . discard args - 966 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 967 # . append-byte(out, *curr) - 968 # . . push args - 969 51/push-ecx - 970 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 971 # . . call - 972 e8/call append-byte/disp32 - 973 # . . discard args - 974 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 975 $emit-string-literal-data:char-done: - 976 # write(out, " ") + 952 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 953 # . . call + 954 e8/call append-byte-hex/disp32 + 955 # . . discard args + 956 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 957 # if (is-alphanumeric?(*curr)) print(out, "/#{*curr}") + 958 # . eax = is-alphanumeric?(CL) + 959 # . . push args + 960 51/push-ecx + 961 # . . call + 962 e8/call is-alphanumeric?/disp32 + 963 # . . discard args + 964 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 965 # . if (eax == 0) goto char-done + 966 3d/compare-eax-and 0/imm32 + 967 74/jump-if-equal $emit-string-literal-data:char-done/disp8 + 968 # . write(out, "/") + 969 # . . push args + 970 68/push Slash/imm32 + 971 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 972 # . . call + 973 e8/call write/disp32 + 974 # . . discard args + 975 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 976 # . append-byte(out, *curr) 977 # . . push args - 978 68/push Space/imm32 + 978 51/push-ecx 979 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) 980 # . . call - 981 e8/call write/disp32 + 981 e8/call append-byte/disp32 982 # . . discard args 983 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 984 # ++curr - 985 42/increment-edx - 986 # ++ idx - 987 43/increment-ebx - 988 # if (idx < 0x40) continue - 989 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x40/imm32 # compare ebx - 990 7c/jump-if-lesser $emit-string-literal-data:next-char/disp8 - 991 # idx = 0 - 992 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx - 993 # write(out, "\n") - 994 # . . push args - 995 68/push Newline/imm32 - 996 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 997 # . . call - 998 e8/call write/disp32 - 999 # . . discard args -1000 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1001 $emit-string-literal-data:next-char: -1002 e9/jump $emit-string-literal-data:loop/disp32 -1003 $emit-string-literal-data:end: -1004 # . restore registers -1005 5e/pop-to-esi -1006 5b/pop-to-ebx -1007 5a/pop-to-edx -1008 59/pop-to-ecx -1009 58/pop-to-eax -1010 # . epilogue -1011 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1012 5d/pop-to-ebp -1013 c3/return -1014 -1015 is-alphanumeric?: # c : int -> eax : boolean -1016 # . prologue -1017 55/push-ebp -1018 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1019 # eax = c -1020 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax -1021 # if (eax < '0') return false -1022 3d/compare-eax-with 0x30/imm32/0 -1023 7c/jump-if-lesser $is-alphanumeric?:false/disp8 -1024 # if (eax <= '9') return true -1025 3d/compare-eax-with 0x39/imm32/9 -1026 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 -1027 # if (eax < 'A') return false -1028 3d/compare-eax-with 0x41/imm32/A -1029 7c/jump-if-lesser $is-alphanumeric?:false/disp8 -1030 # if (eax <= 'Z') return true -1031 3d/compare-eax-with 0x5a/imm32/Z -1032 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 -1033 # if (eax < 'a') return false -1034 3d/compare-eax-with 0x61/imm32/a -1035 7c/jump-if-lesser $is-alphanumeric?:false/disp8 -1036 # if (eax <= 'z') return true -1037 3d/compare-eax-with 0x7a/imm32/z -1038 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 -1039 # return false -1040 $is-alphanumeric?:false: -1041 b8/copy-to-eax 0/imm32/false -1042 eb/jump $is-alphanumeric?:end/disp8 -1043 $is-alphanumeric?:true: -1044 b8/copy-to-eax 1/imm32/true -1045 $is-alphanumeric?:end: -1046 # . epilogue -1047 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1048 5d/pop-to-ebp -1049 c3/return -1050 -1051 test-emit-string-literal-data: -1052 # . prologue -1053 55/push-ebp -1054 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1055 # setup -1056 # . clear-stream(_test-output-stream) -1057 # . . push args -1058 68/push _test-output-stream/imm32 -1059 # . . call -1060 e8/call clear-stream/disp32 -1061 # . . discard args -1062 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1063 # var slice/ecx = '"abc"/d' -1064 68/push _test-slice-abc-limit/imm32 -1065 68/push _test-slice-abc/imm32 -1066 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1067 # emit-string-literal-data(_test-output-stream, slice) -1068 # . . push args -1069 51/push-ecx -1070 68/push _test-output-stream/imm32 -1071 # . . call -1072 e8/call emit-string-literal-data/disp32 -1073 # . . discard args -1074 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1075 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1101 # . check-stream-equal(_test-output-stream, "3/imm32 61/a 62/b 63/c ", msg) -1102 # . . push args -1103 68/push "F - test-emit-string-literal-data"/imm32 -1104 68/push "0x00000003/imm32 61/a 62/b 63/c "/imm32 -1105 68/push _test-output-stream/imm32 -1106 # . . call -1107 e8/call check-stream-equal/disp32 -1108 # . . discard args -1109 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1110 # . epilogue -1111 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1112 5d/pop-to-ebp -1113 c3/return -1114 -1115 test-emit-string-literal-data-empty: -1116 # . prologue -1117 55/push-ebp -1118 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1119 # setup -1120 # . clear-stream(_test-output-stream) -1121 # . . push args -1122 68/push _test-output-stream/imm32 -1123 # . . call -1124 e8/call clear-stream/disp32 -1125 # . . discard args -1126 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1127 # var slice/ecx = '""' -1128 68/push 0/imm32/end -1129 68/push 0/imm32/start -1130 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1131 # emit-string-literal-data(_test-output-stream, slice) -1132 # . . push args -1133 51/push-ecx -1134 68/push _test-output-stream/imm32 -1135 # . . call -1136 e8/call emit-string-literal-data/disp32 -1137 # . . discard args -1138 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1139 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1165 # . check-stream-equal(_test-output-stream, "0/imm32 ", msg) -1166 # . . push args -1167 68/push "F - test-emit-string-literal-data-empty"/imm32 -1168 68/push "0x00000000/imm32 "/imm32 -1169 68/push _test-output-stream/imm32 -1170 # . . call -1171 e8/call check-stream-equal/disp32 -1172 # . . discard args -1173 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1174 # . epilogue -1175 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1176 5d/pop-to-ebp -1177 c3/return -1178 -1179 # just to keep things simple -1180 test-emit-string-literal-data-no-metadata-for-non-alphanumerics: -1181 # . prologue -1182 55/push-ebp -1183 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1184 # setup -1185 # . clear-stream(_test-output-stream) -1186 # . . push args -1187 68/push _test-output-stream/imm32 -1188 # . . call -1189 e8/call clear-stream/disp32 -1190 # . . discard args -1191 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1192 # var slice/ecx = '"a b"' -1193 68/push _test-slice-a-space-b-limit/imm32 -1194 68/push _test-slice-a-space-b/imm32 -1195 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1196 # emit-string-literal-data(_test-output-stream, slice) -1197 # . . push args -1198 51/push-ecx -1199 68/push _test-output-stream/imm32 -1200 # . . call -1201 e8/call emit-string-literal-data/disp32 -1202 # . . discard args -1203 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1204 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1230 # . check-stream-equal(_test-output-stream, "3/imm32 61/a 20 62/b ", msg) # ideally we'd like to say '20/space' but that requires managing names for codepoints -1231 # . . push args -1232 68/push "F - test-emit-string-literal-data-no-metadata-for-non-alphanumerics"/imm32 -1233 68/push "0x00000003/imm32 61/a 20 62/b "/imm32 -1234 68/push _test-output-stream/imm32 -1235 # . . call -1236 e8/call check-stream-equal/disp32 -1237 # . . discard args -1238 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1239 # . epilogue -1240 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1241 5d/pop-to-ebp -1242 c3/return -1243 -1244 test-emit-string-literal-data-handles-escape-sequences: -1245 # . prologue -1246 55/push-ebp -1247 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1248 # setup -1249 # . clear-stream(_test-output-stream) -1250 # . . push args -1251 68/push _test-output-stream/imm32 -1252 # . . call -1253 e8/call clear-stream/disp32 -1254 # . . discard args -1255 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1256 # var slice/ecx = '"a\"b"' -1257 68/push _test-slice-a-dquote-b-limit/imm32 -1258 68/push _test-slice-a-dquote-b/imm32 -1259 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1260 # emit-string-literal-data(_test-output-stream, slice) -1261 # . . push args -1262 51/push-ecx -1263 68/push _test-output-stream/imm32 -1264 # . . call -1265 e8/call emit-string-literal-data/disp32 -1266 # . . discard args -1267 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1268 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1294 # . check-stream-equal(_test-output-stream, "3/imm32 61/a 22 62/b ", msg) -1295 # . . push args -1296 68/push "F - test-emit-string-literal-data-handles-escape-sequences"/imm32 -1297 68/push "0x00000003/imm32 61/a 22 62/b "/imm32 -1298 68/push _test-output-stream/imm32 -1299 # . . call -1300 e8/call check-stream-equal/disp32 -1301 # . . discard args -1302 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1303 # . epilogue -1304 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1305 5d/pop-to-ebp -1306 c3/return -1307 -1308 test-emit-string-literal-data-handles-newline-escape: -1309 # . prologue -1310 55/push-ebp -1311 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1312 # setup -1313 # . clear-stream(_test-output-stream) -1314 # . . push args -1315 68/push _test-output-stream/imm32 -1316 # . . call -1317 e8/call clear-stream/disp32 -1318 # . . discard args -1319 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1320 # var slice/ecx = '"a\nb"' -1321 68/push _test-slice-a-newline-b-limit/imm32 -1322 68/push _test-slice-a-newline-b/imm32 -1323 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1324 # emit-string-literal-data(_test-output-stream, slice) -1325 # . . push args -1326 51/push-ecx -1327 68/push _test-output-stream/imm32 -1328 # . . call -1329 e8/call emit-string-literal-data/disp32 -1330 # . . discard args -1331 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1332 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1358 # . check-stream-equal(_test-output-stream, "3/imm32 61/a 0a 62/b ", msg) -1359 # . . push args -1360 68/push "F - test-emit-string-literal-data-handles-newline-escape"/imm32 -1361 68/push "0x00000003/imm32 61/a 0a 62/b "/imm32 -1362 68/push _test-output-stream/imm32 -1363 # . . call -1364 e8/call check-stream-equal/disp32 -1365 # . . discard args -1366 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1367 # . epilogue -1368 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1369 5d/pop-to-ebp -1370 c3/return -1371 -1372 # emit everything from a word except the initial datum -1373 emit-metadata: # out : (address buffered-file), word : (address slice) -1374 # pseudocode -1375 # var slice = {0, word->end} -1376 # curr = word->start -1377 # if *curr == '"' -1378 # curr = skip-string-in-slice(curr, word->end) -1379 # else -1380 # while true -1381 # if curr == word->end -1382 # return -1383 # if *curr == '/' -1384 # break -1385 # ++curr -1386 # slice->start = curr -1387 # write-slice-buffered(out, slice) -1388 # -1389 # . prologue -1390 55/push-ebp -1391 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1392 # . save registers -1393 50/push-eax -1394 51/push-ecx -1395 52/push-edx -1396 53/push-ebx -1397 56/push-esi -1398 # esi = word -1399 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi -1400 # curr/ecx = word->start -1401 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx -1402 # end/edx = word->end -1403 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 4/disp8 . # copy *(esi+4) to edx -1404 # var slice/ebx = {0, end} -1405 52/push-edx -1406 68/push 0/imm32 -1407 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx -1408 # eax = 0 -1409 b8/copy-to-eax 0/imm32 -1410 $emit-metadata:check-for-string-literal: -1411 # - if (*curr == '"') curr = skip-string-in-slice(curr, end) -1412 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL -1413 3d/compare-eax-and 0x22/imm32/dquote -1414 75/jump-if-not-equal $emit-metadata:skip-datum-loop/disp8 -1415 $emit-metadata:skip-string-literal: -1416 # . eax = skip-string-in-slice(curr, end) -1417 # . . push args -1418 52/push-edx -1419 51/push-ecx -1420 # . . call -1421 e8/call skip-string-in-slice/disp32 -1422 # . . discard args -1423 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1424 # . curr = eax -1425 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx -1426 eb/jump $emit-metadata:emit/disp8 -1427 $emit-metadata:skip-datum-loop: -1428 # - otherwise scan for '/' -1429 # if (curr == end) return -1430 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx and edx -1431 74/jump-if-equal $emit-metadata:end/disp8 -1432 # if (*curr == '/') break -1433 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL -1434 3d/compare-eax-and 0x2f/imm32/slash -1435 74/jump-if-equal $emit-metadata:emit/disp8 -1436 # ++curr -1437 41/increment-ecx -1438 eb/jump $emit-metadata:skip-datum-loop/disp8 -1439 $emit-metadata:emit: -1440 # slice->start = ecx -1441 89/copy 0/mod/indirect 3/rm32/ebx . . . 1/r32/ecx . . # copy ecx to *ebx -1442 # write-slice-buffered(out, slice) -1443 # . . push args -1444 53/push-ebx -1445 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) -1446 # . . call -1447 e8/call write-slice-buffered/disp32 -1448 # . . discard args -1449 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . 8/imm32 . # add to esp -1450 $emit-metadata:end: -1451 # . reclaim locals -1452 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . 8/imm32 . # add to esp -1453 # . restore registers -1454 5e/pop-to-esi -1455 5b/pop-to-ebx -1456 5a/pop-to-edx -1457 59/pop-to-ecx -1458 58/pop-to-eax -1459 # . epilogue -1460 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1461 5d/pop-to-ebp -1462 c3/return -1463 -1464 test-emit-metadata: -1465 # . prologue -1466 55/push-ebp -1467 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1468 # setup -1469 # . clear-stream(_test-output-stream) -1470 # . . push args -1471 68/push _test-output-stream/imm32 -1472 # . . call -1473 e8/call clear-stream/disp32 -1474 # . . discard args -1475 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1476 # . clear-stream(_test-output-buffered-file->buffer) -1477 # . . push args -1478 68/push _test-output-buffered-file->buffer/imm32 -1479 # . . call -1480 e8/call clear-stream/disp32 -1481 # . . discard args -1482 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1483 # (eax..ecx) = "abc/def" -1484 b8/copy-to-eax "abc/def"/imm32 -1485 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx -1486 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx -1487 05/add-to-eax 4/imm32 -1488 # var slice/ecx = {eax, ecx} -1489 51/push-ecx -1490 50/push-eax -1491 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1492 # emit-metadata(_test-output-buffered-file, slice) -1493 # . . push args -1494 51/push-ecx -1495 68/push _test-output-buffered-file/imm32 -1496 # . . call -1497 e8/call emit-metadata/disp32 -1498 # . . discard args -1499 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1500 # flush(_test-output-buffered-file) -1501 # . . push args -1502 68/push _test-output-buffered-file/imm32 -1503 # . . call -1504 e8/call flush/disp32 -1505 # . . discard args -1506 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1507 # check-stream-equal(_test-output-stream, "/def", msg) # important that there's no leading space -1508 # . . push args -1509 68/push "F - test-emit-metadata"/imm32 -1510 68/push "/def"/imm32 -1511 68/push _test-output-stream/imm32 + 984 $emit-string-literal-data:char-done: + 985 # write(out, " ") + 986 # . . push args + 987 68/push Space/imm32 + 988 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 989 # . . call + 990 e8/call write/disp32 + 991 # . . discard args + 992 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 993 # ++curr + 994 42/increment-edx + 995 # ++ idx + 996 43/increment-ebx + 997 # if (idx < 0x40) continue + 998 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x40/imm32 # compare ebx + 999 7c/jump-if-lesser $emit-string-literal-data:next-char/disp8 +1000 # idx = 0 +1001 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx +1002 # write(out, "\n") +1003 # . . push args +1004 68/push Newline/imm32 +1005 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) +1006 # . . call +1007 e8/call write/disp32 +1008 # . . discard args +1009 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1010 $emit-string-literal-data:next-char: +1011 e9/jump $emit-string-literal-data:loop/disp32 +1012 $emit-string-literal-data:end: +1013 # . restore registers +1014 5e/pop-to-esi +1015 5b/pop-to-ebx +1016 5a/pop-to-edx +1017 59/pop-to-ecx +1018 58/pop-to-eax +1019 # . epilogue +1020 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1021 5d/pop-to-ebp +1022 c3/return +1023 +1024 is-alphanumeric?: # c : int -> eax : boolean +1025 # . prologue +1026 55/push-ebp +1027 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1028 # eax = c +1029 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax +1030 # if (eax < '0') return false +1031 3d/compare-eax-with 0x30/imm32/0 +1032 7c/jump-if-lesser $is-alphanumeric?:false/disp8 +1033 # if (eax <= '9') return true +1034 3d/compare-eax-with 0x39/imm32/9 +1035 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 +1036 # if (eax < 'A') return false +1037 3d/compare-eax-with 0x41/imm32/A +1038 7c/jump-if-lesser $is-alphanumeric?:false/disp8 +1039 # if (eax <= 'Z') return true +1040 3d/compare-eax-with 0x5a/imm32/Z +1041 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 +1042 # if (eax < 'a') return false +1043 3d/compare-eax-with 0x61/imm32/a +1044 7c/jump-if-lesser $is-alphanumeric?:false/disp8 +1045 # if (eax <= 'z') return true +1046 3d/compare-eax-with 0x7a/imm32/z +1047 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 +1048 # return false +1049 $is-alphanumeric?:false: +1050 b8/copy-to-eax 0/imm32/false +1051 eb/jump $is-alphanumeric?:end/disp8 +1052 $is-alphanumeric?:true: +1053 b8/copy-to-eax 1/imm32/true +1054 $is-alphanumeric?:end: +1055 # . epilogue +1056 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1057 5d/pop-to-ebp +1058 c3/return +1059 +1060 test-emit-string-literal-data: +1061 # . prologue +1062 55/push-ebp +1063 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1064 # setup +1065 # . clear-stream(_test-output-stream) +1066 # . . push args +1067 68/push _test-output-stream/imm32 +1068 # . . call +1069 e8/call clear-stream/disp32 +1070 # . . discard args +1071 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1072 # var slice/ecx = '"abc"/d' +1073 68/push _test-slice-abc-limit/imm32 +1074 68/push _test-slice-abc/imm32 +1075 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1076 # emit-string-literal-data(_test-output-stream, slice) +1077 # . . push args +1078 51/push-ecx +1079 68/push _test-output-stream/imm32 +1080 # . . call +1081 e8/call emit-string-literal-data/disp32 +1082 # . . discard args +1083 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1084 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1110 # . check-stream-equal(_test-output-stream, "3/imm32 61/a 62/b 63/c ", msg) +1111 # . . push args +1112 68/push "F - test-emit-string-literal-data"/imm32 +1113 68/push "0x00000003/imm32 61/a 62/b 63/c "/imm32 +1114 68/push _test-output-stream/imm32 +1115 # . . call +1116 e8/call check-stream-equal/disp32 +1117 # . . discard args +1118 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1119 # . epilogue +1120 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1121 5d/pop-to-ebp +1122 c3/return +1123 +1124 test-emit-string-literal-data-empty: +1125 # . prologue +1126 55/push-ebp +1127 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1128 # setup +1129 # . clear-stream(_test-output-stream) +1130 # . . push args +1131 68/push _test-output-stream/imm32 +1132 # . . call +1133 e8/call clear-stream/disp32 +1134 # . . discard args +1135 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1136 # var slice/ecx = '""' +1137 68/push 0/imm32/end +1138 68/push 0/imm32/start +1139 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1140 # emit-string-literal-data(_test-output-stream, slice) +1141 # . . push args +1142 51/push-ecx +1143 68/push _test-output-stream/imm32 +1144 # . . call +1145 e8/call emit-string-literal-data/disp32 +1146 # . . discard args +1147 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1148 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1174 # . check-stream-equal(_test-output-stream, "0/imm32 ", msg) +1175 # . . push args +1176 68/push "F - test-emit-string-literal-data-empty"/imm32 +1177 68/push "0x00000000/imm32 "/imm32 +1178 68/push _test-output-stream/imm32 +1179 # . . call +1180 e8/call check-stream-equal/disp32 +1181 # . . discard args +1182 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1183 # . epilogue +1184 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1185 5d/pop-to-ebp +1186 c3/return +1187 +1188 # just to keep things simple +1189 test-emit-string-literal-data-no-metadata-for-non-alphanumerics: +1190 # . prologue +1191 55/push-ebp +1192 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1193 # setup +1194 # . clear-stream(_test-output-stream) +1195 # . . push args +1196 68/push _test-output-stream/imm32 +1197 # . . call +1198 e8/call clear-stream/disp32 +1199 # . . discard args +1200 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1201 # var slice/ecx = '"a b"' +1202 68/push _test-slice-a-space-b-limit/imm32 +1203 68/push _test-slice-a-space-b/imm32 +1204 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1205 # emit-string-literal-data(_test-output-stream, slice) +1206 # . . push args +1207 51/push-ecx +1208 68/push _test-output-stream/imm32 +1209 # . . call +1210 e8/call emit-string-literal-data/disp32 +1211 # . . discard args +1212 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1213 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1239 # . check-stream-equal(_test-output-stream, "3/imm32 61/a 20 62/b ", msg) # ideally we'd like to say '20/space' but that requires managing names for codepoints +1240 # . . push args +1241 68/push "F - test-emit-string-literal-data-no-metadata-for-non-alphanumerics"/imm32 +1242 68/push "0x00000003/imm32 61/a 20 62/b "/imm32 +1243 68/push _test-output-stream/imm32 +1244 # . . call +1245 e8/call check-stream-equal/disp32 +1246 # . . discard args +1247 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1248 # . epilogue +1249 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1250 5d/pop-to-ebp +1251 c3/return +1252 +1253 test-emit-string-literal-data-handles-escape-sequences: +1254 # . prologue +1255 55/push-ebp +1256 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1257 # setup +1258 # . clear-stream(_test-output-stream) +1259 # . . push args +1260 68/push _test-output-stream/imm32 +1261 # . . call +1262 e8/call clear-stream/disp32 +1263 # . . discard args +1264 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1265 # var slice/ecx = '"a\"b"' +1266 68/push _test-slice-a-dquote-b-limit/imm32 +1267 68/push _test-slice-a-dquote-b/imm32 +1268 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1269 # emit-string-literal-data(_test-output-stream, slice) +1270 # . . push args +1271 51/push-ecx +1272 68/push _test-output-stream/imm32 +1273 # . . call +1274 e8/call emit-string-literal-data/disp32 +1275 # . . discard args +1276 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1277 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1303 # . check-stream-equal(_test-output-stream, "3/imm32 61/a 22 62/b ", msg) +1304 # . . push args +1305 68/push "F - test-emit-string-literal-data-handles-escape-sequences"/imm32 +1306 68/push "0x00000003/imm32 61/a 22 62/b "/imm32 +1307 68/push _test-output-stream/imm32 +1308 # . . call +1309 e8/call check-stream-equal/disp32 +1310 # . . discard args +1311 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1312 # . epilogue +1313 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1314 5d/pop-to-ebp +1315 c3/return +1316 +1317 test-emit-string-literal-data-handles-newline-escape: +1318 # . prologue +1319 55/push-ebp +1320 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1321 # setup +1322 # . clear-stream(_test-output-stream) +1323 # . . push args +1324 68/push _test-output-stream/imm32 +1325 # . . call +1326 e8/call clear-stream/disp32 +1327 # . . discard args +1328 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1329 # var slice/ecx = '"a\nb"' +1330 68/push _test-slice-a-newline-b-limit/imm32 +1331 68/push _test-slice-a-newline-b/imm32 +1332 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1333 # emit-string-literal-data(_test-output-stream, slice) +1334 # . . push args +1335 51/push-ecx +1336 68/push _test-output-stream/imm32 +1337 # . . call +1338 e8/call emit-string-literal-data/disp32 +1339 # . . discard args +1340 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1341 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1367 # . check-stream-equal(_test-output-stream, "3/imm32 61/a 0a 62/b ", msg) +1368 # . . push args +1369 68/push "F - test-emit-string-literal-data-handles-newline-escape"/imm32 +1370 68/push "0x00000003/imm32 61/a 0a 62/b "/imm32 +1371 68/push _test-output-stream/imm32 +1372 # . . call +1373 e8/call check-stream-equal/disp32 +1374 # . . discard args +1375 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1376 # . epilogue +1377 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1378 5d/pop-to-ebp +1379 c3/return +1380 +1381 # emit everything from a word except the initial datum +1382 emit-metadata: # out : (address buffered-file), word : (address slice) +1383 # pseudocode +1384 # var slice = {0, word->end} +1385 # curr = word->start +1386 # if *curr == '"' +1387 # curr = skip-string-in-slice(curr, word->end) +1388 # else +1389 # while true +1390 # if curr == word->end +1391 # return +1392 # if *curr == '/' +1393 # break +1394 # ++curr +1395 # slice->start = curr +1396 # write-slice-buffered(out, slice) +1397 # +1398 # . prologue +1399 55/push-ebp +1400 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1401 # . save registers +1402 50/push-eax +1403 51/push-ecx +1404 52/push-edx +1405 53/push-ebx +1406 56/push-esi +1407 # esi = word +1408 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi +1409 # curr/ecx = word->start +1410 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx +1411 # end/edx = word->end +1412 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 4/disp8 . # copy *(esi+4) to edx +1413 # var slice/ebx = {0, end} +1414 52/push-edx +1415 68/push 0/imm32 +1416 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx +1417 # eax = 0 +1418 b8/copy-to-eax 0/imm32 +1419 $emit-metadata:check-for-string-literal: +1420 # - if (*curr == '"') curr = skip-string-in-slice(curr, end) +1421 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL +1422 3d/compare-eax-and 0x22/imm32/dquote +1423 75/jump-if-not-equal $emit-metadata:skip-datum-loop/disp8 +1424 $emit-metadata:skip-string-literal: +1425 # . eax = skip-string-in-slice(curr, end) +1426 # . . push args +1427 52/push-edx +1428 51/push-ecx +1429 # . . call +1430 e8/call skip-string-in-slice/disp32 +1431 # . . discard args +1432 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1433 # . curr = eax +1434 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx +1435 eb/jump $emit-metadata:emit/disp8 +1436 $emit-metadata:skip-datum-loop: +1437 # - otherwise scan for '/' +1438 # if (curr == end) return +1439 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx and edx +1440 74/jump-if-equal $emit-metadata:end/disp8 +1441 # if (*curr == '/') break +1442 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL +1443 3d/compare-eax-and 0x2f/imm32/slash +1444 74/jump-if-equal $emit-metadata:emit/disp8 +1445 # ++curr +1446 41/increment-ecx +1447 eb/jump $emit-metadata:skip-datum-loop/disp8 +1448 $emit-metadata:emit: +1449 # slice->start = ecx +1450 89/copy 0/mod/indirect 3/rm32/ebx . . . 1/r32/ecx . . # copy ecx to *ebx +1451 # write-slice-buffered(out, slice) +1452 # . . push args +1453 53/push-ebx +1454 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) +1455 # . . call +1456 e8/call write-slice-buffered/disp32 +1457 # . . discard args +1458 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . 8/imm32 . # add to esp +1459 $emit-metadata:end: +1460 # . reclaim locals +1461 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . 8/imm32 . # add to esp +1462 # . restore registers +1463 5e/pop-to-esi +1464 5b/pop-to-ebx +1465 5a/pop-to-edx +1466 59/pop-to-ecx +1467 58/pop-to-eax +1468 # . epilogue +1469 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1470 5d/pop-to-ebp +1471 c3/return +1472 +1473 test-emit-metadata: +1474 # . prologue +1475 55/push-ebp +1476 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1477 # setup +1478 # . clear-stream(_test-output-stream) +1479 # . . push args +1480 68/push _test-output-stream/imm32 +1481 # . . call +1482 e8/call clear-stream/disp32 +1483 # . . discard args +1484 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1485 # . clear-stream(_test-output-buffered-file->buffer) +1486 # . . push args +1487 68/push _test-output-buffered-file->buffer/imm32 +1488 # . . call +1489 e8/call clear-stream/disp32 +1490 # . . discard args +1491 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1492 # (eax..ecx) = "abc/def" +1493 b8/copy-to-eax "abc/def"/imm32 +1494 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx +1495 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx +1496 05/add-to-eax 4/imm32 +1497 # var slice/ecx = {eax, ecx} +1498 51/push-ecx +1499 50/push-eax +1500 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1501 # emit-metadata(_test-output-buffered-file, slice) +1502 # . . push args +1503 51/push-ecx +1504 68/push _test-output-buffered-file/imm32 +1505 # . . call +1506 e8/call emit-metadata/disp32 +1507 # . . discard args +1508 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1509 # flush(_test-output-buffered-file) +1510 # . . push args +1511 68/push _test-output-buffered-file/imm32 1512 # . . call -1513 e8/call check-stream-equal/disp32 +1513 e8/call flush/disp32 1514 # . . discard args -1515 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1516 # . epilogue -1517 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1518 5d/pop-to-ebp -1519 c3/return -1520 -1521 test-emit-metadata-none: -1522 # . prologue -1523 55/push-ebp -1524 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1525 # setup -1526 # . clear-stream(_test-output-stream) -1527 # . . push args -1528 68/push _test-output-stream/imm32 -1529 # . . call -1530 e8/call clear-stream/disp32 -1531 # . . discard args -1532 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1533 # . clear-stream(_test-output-buffered-file->buffer) -1534 # . . push args -1535 68/push _test-output-buffered-file->buffer/imm32 -1536 # . . call -1537 e8/call clear-stream/disp32 -1538 # . . discard args -1539 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1540 # (eax..ecx) = "abc" -1541 b8/copy-to-eax "abc"/imm32 -1542 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx -1543 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx -1544 05/add-to-eax 4/imm32 -1545 # var slice/ecx = {eax, ecx} -1546 51/push-ecx -1547 50/push-eax -1548 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1549 # emit-metadata(_test-output-buffered-file, slice) -1550 # . . push args -1551 51/push-ecx -1552 68/push _test-output-buffered-file/imm32 -1553 # . . call -1554 e8/call emit-metadata/disp32 -1555 # . . discard args -1556 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1557 # flush(_test-output-buffered-file) -1558 # . . push args -1559 68/push _test-output-buffered-file/imm32 -1560 # . . call -1561 e8/call flush/disp32 -1562 # . . discard args -1563 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1564 # check-stream-equal(_test-output-stream, "", msg) -1565 # . . push args -1566 68/push "F - test-emit-metadata-none"/imm32 -1567 68/push ""/imm32 -1568 68/push _test-output-stream/imm32 +1515 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1516 # check-stream-equal(_test-output-stream, "/def", msg) # important that there's no leading space +1517 # . . push args +1518 68/push "F - test-emit-metadata"/imm32 +1519 68/push "/def"/imm32 +1520 68/push _test-output-stream/imm32 +1521 # . . call +1522 e8/call check-stream-equal/disp32 +1523 # . . discard args +1524 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1525 # . epilogue +1526 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1527 5d/pop-to-ebp +1528 c3/return +1529 +1530 test-emit-metadata-none: +1531 # . prologue +1532 55/push-ebp +1533 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1534 # setup +1535 # . clear-stream(_test-output-stream) +1536 # . . push args +1537 68/push _test-output-stream/imm32 +1538 # . . call +1539 e8/call clear-stream/disp32 +1540 # . . discard args +1541 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1542 # . clear-stream(_test-output-buffered-file->buffer) +1543 # . . push args +1544 68/push _test-output-buffered-file->buffer/imm32 +1545 # . . call +1546 e8/call clear-stream/disp32 +1547 # . . discard args +1548 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1549 # (eax..ecx) = "abc" +1550 b8/copy-to-eax "abc"/imm32 +1551 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx +1552 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx +1553 05/add-to-eax 4/imm32 +1554 # var slice/ecx = {eax, ecx} +1555 51/push-ecx +1556 50/push-eax +1557 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1558 # emit-metadata(_test-output-buffered-file, slice) +1559 # . . push args +1560 51/push-ecx +1561 68/push _test-output-buffered-file/imm32 +1562 # . . call +1563 e8/call emit-metadata/disp32 +1564 # . . discard args +1565 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1566 # flush(_test-output-buffered-file) +1567 # . . push args +1568 68/push _test-output-buffered-file/imm32 1569 # . . call -1570 e8/call check-stream-equal/disp32 +1570 e8/call flush/disp32 1571 # . . discard args -1572 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1573 # . epilogue -1574 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1575 5d/pop-to-ebp -1576 c3/return -1577 -1578 test-emit-metadata-multiple: -1579 # . prologue -1580 55/push-ebp -1581 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1582 # setup -1583 # . clear-stream(_test-output-stream) -1584 # . . push args -1585 68/push _test-output-stream/imm32 -1586 # . . call -1587 e8/call clear-stream/disp32 -1588 # . . discard args -1589 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1590 # . clear-stream(_test-output-buffered-file->buffer) -1591 # . . push args -1592 68/push _test-output-buffered-file->buffer/imm32 -1593 # . . call -1594 e8/call clear-stream/disp32 -1595 # . . discard args -1596 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1597 # (eax..ecx) = "abc/def/ghi" -1598 b8/copy-to-eax "abc/def/ghi"/imm32 -1599 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx -1600 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx -1601 05/add-to-eax 4/imm32 -1602 # var slice/ecx = {eax, ecx} -1603 51/push-ecx -1604 50/push-eax -1605 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1606 # emit-metadata(_test-output-buffered-file, slice) -1607 # . . push args -1608 51/push-ecx -1609 68/push _test-output-buffered-file/imm32 -1610 # . . call -1611 e8/call emit-metadata/disp32 -1612 # . . discard args -1613 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1614 # flush(_test-output-buffered-file) -1615 # . . push args -1616 68/push _test-output-buffered-file/imm32 -1617 # . . call -1618 e8/call flush/disp32 -1619 # . . discard args -1620 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1621 # check-stream-equal(_test-output-stream, "/def/ghi", msg) # important that there's no leading space -1622 # . . push args -1623 68/push "F - test-emit-metadata-multiple"/imm32 -1624 68/push "/def/ghi"/imm32 -1625 68/push _test-output-stream/imm32 +1572 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1573 # check-stream-equal(_test-output-stream, "", msg) +1574 # . . push args +1575 68/push "F - test-emit-metadata-none"/imm32 +1576 68/push ""/imm32 +1577 68/push _test-output-stream/imm32 +1578 # . . call +1579 e8/call check-stream-equal/disp32 +1580 # . . discard args +1581 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1582 # . epilogue +1583 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1584 5d/pop-to-ebp +1585 c3/return +1586 +1587 test-emit-metadata-multiple: +1588 # . prologue +1589 55/push-ebp +1590 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1591 # setup +1592 # . clear-stream(_test-output-stream) +1593 # . . push args +1594 68/push _test-output-stream/imm32 +1595 # . . call +1596 e8/call clear-stream/disp32 +1597 # . . discard args +1598 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1599 # . clear-stream(_test-output-buffered-file->buffer) +1600 # . . push args +1601 68/push _test-output-buffered-file->buffer/imm32 +1602 # . . call +1603 e8/call clear-stream/disp32 +1604 # . . discard args +1605 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1606 # (eax..ecx) = "abc/def/ghi" +1607 b8/copy-to-eax "abc/def/ghi"/imm32 +1608 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx +1609 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx +1610 05/add-to-eax 4/imm32 +1611 # var slice/ecx = {eax, ecx} +1612 51/push-ecx +1613 50/push-eax +1614 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1615 # emit-metadata(_test-output-buffered-file, slice) +1616 # . . push args +1617 51/push-ecx +1618 68/push _test-output-buffered-file/imm32 +1619 # . . call +1620 e8/call emit-metadata/disp32 +1621 # . . discard args +1622 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1623 # flush(_test-output-buffered-file) +1624 # . . push args +1625 68/push _test-output-buffered-file/imm32 1626 # . . call -1627 e8/call check-stream-equal/disp32 +1627 e8/call flush/disp32 1628 # . . discard args -1629 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1630 # . epilogue -1631 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1632 5d/pop-to-ebp -1633 c3/return -1634 -1635 test-emit-metadata-when-no-datum: -1636 # . prologue -1637 55/push-ebp -1638 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1639 # setup -1640 # . clear-stream(_test-output-stream) -1641 # . . push args -1642 68/push _test-output-stream/imm32 -1643 # . . call -1644 e8/call clear-stream/disp32 -1645 # . . discard args -1646 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1647 # . clear-stream(_test-output-buffered-file->buffer) -1648 # . . push args -1649 68/push _test-output-buffered-file->buffer/imm32 -1650 # . . call -1651 e8/call clear-stream/disp32 -1652 # . . discard args -1653 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1654 # var slice/ecx = "/abc" -1655 b8/copy-to-eax "/abc"/imm32 -1656 # . push end/ecx -1657 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx -1658 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx -1659 51/push-ecx -1660 # . push curr/eax -1661 05/add-to-eax 4/imm32 -1662 50/push-eax -1663 # . save stack pointer -1664 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1665 # emit-metadata(_test-output-buffered-file, slice) -1666 # . . push args -1667 51/push-ecx -1668 68/push _test-output-buffered-file/imm32 -1669 # . . call -1670 e8/call emit-metadata/disp32 -1671 # . . discard args -1672 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1673 # flush(_test-output-buffered-file) -1674 # . . push args -1675 68/push _test-output-buffered-file/imm32 -1676 # . . call -1677 e8/call flush/disp32 -1678 # . . discard args -1679 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1680 # check-stream-equal(_test-output-stream, "/abc", msg) # nothing skipped -1681 # . . push args -1682 68/push "F - test-emit-metadata-when-no-datum"/imm32 -1683 68/push "/abc"/imm32 -1684 68/push _test-output-stream/imm32 +1629 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1630 # check-stream-equal(_test-output-stream, "/def/ghi", msg) # important that there's no leading space +1631 # . . push args +1632 68/push "F - test-emit-metadata-multiple"/imm32 +1633 68/push "/def/ghi"/imm32 +1634 68/push _test-output-stream/imm32 +1635 # . . call +1636 e8/call check-stream-equal/disp32 +1637 # . . discard args +1638 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1639 # . epilogue +1640 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1641 5d/pop-to-ebp +1642 c3/return +1643 +1644 test-emit-metadata-when-no-datum: +1645 # . prologue +1646 55/push-ebp +1647 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1648 # setup +1649 # . clear-stream(_test-output-stream) +1650 # . . push args +1651 68/push _test-output-stream/imm32 +1652 # . . call +1653 e8/call clear-stream/disp32 +1654 # . . discard args +1655 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1656 # . clear-stream(_test-output-buffered-file->buffer) +1657 # . . push args +1658 68/push _test-output-buffered-file->buffer/imm32 +1659 # . . call +1660 e8/call clear-stream/disp32 +1661 # . . discard args +1662 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1663 # var slice/ecx = "/abc" +1664 b8/copy-to-eax "/abc"/imm32 +1665 # . push end/ecx +1666 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx +1667 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx +1668 51/push-ecx +1669 # . push curr/eax +1670 05/add-to-eax 4/imm32 +1671 50/push-eax +1672 # . save stack pointer +1673 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1674 # emit-metadata(_test-output-buffered-file, slice) +1675 # . . push args +1676 51/push-ecx +1677 68/push _test-output-buffered-file/imm32 +1678 # . . call +1679 e8/call emit-metadata/disp32 +1680 # . . discard args +1681 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1682 # flush(_test-output-buffered-file) +1683 # . . push args +1684 68/push _test-output-buffered-file/imm32 1685 # . . call -1686 e8/call check-stream-equal/disp32 +1686 e8/call flush/disp32 1687 # . . discard args -1688 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1689 # . epilogue -1690 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1691 5d/pop-to-ebp -1692 c3/return -1693 -1694 test-emit-metadata-in-string-literal: -1695 # . prologue -1696 55/push-ebp -1697 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1698 # setup -1699 # . clear-stream(_test-output-stream) -1700 # . . push args -1701 68/push _test-output-stream/imm32 -1702 # . . call -1703 e8/call clear-stream/disp32 -1704 # . . discard args -1705 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1706 # . clear-stream(_test-output-buffered-file->buffer) -1707 # . . push args -1708 68/push _test-output-buffered-file->buffer/imm32 -1709 # . . call -1710 e8/call clear-stream/disp32 -1711 # . . discard args -1712 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1713 # var slice/ecx = "\"abc/def\"/ghi" -1714 68/push _test-slice-literal-string-with-limit/imm32 -1715 68/push _test-slice-literal-string/imm32/start -1716 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1717 # emit-metadata(_test-output-buffered-file, slice) -1718 # . . push args -1719 51/push-ecx -1720 68/push _test-output-buffered-file/imm32 -1721 # . . call -1722 e8/call emit-metadata/disp32 -1723 # . . discard args -1724 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1725 # flush(_test-output-buffered-file) -1726 # . . push args -1727 68/push _test-output-buffered-file/imm32 -1728 # . . call -1729 e8/call flush/disp32 -1730 # . . discard args -1731 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1732 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- -1758 # check-stream-equal(_test-output-stream, "/ghi", msg) # important that there's no leading space -1759 # . . push args -1760 68/push "F - test-emit-metadata-in-string-literal"/imm32 -1761 68/push "/ghi"/imm32 -1762 68/push _test-output-stream/imm32 -1763 # . . call -1764 e8/call check-stream-equal/disp32 -1765 # . . discard args -1766 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1767 # . epilogue -1768 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1769 5d/pop-to-ebp -1770 c3/return -1771 -1772 string-length-at-start-of-slice: # curr : (address byte), end : (address byte) -> length/eax -1773 # . prologue -1774 55/push-ebp -1775 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1776 # . save registers -1777 51/push-ecx -1778 52/push-edx -1779 53/push-ebx -1780 # ecx = curr -1781 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx -1782 # edx = end -1783 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx -1784 # length/eax = 0 -1785 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax -1786 # ebx = 0 -1787 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx -1788 # skip initial dquote -1789 41/increment-ecx -1790 $string-length-at-start-of-slice:loop: -1791 # if (curr >= end) return length -1792 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx -1793 73/jump-if-greater-unsigned-or-equal $string-length-at-start-of-slice:end/disp8 -1794 # BL = *curr -1795 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 3/r32/BL . . # copy byte at *ecx to BL -1796 $string-length-at-start-of-slice:dquote: -1797 # if (ebx == '"') break -1798 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x22/imm32/dquote # compare ebx -1799 74/jump-if-equal $string-length-at-start-of-slice:end/disp8 -1800 $string-length-at-start-of-slice:check-for-escape: -1801 # if (ebx == '\') escape next char -1802 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x5c/imm32/backslash # compare ebx -1803 75/jump-if-not-equal $string-length-at-start-of-slice:continue/disp8 -1804 $string-length-at-start-of-slice:escape: -1805 # increment curr but not result -1806 41/increment-ecx -1807 $string-length-at-start-of-slice:continue: -1808 # ++result -1809 40/increment-eax -1810 # ++curr -1811 41/increment-ecx -1812 eb/jump $string-length-at-start-of-slice:loop/disp8 -1813 $string-length-at-start-of-slice:end: -1814 # . restore registers -1815 5b/pop-to-ebx -1816 5a/pop-to-edx -1817 59/pop-to-ecx -1818 # . epilogue -1819 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1820 5d/pop-to-ebp -1821 c3/return -1822 -1823 test-string-length-at-start-of-slice: -1824 # . prologue -1825 55/push-ebp -1826 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1827 # setup: (eax..ecx) = "\"abc\" def" -1828 b8/copy-to-eax "\"abc\" def"/imm32 -1829 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx -1830 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx -1831 05/add-to-eax 4/imm32 -1832 # eax = string-length-at-start-of-slice(eax, ecx) -1833 # . . push args -1834 51/push-ecx -1835 50/push-eax -1836 # . . call -1837 e8/call string-length-at-start-of-slice/disp32 -1838 # . . discard args -1839 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1840 # check-ints-equal(eax, 3, msg) -1841 # . . push args -1842 68/push "F - test-string-length-at-start-of-slice"/imm32 -1843 68/push 3/imm32 +1688 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1689 # check-stream-equal(_test-output-stream, "/abc", msg) # nothing skipped +1690 # . . push args +1691 68/push "F - test-emit-metadata-when-no-datum"/imm32 +1692 68/push "/abc"/imm32 +1693 68/push _test-output-stream/imm32 +1694 # . . call +1695 e8/call check-stream-equal/disp32 +1696 # . . discard args +1697 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1698 # . epilogue +1699 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1700 5d/pop-to-ebp +1701 c3/return +1702 +1703 test-emit-metadata-in-string-literal: +1704 # . prologue +1705 55/push-ebp +1706 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1707 # setup +1708 # . clear-stream(_test-output-stream) +1709 # . . push args +1710 68/push _test-output-stream/imm32 +1711 # . . call +1712 e8/call clear-stream/disp32 +1713 # . . discard args +1714 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1715 # . clear-stream(_test-output-buffered-file->buffer) +1716 # . . push args +1717 68/push _test-output-buffered-file->buffer/imm32 +1718 # . . call +1719 e8/call clear-stream/disp32 +1720 # . . discard args +1721 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1722 # var slice/ecx = "\"abc/def\"/ghi" +1723 68/push _test-slice-literal-string-with-limit/imm32 +1724 68/push _test-slice-literal-string/imm32/start +1725 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1726 # emit-metadata(_test-output-buffered-file, slice) +1727 # . . push args +1728 51/push-ecx +1729 68/push _test-output-buffered-file/imm32 +1730 # . . call +1731 e8/call emit-metadata/disp32 +1732 # . . discard args +1733 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1734 # flush(_test-output-buffered-file) +1735 # . . push args +1736 68/push _test-output-buffered-file/imm32 +1737 # . . call +1738 e8/call flush/disp32 +1739 # . . discard args +1740 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1741 +-- 26 lines: #? # dump output --------------------------------------------------------------------------------------------------------------------------- +1767 # check-stream-equal(_test-output-stream, "/ghi", msg) # important that there's no leading space +1768 # . . push args +1769 68/push "F - test-emit-metadata-in-string-literal"/imm32 +1770 68/push "/ghi"/imm32 +1771 68/push _test-output-stream/imm32 +1772 # . . call +1773 e8/call check-stream-equal/disp32 +1774 # . . discard args +1775 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1776 # . epilogue +1777 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1778 5d/pop-to-ebp +1779 c3/return +1780 +1781 string-length-at-start-of-slice: # curr : (address byte), end : (address byte) -> length/eax +1782 # . prologue +1783 55/push-ebp +1784 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1785 # . save registers +1786 51/push-ecx +1787 52/push-edx +1788 53/push-ebx +1789 # ecx = curr +1790 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx +1791 # edx = end +1792 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx +1793 # length/eax = 0 +1794 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax +1795 # ebx = 0 +1796 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx +1797 # skip initial dquote +1798 41/increment-ecx +1799 $string-length-at-start-of-slice:loop: +1800 # if (curr >= end) return length +1801 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx +1802 73/jump-if-greater-unsigned-or-equal $string-length-at-start-of-slice:end/disp8 +1803 # BL = *curr +1804 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 3/r32/BL . . # copy byte at *ecx to BL +1805 $string-length-at-start-of-slice:dquote: +1806 # if (ebx == '"') break +1807 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x22/imm32/dquote # compare ebx +1808 74/jump-if-equal $string-length-at-start-of-slice:end/disp8 +1809 $string-length-at-start-of-slice:check-for-escape: +1810 # if (ebx == '\') escape next char +1811 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x5c/imm32/backslash # compare ebx +1812 75/jump-if-not-equal $string-length-at-start-of-slice:continue/disp8 +1813 $string-length-at-start-of-slice:escape: +1814 # increment curr but not result +1815 41/increment-ecx +1816 $string-length-at-start-of-slice:continue: +1817 # ++result +1818 40/increment-eax +1819 # ++curr +1820 41/increment-ecx +1821 eb/jump $string-length-at-start-of-slice:loop/disp8 +1822 $string-length-at-start-of-slice:end: +1823 # . restore registers +1824 5b/pop-to-ebx +1825 5a/pop-to-edx +1826 59/pop-to-ecx +1827 # . epilogue +1828 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1829 5d/pop-to-ebp +1830 c3/return +1831 +1832 test-string-length-at-start-of-slice: +1833 # . prologue +1834 55/push-ebp +1835 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1836 # setup: (eax..ecx) = "\"abc\" def" +1837 b8/copy-to-eax "\"abc\" def"/imm32 +1838 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx +1839 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx +1840 05/add-to-eax 4/imm32 +1841 # eax = string-length-at-start-of-slice(eax, ecx) +1842 # . . push args +1843 51/push-ecx 1844 50/push-eax 1845 # . . call -1846 e8/call check-ints-equal/disp32 +1846 e8/call string-length-at-start-of-slice/disp32 1847 # . . discard args -1848 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1849 # . epilogue -1850 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1851 5d/pop-to-ebp -1852 c3/return -1853 -1854 test-string-length-at-start-of-slice-escaped: -1855 # . prologue -1856 55/push-ebp -1857 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1858 # setup: (eax..ecx) = "\"ab\\c\" def" -1859 b8/copy-to-eax "\"ab\\c\" def"/imm32 -1860 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx -1861 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx -1862 05/add-to-eax 4/imm32 -1863 # eax = string-length-at-start-of-slice(eax, ecx) -1864 # . . push args -1865 51/push-ecx -1866 50/push-eax -1867 # . . call -1868 e8/call string-length-at-start-of-slice/disp32 -1869 # . . discard args -1870 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1871 # check-ints-equal(eax, 3, msg) -1872 # . . push args -1873 68/push "F - test-string-length-at-start-of-slice-escaped"/imm32 -1874 68/push 3/imm32 +1848 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1849 # check-ints-equal(eax, 3, msg) +1850 # . . push args +1851 68/push "F - test-string-length-at-start-of-slice"/imm32 +1852 68/push 3/imm32 +1853 50/push-eax +1854 # . . call +1855 e8/call check-ints-equal/disp32 +1856 # . . discard args +1857 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1858 # . epilogue +1859 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1860 5d/pop-to-ebp +1861 c3/return +1862 +1863 test-string-length-at-start-of-slice-escaped: +1864 # . prologue +1865 55/push-ebp +1866 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1867 # setup: (eax..ecx) = "\"ab\\c\" def" +1868 b8/copy-to-eax "\"ab\\c\" def"/imm32 +1869 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx +1870 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx +1871 05/add-to-eax 4/imm32 +1872 # eax = string-length-at-start-of-slice(eax, ecx) +1873 # . . push args +1874 51/push-ecx 1875 50/push-eax 1876 # . . call -1877 e8/call check-ints-equal/disp32 +1877 e8/call string-length-at-start-of-slice/disp32 1878 # . . discard args -1879 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1880 # . epilogue -1881 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1882 5d/pop-to-ebp -1883 c3/return -1884 -1885 == data -1886 -1887 Next-string-literal: # tracks the next auto-generated variable name -1888 1/imm32 -1889 -1890 _test-slice-abc: -1891 22/dquote 61/a 62/b 63/c 22/dquote # "abc" -1892 2f/slash 64/d -1893 _test-slice-abc-limit: -1894 -1895 _test-slice-a-space-b: -1896 22/dquote 61/a 20/space 62/b 22/dquote # "a b" -1897 _test-slice-a-space-b-limit: +1879 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1880 # check-ints-equal(eax, 3, msg) +1881 # . . push args +1882 68/push "F - test-string-length-at-start-of-slice-escaped"/imm32 +1883 68/push 3/imm32 +1884 50/push-eax +1885 # . . call +1886 e8/call check-ints-equal/disp32 +1887 # . . discard args +1888 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1889 # . epilogue +1890 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1891 5d/pop-to-ebp +1892 c3/return +1893 +1894 == data +1895 +1896 Next-string-literal: # tracks the next auto-generated variable name +1897 1/imm32 1898 -1899 _test-slice-a-dquote-b: -1900 22/dquote 61/a 5c/backslash 22/dquote 62/b 22/dquote # "a\"b" -1901 _test-slice-a-dquote-b-limit: -1902 -1903 _test-slice-a-newline-b: -1904 22/dquote 61/a 5c/backslash 6e/n 62/b 22/dquote # "a\nb" -1905 _test-slice-a-newline-b-limit: -1906 -1907 # "abc/def"/ghi -1908 _test-slice-literal-string: -1909 22/dquote -1910 61/a 62/b 63/c # abc -1911 2f/slash 64/d 65/e 66/f # /def -1912 22/dquote -1913 2f/slash 67/g 68/h 69/i # /ghi -1914 _test-slice-literal-string-with-limit: +1899 _test-slice-abc: +1900 22/dquote 61/a 62/b 63/c 22/dquote # "abc" +1901 2f/slash 64/d +1902 _test-slice-abc-limit: +1903 +1904 _test-slice-a-space-b: +1905 22/dquote 61/a 20/space 62/b 22/dquote # "a b" +1906 _test-slice-a-space-b-limit: +1907 +1908 _test-slice-a-dquote-b: +1909 22/dquote 61/a 5c/backslash 22/dquote 62/b 22/dquote # "a\"b" +1910 _test-slice-a-dquote-b-limit: +1911 +1912 _test-slice-a-newline-b: +1913 22/dquote 61/a 5c/backslash 6e/n 62/b 22/dquote # "a\nb" +1914 _test-slice-a-newline-b-limit: 1915 -1916 # . . vim:nowrap:textwidth=0 +1916 # "abc/def"/ghi +1917 _test-slice-literal-string: +1918 22/dquote +1919 61/a 62/b 63/c # abc +1920 2f/slash 64/d 65/e 66/f # /def +1921 22/dquote +1922 2f/slash 67/g 68/h 69/i # /ghi +1923 _test-slice-literal-string-with-limit: +1924 +1925 # . . vim:nowrap:textwidth=0 diff --git a/ntranslate b/ntranslate index 9b8eb28c..e1c6f99b 100755 --- a/ntranslate +++ b/ntranslate @@ -27,11 +27,24 @@ cat a.calls |apps/sigils > a.sigils cat a.sigils |apps/tests > a.tests -cat a.tests |apps/dquotes > a.dquotes +cat a.tests |apps/assort > a.assort -cat a.dquotes |apps/assort > a.assort +cat a.assort |apps/dquotes > a.dquotes -cat a.assort |apps/pack > a.pack +# A little hack. We want ntranslate to always emit identical binaries to the +# C++ translator. The C++ translator assorts segments before it processes +# string literals, so we follow the same order above. +# +# However, dquotes currently emits a separate data segment for string literals. +# So we need to run assort a second time to clean up after it. +# +# Potential solutions: +# a) modify C++ translator to process string literals before assorting. +# b) clean up dquotes to assume assorted segments, and append to the +# existing data segment. +cat a.dquotes |apps/assort > a.assort2 + +cat a.assort2 |apps/pack > a.pack cat a.pack |apps/survey > a.survey