From 33258e0ad2b5bbae249ca0558bdeb463af7b6148 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 19 Jan 2020 21:58:32 -0800 Subject: 5903 --- html/apps/calls.subx.html | 3151 +++++++++++++++++++++++---------------------- 1 file changed, 1576 insertions(+), 1575 deletions(-) (limited to 'html/apps/calls.subx.html') diff --git a/html/apps/calls.subx.html b/html/apps/calls.subx.html index 783ccff9..149ef8c7 100644 --- a/html/apps/calls.subx.html +++ b/html/apps/calls.subx.html @@ -144,7 +144,7 @@ if ('onhashchange' in window) { 83 # clear-stream(line) 84 # read-line-buffered(in, line) 85 # if (line->write == 0) break # end of file - 86 # skip-chars-matching-whitespace(line) + 86 # skip-chars-matching(line, ' ') 87 # if line->data[line->read] != '(' 88 # write-stream-data(out, line) 89 # continue @@ -198,1581 +198,1582 @@ if ('onhashchange' in window) { 137 # if (line->write == 0) break 138 81 7/subop/compare *esi 0/imm32 139 0f 84/jump-if-= $subx-calls:break/disp32 - 140 # skip-chars-matching-whitespace(line) + 140 # skip-chars-matching(line, ' ') 141 # . . push args - 142 56/push-esi - 143 # . . call - 144 e8/call skip-chars-matching-whitespace/disp32 - 145 # . . discard args - 146 81 0/subop/add %esp 4/imm32 - 147 # if (line->data[line->read] == '(') goto convert-call - 148 # . ecx = line->read - 149 8b/-> *(esi+4) 1/r32/ecx - 150 # . eax = line->data[line->read] - 151 31/xor %eax 0/r32/eax - 152 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 153 # . if (eax == '(') goto convert-call - 154 3d/compare-eax-and 0x28/imm32/open-paren - 155 74/jump-if-= $subx-calls:convert-call/disp8 - 156 $subx-calls:pass-through: - 157 # write-stream-data(out, line) - 158 # . . push args - 159 56/push-esi - 160 ff 6/subop/push *(ebp+0xc) - 161 # . . call - 162 e8/call write-stream-data/disp32 - 163 # . . discard args - 164 81 0/subop/add %esp 8/imm32 - 165 # continue - 166 eb/jump $subx-calls:loop/disp8 - 167 $subx-calls:convert-call: - 168 # - emit comment - 169 # write-buffered(out, "# . ") - 170 # . . push args - 171 68/push "# . "/imm32 - 172 ff 6/subop/push *(ebp+0xc) - 173 # . . call - 174 e8/call write-buffered/disp32 - 175 # . . discard args - 176 81 0/subop/add %esp 8/imm32 - 177 # write-stream-data(out, line) - 178 # . . push args - 179 56/push-esi - 180 ff 6/subop/push *(ebp+0xc) - 181 # . . call - 182 e8/call write-stream-data/disp32 - 183 # . . discard args - 184 81 0/subop/add %esp 8/imm32 - 185 # - emit code - 186 # ++line->read to skip '(' - 187 ff 0/subop/increment *(esi+4) - 188 # clear-stream(words) - 189 # . . push args - 190 52/push-edx - 191 # . . call - 192 e8/call clear-stream/disp32 - 193 # . . discard args - 194 81 0/subop/add %esp 4/imm32 - 195 # words = parse-line(line) - 196 # . . push args - 197 52/push-edx - 198 56/push-esi - 199 # . . call - 200 e8/call parse-line/disp32 - 201 # . . discard args - 202 81 0/subop/add %esp 8/imm32 - 203 # emit-call(out, words) - 204 # . . push args - 205 52/push-edx - 206 ff 6/subop/push *(ebp+0xc) - 207 # . . call - 208 e8/call emit-call/disp32 - 209 # . . discard args - 210 81 0/subop/add %esp 8/imm32 - 211 # loop - 212 e9/jump $subx-calls:loop/disp32 - 213 $subx-calls:break: - 214 # flush(out) - 215 # . . push args - 216 ff 6/subop/push *(ebp+0xc) - 217 # . . call - 218 e8/call flush/disp32 - 219 # . . discard args - 220 81 0/subop/add %esp 4/imm32 - 221 $subx-calls:end: - 222 # . reclaim locals - 223 81 0/subop/add %esp 0x298/imm32 # 0x20c + 0x8c - 224 # . restore registers - 225 5e/pop-to-esi - 226 5a/pop-to-edx - 227 59/pop-to-ecx - 228 58/pop-to-eax - 229 # . epilogue - 230 89/<- %esp 5/r32/ebp - 231 5d/pop-to-ebp - 232 c3/return - 233 - 234 parse-line: # line : (addr stream byte), words : (addr stream slice) - 235 # pseudocode: - 236 # var word-slice : slice - 237 # while true - 238 # word-slice = next-word-string-or-expression-without-metadata(line) - 239 # if slice-empty?(word-slice) - 240 # break # end of line - 241 # write-int(words, word-slice->start) - 242 # write-int(words, word-slice->end) - 243 # - 244 # . prologue - 245 55/push-ebp - 246 89/<- %ebp 4/r32/esp - 247 # . save registers - 248 51/push-ecx - 249 # var word-slice/ecx : slice - 250 68/push 0/imm32/end - 251 68/push 0/imm32/start - 252 89/<- %ecx 4/r32/esp - 253 $parse-line:loop: - 254 # word-slice = next-word-string-or-expression-without-metadata(line) - 255 # . . push args - 256 51/push-ecx - 257 ff 6/subop/push *(ebp+8) - 258 # . . call - 259 e8/call next-word-string-or-expression-without-metadata/disp32 - 260 # . . discard args - 261 81 0/subop/add %esp 8/imm32 - 262 $parse-line:check1: - 263 # if (slice-empty?(word-slice)) break - 264 # . eax = slice-empty?(word-slice) - 265 # . . push args - 266 51/push-ecx - 267 # . . call - 268 e8/call slice-empty?/disp32 - 269 # . . discard args - 270 81 0/subop/add %esp 4/imm32 - 271 # . if (eax != false) break - 272 3d/compare-eax-and 0/imm32/false - 273 0f 85/jump-if-!= $parse-line:end/disp32 - 274 +-- 40 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- - 314 $parse-line:write-word: - 315 # write-int(words, word-slice->start) - 316 # . . push args - 317 ff 6/subop/push *ecx - 318 ff 6/subop/push *(ebp+0xc) - 319 # . . call - 320 e8/call write-int/disp32 - 321 # . . discard args - 322 81 0/subop/add %esp 8/imm32 - 323 # write-int(words, word-slice->end) - 324 # . . push args - 325 ff 6/subop/push *(ecx+4) - 326 ff 6/subop/push *(ebp+0xc) - 327 # . . call - 328 e8/call write-int/disp32 - 329 # . . discard args - 330 81 0/subop/add %esp 8/imm32 - 331 # loop - 332 e9/jump $parse-line:loop/disp32 - 333 $parse-line:end: - 334 # . reclaim locals - 335 81 0/subop/add %esp 8/imm32 - 336 # . restore registers - 337 59/pop-to-ecx - 338 # . epilogue - 339 89/<- %esp 5/r32/ebp - 340 5d/pop-to-ebp - 341 c3/return - 342 - 343 emit-call: # out : (addr buffered-file), words : (addr stream slice) - 344 # pseudocode: - 345 # if (words->write < 8) abort - 346 # curr = &words->data[words->write-8] - 347 # min = words->data - 348 # # emit pushes - 349 # while true - 350 # if (curr <= min) break - 351 # if *curr->start in '%' '*' - 352 # write-buffered(out, "ff 6/subop/push ") - 353 # write-slice-buffered(out, curr) - 354 # write-buffered(out, "\n") - 355 # else - 356 # write-buffered(out, "68/push ") - 357 # write-slice-buffered(out, curr) - 358 # write-buffered(out, "/imm32\n") - 359 # curr -= 8 - 360 # # emit call - 361 # write-buffered(out, "e8/call ") - 362 # write-slice-buffered(out, curr) - 363 # write-buffered(out, "/disp32\n") - 364 # # emit pops - 365 # write-buffered(out, "81 0/subop/add %esp ") - 366 # print-int32-buffered(out, words->write >> 1 - 4) - 367 # write-buffered(out, "/imm32\n") - 368 # - 369 # . prologue - 370 55/push-ebp - 371 89/<- %ebp 4/r32/esp - 372 # . save registers - 373 50/push-eax - 374 51/push-ecx - 375 52/push-edx - 376 56/push-esi - 377 # esi = words - 378 8b/-> *(ebp+0xc) 6/r32/esi - 379 # if (words->write < 8) abort - 380 # . ecx = words->write - 8 - 381 8b/-> *esi 1/r32/ecx - 382 81 5/subop/subtract %ecx 8/imm32 - 383 0f 8c/jump-if-< $emit-call:error1/disp32 - 384 # var curr/ecx : (addr slice) = &words->data[words->write-8] - 385 8d/copy-address *(esi+ecx+0xc) 1/r32/ecx - 386 # var min/edx : (addr byte) = words->data - 387 8d/copy-address *(esi+0xc) 2/r32/edx - 388 # - emit pushes - 389 $emit-call:push-loop: - 390 # if (curr <= min) break - 391 39/compare %ecx 2/r32/edx - 392 0f 8e/jump-if-<= $emit-call:call-instruction/disp32 - 393 # if (*curr->start in '%' '*') goto push-rm32 - 394 # . var start/eax : (addr byte) = curr->start - 395 8b/-> *ecx 0/r32/eax - 396 # . var c/eax : byte = *eax - 397 8b/-> *eax 0/r32/eax - 398 81 4/subop/and %eax 0xff/imm32 - 399 # . if (c == '%') goto push-rm32 - 400 3d/compare-eax-and 0x25/imm32/percent - 401 74/jump-if-= $emit-call:push-rm32/disp8 - 402 # . if (c == '*') goto push-rm32 - 403 3d/compare-eax-and 0x2a/imm32/asterisk - 404 74/jump-if-= $emit-call:push-rm32/disp8 - 405 $emit-call:push-imm32: - 406 # write-buffered(out, "68/push ") - 407 68/push "68/push "/imm32 - 408 ff 6/subop/push *(ebp+8) - 409 # . . call - 410 e8/call write-buffered/disp32 - 411 # . . discard args - 412 81 0/subop/add %esp 8/imm32 - 413 # write-slice-buffered(out, curr) - 414 # . . push args - 415 51/push-ecx - 416 ff 6/subop/push *(ebp+8) - 417 # . . call - 418 e8/call write-slice-buffered/disp32 - 419 # . . discard args - 420 81 0/subop/add %esp 8/imm32 - 421 # write-buffered(out, "/imm32\n") - 422 68/push "/imm32\n"/imm32 - 423 ff 6/subop/push *(ebp+8) - 424 # . . call - 425 e8/call write-buffered/disp32 - 426 # . . discard args - 427 81 0/subop/add %esp 8/imm32 - 428 # continue - 429 eb/jump $emit-call:next-push/disp8 - 430 $emit-call:push-rm32: - 431 # write-buffered(out, "ff 6/subop/push ") - 432 # . . push args - 433 68/push "ff 6/subop/push "/imm32 - 434 ff 6/subop/push *(ebp+8) - 435 # . . call - 436 e8/call write-buffered/disp32 - 437 # . . discard args - 438 81 0/subop/add %esp 8/imm32 - 439 # write-slice-buffered(out, curr) - 440 # . . push args - 441 51/push-ecx - 442 ff 6/subop/push *(ebp+8) - 443 # . . call - 444 e8/call write-slice-buffered/disp32 - 445 # . . discard args - 446 81 0/subop/add %esp 8/imm32 - 447 # write-buffered(out, "\n") - 448 68/push Newline/imm32 - 449 ff 6/subop/push *(ebp+8) - 450 # . . call - 451 e8/call write-buffered/disp32 - 452 # . . discard args - 453 81 0/subop/add %esp 8/imm32 - 454 $emit-call:next-push: - 455 # curr -= 8 - 456 81 5/subop/subtract %ecx 8/imm32 - 457 # loop - 458 e9/jump $emit-call:push-loop/disp32 - 459 $emit-call:call-instruction: - 460 # write-buffered(out, "e8/call ") - 461 68/push "e8/call "/imm32 - 462 ff 6/subop/push *(ebp+8) - 463 # . . call - 464 e8/call write-buffered/disp32 - 465 # . . discard args - 466 81 0/subop/add %esp 8/imm32 - 467 # write-slice-buffered(out, curr) - 468 # . . push args - 469 51/push-ecx - 470 ff 6/subop/push *(ebp+8) - 471 # . . call - 472 e8/call write-slice-buffered/disp32 - 473 # . . discard args - 474 81 0/subop/add %esp 8/imm32 - 475 # write-buffered(out, "/disp32\n") - 476 68/push "/disp32\n"/imm32 - 477 ff 6/subop/push *(ebp+8) - 478 # . . call - 479 e8/call write-buffered/disp32 - 480 # . . discard args - 481 81 0/subop/add %esp 8/imm32 - 482 $emit-call:pop-instruction: - 483 # write-buffered(out, "81 0/subop/add %esp ") - 484 68/push "81 0/subop/add %esp "/imm32 - 485 ff 6/subop/push *(ebp+8) - 486 # . . call - 487 e8/call write-buffered/disp32 - 488 # . . discard args - 489 81 0/subop/add %esp 8/imm32 - 490 # print-int32-buffered(out, words->write >> 1 - 4) - 491 # . . push args - 492 8b/-> *esi 0/r32/eax - 493 c1/shift 7/subop/arith-right %eax 1/imm8 - 494 2d/subtract-from-eax 4/imm32 - 495 50/push-eax - 496 ff 6/subop/push *(ebp+8) - 497 # . . call - 498 e8/call print-int32-buffered/disp32 - 499 # . . discard args - 500 81 0/subop/add %esp 8/imm32 - 501 # write-buffered(out, "/imm32\n") - 502 68/push "/imm32\n"/imm32 - 503 ff 6/subop/push *(ebp+8) - 504 # . . call - 505 e8/call write-buffered/disp32 - 506 # . . discard args - 507 81 0/subop/add %esp 8/imm32 - 508 $emit-call:end: - 509 # . restore registers - 510 5e/pop-to-esi - 511 5a/pop-to-edx - 512 59/pop-to-ecx - 513 58/pop-to-eax - 514 # . epilogue - 515 89/<- %esp 5/r32/ebp - 516 5d/pop-to-ebp - 517 c3/return - 518 - 519 $emit-call:error1: - 520 # print(stderr, "error: calls.subx: '()' is not a valid call") - 521 # . write-buffered(Stderr, "error: calls.subx: '()' is not a valid call") - 522 # . . push args - 523 68/push "error: calls.subx: '()' is not a valid call"/imm32 - 524 68/push Stderr/imm32 - 525 # . . call - 526 e8/call write-buffered/disp32 - 527 # . . discard args - 528 81 0/subop/add %esp 8/imm32 - 529 # . flush(Stderr) - 530 # . . push args - 531 68/push Stderr/imm32 - 532 # . . call - 533 e8/call flush/disp32 - 534 # . . discard args - 535 81 0/subop/add %esp 4/imm32 - 536 # . syscall(exit, 1) - 537 bb/copy-to-ebx 1/imm32 - 538 b8/copy-to-eax 1/imm32/exit - 539 cd/syscall 0x80/imm8 - 540 # never gets here - 541 - 542 test-subx-calls-passes-most-lines-through: - 543 # . prologue - 544 55/push-ebp - 545 89/<- %ebp 4/r32/esp - 546 # setup - 547 # . clear-stream(_test-input-stream) - 548 # . . push args - 549 68/push _test-input-stream/imm32 - 550 # . . call - 551 e8/call clear-stream/disp32 - 552 # . . discard args - 553 81 0/subop/add %esp 4/imm32 - 554 # . clear-stream($_test-input-buffered-file->buffer) - 555 # . . push args - 556 68/push $_test-input-buffered-file->buffer/imm32 - 557 # . . call - 558 e8/call clear-stream/disp32 - 559 # . . discard args - 560 81 0/subop/add %esp 4/imm32 - 561 # . clear-stream(_test-output-stream) - 562 # . . push args - 563 68/push _test-output-stream/imm32 - 564 # . . call - 565 e8/call clear-stream/disp32 - 566 # . . discard args - 567 81 0/subop/add %esp 4/imm32 - 568 # . clear-stream($_test-output-buffered-file->buffer) - 569 # . . push args - 570 68/push $_test-output-buffered-file->buffer/imm32 - 571 # . . call - 572 e8/call clear-stream/disp32 - 573 # . . discard args - 574 81 0/subop/add %esp 4/imm32 - 575 # . write(_test-input-stream, "== abcd 0x1\n") - 576 # . . push args - 577 68/push "== abcd 0x1\n"/imm32 - 578 68/push _test-input-stream/imm32 - 579 # . . call - 580 e8/call write/disp32 - 581 # . . discard args - 582 81 0/subop/add %esp 8/imm32 - 583 # subx-calls(_test-input-buffered-file, _test-output-buffered-file) - 584 # . . push args - 585 68/push _test-output-buffered-file/imm32 - 586 68/push _test-input-buffered-file/imm32 - 587 # . . call - 588 e8/call subx-calls/disp32 - 589 # . . discard args - 590 81 0/subop/add %esp 8/imm32 - 591 # check that the line just passed through - 592 # . flush(_test-output-buffered-file) - 593 # . . push args - 594 68/push _test-output-buffered-file/imm32 - 595 # . . call - 596 e8/call flush/disp32 - 597 # . . discard args - 598 81 0/subop/add %esp 4/imm32 - 599 # . check-stream-equal(_test-output-stream, "== abcd 0x1\n", msg) - 600 # . . push args - 601 68/push "F - test-subx-calls-passes-most-lines-through"/imm32 - 602 68/push "== abcd 0x1\n"/imm32 - 603 68/push _test-output-stream/imm32 - 604 # . . call - 605 e8/call check-stream-equal/disp32 - 606 # . . discard args - 607 81 0/subop/add %esp 0xc/imm32 - 608 # . epilogue - 609 89/<- %esp 5/r32/ebp - 610 5d/pop-to-ebp - 611 c3/return - 612 - 613 test-subx-calls-processes-calls: - 614 # . prologue - 615 55/push-ebp - 616 89/<- %ebp 4/r32/esp - 617 # setup - 618 # . clear-stream(_test-input-stream) - 619 # . . push args - 620 68/push _test-input-stream/imm32 - 621 # . . call - 622 e8/call clear-stream/disp32 - 623 # . . discard args - 624 81 0/subop/add %esp 4/imm32 - 625 # . clear-stream($_test-input-buffered-file->buffer) - 626 # . . push args - 627 68/push $_test-input-buffered-file->buffer/imm32 - 628 # . . call - 629 e8/call clear-stream/disp32 - 630 # . . discard args - 631 81 0/subop/add %esp 4/imm32 - 632 # . clear-stream(_test-output-stream) - 633 # . . push args - 634 68/push _test-output-stream/imm32 - 635 # . . call - 636 e8/call clear-stream/disp32 - 637 # . . discard args - 638 81 0/subop/add %esp 4/imm32 - 639 # . clear-stream($_test-output-buffered-file->buffer) - 640 # . . push args - 641 68/push $_test-output-buffered-file->buffer/imm32 - 642 # . . call - 643 e8/call clear-stream/disp32 - 644 # . . discard args - 645 81 0/subop/add %esp 4/imm32 - 646 # . write(_test-input-stream, "(foo %eax)\n") - 647 # . . push args - 648 68/push "(foo %eax)\n"/imm32 - 649 68/push _test-input-stream/imm32 - 650 # . . call - 651 e8/call write/disp32 - 652 # . . discard args - 653 81 0/subop/add %esp 8/imm32 - 654 # subx-calls(_test-input-buffered-file, _test-output-buffered-file) - 655 # . . push args - 656 68/push _test-output-buffered-file/imm32 - 657 68/push _test-input-buffered-file/imm32 - 658 # . . call - 659 e8/call subx-calls/disp32 - 660 # . . discard args - 661 81 0/subop/add %esp 8/imm32 - 662 # check that the line just passed through - 663 # . flush(_test-output-buffered-file) - 664 # . . push args - 665 68/push _test-output-buffered-file/imm32 - 666 # . . call - 667 e8/call flush/disp32 - 668 # . . discard args - 669 81 0/subop/add %esp 4/imm32 - 670 +-- 33 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- - 703 # . check-next-stream-line-equal(_test-output-stream, "# . (foo %eax)", msg) - 704 # . . push args - 705 68/push "F - test-subx-calls-processes-calls: comment"/imm32 - 706 68/push "# . (foo %eax)"/imm32 - 707 68/push _test-output-stream/imm32 - 708 # . . call - 709 e8/call check-next-stream-line-equal/disp32 - 710 # . . discard args - 711 81 0/subop/add %esp 0xc/imm32 - 712 # . check-next-stream-line-equal(_test-output-stream, "ff 6/subop/push %eax", msg) - 713 # . . push args - 714 68/push "F - test-subx-calls-processes-calls: arg 0"/imm32 - 715 68/push "ff 6/subop/push %eax"/imm32 - 716 68/push _test-output-stream/imm32 - 717 # . . call - 718 e8/call check-next-stream-line-equal/disp32 - 719 # . . discard args - 720 81 0/subop/add %esp 0xc/imm32 - 721 # . check-next-stream-line-equal(_test-output-stream, "e8/call foo/disp32", msg) - 722 # . . push args - 723 68/push "F - test-subx-calls-processes-calls: call"/imm32 - 724 68/push "e8/call foo/disp32"/imm32 - 725 68/push _test-output-stream/imm32 - 726 # . . call - 727 e8/call check-next-stream-line-equal/disp32 - 728 # . . discard args - 729 81 0/subop/add %esp 0xc/imm32 - 730 # . check-next-stream-line-equal(_test-output-stream, "81 0/subop/add %esp 4/imm32", msg) - 731 # . . push args - 732 68/push "F - test-subx-calls-processes-calls: pops"/imm32 - 733 68/push "81 0/subop/add %esp 0x00000004/imm32"/imm32 - 734 68/push _test-output-stream/imm32 - 735 # . . call - 736 e8/call check-next-stream-line-equal/disp32 - 737 # . . discard args - 738 81 0/subop/add %esp 0xc/imm32 - 739 # . epilogue - 740 89/<- %esp 5/r32/ebp - 741 5d/pop-to-ebp - 742 c3/return - 743 - 744 next-word-string-or-expression-without-metadata: # line : (addr stream byte), out : (addr slice) - 745 # pseudocode: - 746 # skip-chars-matching(line, ' ') - 747 # if line->read >= line->write # end of line - 748 # out = {0, 0} - 749 # return - 750 # out->start = &line->data[line->read] - 751 # if line->data[line->read] == '#' # comment - 752 # out->end = &line->data[line->write] # skip to end of line - 753 # return - 754 # if line->data[line->read] == '"' # string literal - 755 # skip-string(line) - 756 # out->end = &line->data[line->read] # no metadata - 757 # return - 758 # if line->data[line->read] == '*' # expression - 759 # if line->data[line->read + 1] == ' ' - 760 # abort - 761 # if line->data[line->read + 1] == '(' - 762 # skip-until-close-paren(line) - 763 # if (line->data[line->read] != ')' - 764 # abort - 765 # ++line->read to skip ')' - 766 # out->end = &line->data[line->read] - 767 # return - 768 # if line->data[line->read] == ')' - 769 # ++line->read to skip ')' - 770 # # make sure there's nothing else of importance - 771 # if line->read >= line->write - 772 # out = {0, 0} - 773 # return - 774 # if line->data[line->read] != ' ' - 775 # abort - 776 # skip-chars-matching-whitespace(line) - 777 # if line->read >= line->write - 778 # out = {0, 0} - 779 # return - 780 # if line->data[line->read] == '#' # only thing permitted after ')' is a comment - 781 # out = {0, 0} - 782 # return - 783 # abort - 784 # # default case: read a word -- but no metadata - 785 # while true - 786 # if line->read >= line->write - 787 # break - 788 # if line->data[line->read] == ' ' - 789 # break - 790 # if line->data[line->read] == ')' - 791 # break - 792 # if line->data[line->read] == '/' - 793 # abort - 794 # ++line->read - 795 # out->end = &line->data[line->read] - 796 # - 797 # registers: - 798 # ecx: often line->read - 799 # eax: often line->data[line->read] - 800 # - 801 # . prologue - 802 55/push-ebp - 803 89/<- %ebp 4/r32/esp - 804 # . save registers - 805 50/push-eax - 806 51/push-ecx - 807 56/push-esi - 808 57/push-edi - 809 # esi = line - 810 8b/-> *(ebp+8) 6/r32/esi - 811 # edi = out - 812 8b/-> *(ebp+0xc) 7/r32/edi - 813 # skip-chars-matching(line, ' ') - 814 # . . push args - 815 68/push 0x20/imm32/space - 816 ff 6/subop/push *(ebp+8) - 817 # . . call - 818 e8/call skip-chars-matching/disp32 - 819 # . . discard args - 820 81 0/subop/add %esp 8/imm32 - 821 $next-word-string-or-expression-without-metadata:check0: - 822 # if (line->read >= line->write) return out = {0, 0} - 823 # . ecx = line->read - 824 8b/-> *(esi+4) 1/r32/ecx - 825 # . if (ecx >= line->write) return out = {0, 0} - 826 3b/compare 1/r32/ecx *esi - 827 0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:return-eol/disp32 - 828 $next-word-string-or-expression-without-metadata:check-for-comment: - 829 # out->start = &line->data[line->read] - 830 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 831 89/<- *edi 0/r32/eax - 832 # if (line->data[line->read] != '#') goto next check - 833 # . var eax : byte = line->data[line->read] - 834 31/xor %eax 0/r32/eax - 835 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 836 # . if (eax != '#') goto next check - 837 3d/compare-eax-and 0x23/imm32/pound - 838 75/jump-if-!= $next-word-string-or-expression-without-metadata:check-for-string-literal/disp8 - 839 $next-word-string-or-expression-without-metadata:comment: - 840 # out->end = &line->data[line->write] - 841 8b/-> *esi 0/r32/eax - 842 8d/copy-address *(esi+eax+0xc) 0/r32/eax - 843 89/<- *(edi+4) 0/r32/eax - 844 # line->read = line->write # skip rest of line - 845 8b/-> *esi 0/r32/eax - 846 89/<- *(esi+4) 0/r32/eax - 847 # return - 848 e9/jump $next-word-string-or-expression-without-metadata:end/disp32 - 849 $next-word-string-or-expression-without-metadata:check-for-string-literal: - 850 # if (line->data[line->read] != '"') goto next check - 851 3d/compare-eax-and 0x22/imm32/dquote - 852 75/jump-if-!= $next-word-string-or-expression-without-metadata:check-for-expression/disp8 - 853 $next-word-string-or-expression-without-metadata:string-literal: - 854 # skip-string(line) - 855 # . . push args - 856 56/push-esi - 857 # . . call - 858 e8/call skip-string/disp32 - 859 # . . discard args - 860 81 0/subop/add %esp 4/imm32 - 861 # out->end = &line->data[line->read] - 862 8b/-> *(esi+4) 1/r32/ecx - 863 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 864 89/<- *(edi+4) 0/r32/eax - 865 # return - 866 e9/jump $next-word-string-or-expression-without-metadata:end/disp32 - 867 $next-word-string-or-expression-without-metadata:check-for-expression: - 868 # if (line->data[line->read] != '*') goto next check - 869 3d/compare-eax-and 0x2a/imm32/asterisk - 870 75/jump-if-!= $next-word-string-or-expression-without-metadata:check-for-end-of-call/disp8 - 871 # if (line->data[line->read + 1] == ' ') goto error1 - 872 8a/copy-byte *(esi+ecx+0xd) 0/r32/AL - 873 3d/compare-eax-and 0x20/imm32/space - 874 0f 84/jump-if-= $next-word-string-or-expression-without-metadata:error1/disp32 - 875 # if (line->data[line->read + 1] != '(') goto regular-word - 876 3d/compare-eax-and 0x28/imm32/open-paren - 877 0f 85/jump-if-!= $next-word-string-or-expression-without-metadata:regular-word-without-metadata/disp32 - 878 $next-word-string-or-expression-without-metadata:paren: - 879 # skip-until-close-paren(line) - 880 # . . push args - 881 56/push-esi - 882 # . . call - 883 e8/call skip-until-close-paren/disp32 - 884 # . . discard args - 885 81 0/subop/add %esp 4/imm32 - 886 # if (line->data[line->read] != ')') goto error2 - 887 # . eax = line->data[line->read] - 888 8b/-> *(esi+4) 1/r32/ecx - 889 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 890 # . if (eax != ')') goto error2 - 891 3d/compare-eax-and 0x29/imm32/close-paren - 892 0f 85/jump-if-!= $next-word-string-or-expression-without-metadata:error2/disp32 - 893 # ++line->read to skip ')' - 894 ff 0/subop/increment *(esi+4) - 895 # out->end = &line->data[line->read] - 896 8b/-> *(esi+4) 1/r32/ecx - 897 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 898 89/<- *(edi+4) 0/r32/eax - 899 # return - 900 e9/jump $next-word-string-or-expression-without-metadata:end/disp32 - 901 $next-word-string-or-expression-without-metadata:check-for-end-of-call: - 902 # if (line->data[line->read] != ')') goto next check - 903 3d/compare-eax-and 0x29/imm32/close-paren - 904 75/jump-if-!= $next-word-string-or-expression-without-metadata:regular-word-without-metadata/disp8 - 905 # ++line->read to skip ')' - 906 ff 0/subop/increment *(esi+4) - 907 # - error checking: make sure there's nothing else of importance on the line - 908 # if (line->read >= line->write) return out = {0, 0} - 909 # . ecx = line->read - 910 8b/-> *(esi+4) 1/r32/ecx - 911 # . if (ecx >= line->write) return {0, 0} - 912 3b/compare 1/r32/ecx *esi - 913 0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:return-eol/disp32 - 914 # if (line->data[line->read] == '/') goto error3 - 915 # . eax = line->data[line->read] - 916 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 917 # . if (eax == '/') goto error3 - 918 3d/compare-eax-and 0x2f/imm32/slash - 919 0f 84/jump-if-= $next-word-string-or-expression-without-metadata:error3/disp32 - 920 # skip-chars-matching-whitespace(line) - 921 # . . push args - 922 56/push-esi - 923 # . . call - 924 e8/call skip-chars-matching-whitespace/disp32 - 925 # . . discard args - 926 81 0/subop/add %esp 4/imm32 - 927 # if (line->read >= line->write) return out = {0, 0} - 928 # . ecx = line->read - 929 8b/-> *(esi+4) 1/r32/ecx - 930 # . if (ecx >= line->write) return {0, 0} - 931 3b/compare 1/r32/ecx *esi - 932 0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:return-eol/disp32 - 933 # if (line->data[line->read] == '#') return out = {0, 0} - 934 # . eax = line->data[line->read] - 935 8b/-> *(esi+4) 1/r32/ecx - 936 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 937 # . if (eax == '#') return out = {0, 0} - 938 3d/compare-eax-and 0x23/imm32/pound - 939 74/jump-if-= $next-word-string-or-expression-without-metadata:return-eol/disp8 - 940 # otherwise goto error4 - 941 e9/jump $next-word-string-or-expression-without-metadata:error4/disp32 - 942 $next-word-string-or-expression-without-metadata:regular-word-without-metadata: - 943 # if (line->read >= line->write) break - 944 # . ecx = line->read - 945 8b/-> *(esi+4) 1/r32/ecx - 946 # . if (ecx >= line->write) break - 947 3b/compare *esi 1/r32/ecx - 948 7d/jump-if->= $next-word-string-or-expression-without-metadata:regular-word-break/disp8 - 949 # if (line->data[line->read] == ' ') break - 950 # . eax = line->data[line->read] - 951 8b/-> *(esi+4) 1/r32/ecx - 952 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 953 # . if (eax == ' ') break - 954 3d/compare-eax-and 0x20/imm32/space - 955 74/jump-if-= $next-word-string-or-expression-without-metadata:regular-word-break/disp8 - 956 # if (line->data[line->read] == ')') break - 957 3d/compare-eax-and 0x29/imm32/close-paren - 958 0f 84/jump-if-= $next-word-string-or-expression-without-metadata:regular-word-break/disp32 - 959 # if (line->data[line->read] == '/') goto error5 - 960 3d/compare-eax-and 0x2f/imm32/slash - 961 0f 84/jump-if-= $next-word-string-or-expression-without-metadata:error5/disp32 - 962 # ++line->read - 963 ff 0/subop/increment *(esi+4) - 964 # loop - 965 e9/jump $next-word-string-or-expression-without-metadata:regular-word-without-metadata/disp32 - 966 $next-word-string-or-expression-without-metadata:regular-word-break: - 967 # out->end = &line->data[line->read] - 968 8b/-> *(esi+4) 1/r32/ecx - 969 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 970 89/<- *(edi+4) 0/r32/eax - 971 eb/jump $next-word-string-or-expression-without-metadata:end/disp8 - 972 $next-word-string-or-expression-without-metadata:return-eol: - 973 # return out = {0, 0} - 974 c7 0/subop/copy *edi 0/imm32 - 975 c7 0/subop/copy *(edi+4) 0/imm32 - 976 $next-word-string-or-expression-without-metadata:end: - 977 # . restore registers - 978 5f/pop-to-edi - 979 5e/pop-to-esi - 980 59/pop-to-ecx - 981 58/pop-to-eax - 982 # . epilogue - 983 89/<- %esp 5/r32/ebp - 984 5d/pop-to-ebp - 985 c3/return - 986 - 987 $next-word-string-or-expression-without-metadata:error1: - 988 # print(stderr, "error: no space allowed after '*' in '" line "'") - 989 # . write-buffered(Stderr, "error: no space allowed after '*' in '") - 990 # . . push args - 991 68/push "error: no space allowed after '*' in '"/imm32 - 992 68/push Stderr/imm32 - 993 # . . call - 994 e8/call write-buffered/disp32 - 995 # . . discard args - 996 81 0/subop/add %esp 8/imm32 - 997 # . write-stream-data(Stderr, line) - 998 # . . push args - 999 56/push-esi -1000 68/push Stderr/imm32 -1001 # . . call -1002 e8/call write-stream-data/disp32 -1003 # . . discard args -1004 81 0/subop/add %esp 8/imm32 -1005 # . write-buffered(Stderr, "'") -1006 # . . push args -1007 68/push "'"/imm32 -1008 68/push Stderr/imm32 -1009 # . . call -1010 e8/call write-buffered/disp32 -1011 # . . discard args -1012 81 0/subop/add %esp 8/imm32 -1013 # . flush(Stderr) -1014 # . . push args -1015 68/push Stderr/imm32 -1016 # . . call -1017 e8/call flush/disp32 -1018 # . . discard args -1019 81 0/subop/add %esp 4/imm32 -1020 # . syscall(exit, 1) -1021 bb/copy-to-ebx 1/imm32 -1022 b8/copy-to-eax 1/imm32/exit -1023 cd/syscall 0x80/imm8 -1024 # never gets here -1025 -1026 $next-word-string-or-expression-without-metadata:error2: -1027 # print(stderr, "error: *(...) expression must be all on a single line in '" line "'") -1028 # . write-buffered(Stderr, "error: *(...) expression must be all on a single line in '") -1029 # . . push args -1030 68/push "error: *(...) expression must be all on a single line in '"/imm32 -1031 68/push Stderr/imm32 -1032 # . . call -1033 e8/call write-buffered/disp32 -1034 # . . discard args -1035 81 0/subop/add %esp 8/imm32 -1036 # . write-stream-data(Stderr, line) -1037 # . . push args -1038 56/push-esi -1039 68/push Stderr/imm32 -1040 # . . call -1041 e8/call write-stream-data/disp32 -1042 # . . discard args -1043 81 0/subop/add %esp 8/imm32 -1044 # . write-buffered(Stderr, "'") -1045 # . . push args -1046 68/push "'"/imm32 -1047 68/push Stderr/imm32 -1048 # . . call -1049 e8/call write-buffered/disp32 -1050 # . . discard args -1051 81 0/subop/add %esp 8/imm32 -1052 # . flush(Stderr) -1053 # . . push args -1054 68/push Stderr/imm32 -1055 # . . call -1056 e8/call flush/disp32 -1057 # . . discard args -1058 81 0/subop/add %esp 4/imm32 -1059 # . syscall(exit, 1) -1060 bb/copy-to-ebx 1/imm32 -1061 b8/copy-to-eax 1/imm32/exit -1062 cd/syscall 0x80/imm8 -1063 # never gets here -1064 -1065 $next-word-string-or-expression-without-metadata:error3: -1066 # print(stderr, "error: no metadata after calls; just use a comment (in '" line "')") -1067 # . write-buffered(Stderr, "error: no metadata after calls; just use a comment (in '") -1068 # . . push args -1069 68/push "error: no metadata after calls; just use a comment (in '"/imm32 -1070 68/push Stderr/imm32 -1071 # . . call -1072 e8/call write-buffered/disp32 -1073 # . . discard args -1074 81 0/subop/add %esp 8/imm32 -1075 # . write-stream-data(Stderr, line) -1076 # . . push args -1077 56/push-esi -1078 68/push Stderr/imm32 -1079 # . . call -1080 e8/call write-stream-data/disp32 -1081 # . . discard args -1082 81 0/subop/add %esp 8/imm32 -1083 # . write-buffered(Stderr, "')") -1084 # . . push args -1085 68/push "')"/imm32 -1086 68/push Stderr/imm32 -1087 # . . call -1088 e8/call write-buffered/disp32 -1089 # . . discard args -1090 81 0/subop/add %esp 8/imm32 -1091 # . flush(Stderr) -1092 # . . push args -1093 68/push Stderr/imm32 -1094 # . . call -1095 e8/call flush/disp32 -1096 # . . discard args -1097 81 0/subop/add %esp 4/imm32 -1098 # . syscall(exit, 1) -1099 bb/copy-to-ebx 1/imm32 -1100 b8/copy-to-eax 1/imm32/exit -1101 cd/syscall 0x80/imm8 -1102 # never gets here -1103 -1104 $next-word-string-or-expression-without-metadata:error4: -1105 # print(stderr, "error: unexpected text after end of call in '" line "'") -1106 # . write-buffered(Stderr, "error: unexpected text after end of call in '") -1107 # . . push args -1108 68/push "error: unexpected text after end of call in '"/imm32 -1109 68/push Stderr/imm32 -1110 # . . call -1111 e8/call write-buffered/disp32 -1112 # . . discard args -1113 81 0/subop/add %esp 8/imm32 -1114 # . write-stream-data(Stderr, line) -1115 # . . push args -1116 56/push-esi -1117 68/push Stderr/imm32 -1118 # . . call -1119 e8/call write-stream-data/disp32 -1120 # . . discard args -1121 81 0/subop/add %esp 8/imm32 -1122 # . write-buffered(Stderr, "'") -1123 # . . push args -1124 68/push "'"/imm32 -1125 68/push Stderr/imm32 -1126 # . . call -1127 e8/call write-buffered/disp32 -1128 # . . discard args -1129 81 0/subop/add %esp 8/imm32 -1130 # . flush(Stderr) -1131 # . . push args -1132 68/push Stderr/imm32 -1133 # . . call -1134 e8/call flush/disp32 -1135 # . . discard args -1136 81 0/subop/add %esp 4/imm32 -1137 # . syscall(exit, 1) -1138 bb/copy-to-ebx 1/imm32 -1139 b8/copy-to-eax 1/imm32/exit -1140 cd/syscall 0x80/imm8 -1141 # never gets here -1142 -1143 $next-word-string-or-expression-without-metadata:error5: -1144 # print(stderr, "error: no metadata anywhere in calls (in '" line "')") -1145 # . write-buffered(Stderr, "error: no metadata anywhere in calls (in '") -1146 # . . push args -1147 68/push "error: no metadata anywhere in calls (in '"/imm32 -1148 68/push Stderr/imm32 -1149 # . . call -1150 e8/call write-buffered/disp32 -1151 # . . discard args -1152 81 0/subop/add %esp 8/imm32 -1153 # . write-stream-data(Stderr, line) -1154 # . . push args -1155 56/push-esi -1156 68/push Stderr/imm32 -1157 # . . call -1158 e8/call write-stream-data/disp32 -1159 # . . discard args -1160 81 0/subop/add %esp 8/imm32 -1161 # . write-buffered(Stderr, "')") -1162 # . . push args -1163 68/push "')"/imm32 -1164 68/push Stderr/imm32 -1165 # . . call -1166 e8/call write-buffered/disp32 -1167 # . . discard args -1168 81 0/subop/add %esp 8/imm32 -1169 # . flush(Stderr) -1170 # . . push args -1171 68/push Stderr/imm32 -1172 # . . call -1173 e8/call flush/disp32 -1174 # . . discard args -1175 81 0/subop/add %esp 4/imm32 -1176 # . syscall(exit, 1) -1177 bb/copy-to-ebx 1/imm32 -1178 b8/copy-to-eax 1/imm32/exit -1179 cd/syscall 0x80/imm8 -1180 # never gets here -1181 -1182 test-next-word-string-or-expression-without-metadata: -1183 # . prologue -1184 55/push-ebp -1185 89/<- %ebp 4/r32/esp -1186 # setup -1187 # . clear-stream(_test-input-stream) -1188 # . . push args -1189 68/push _test-input-stream/imm32 -1190 # . . call -1191 e8/call clear-stream/disp32 -1192 # . . discard args -1193 81 0/subop/add %esp 4/imm32 -1194 # var slice/ecx : slice -1195 68/push 0/imm32/end -1196 68/push 0/imm32/start -1197 89/<- %ecx 4/r32/esp -1198 # write(_test-input-stream, " ab") -1199 # . . push args -1200 68/push " ab"/imm32 -1201 68/push _test-input-stream/imm32 -1202 # . . call -1203 e8/call write/disp32 -1204 # . . discard args -1205 81 0/subop/add %esp 8/imm32 -1206 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1207 # . . push args -1208 51/push-ecx -1209 68/push _test-input-stream/imm32 -1210 # . . call -1211 e8/call next-word-string-or-expression-without-metadata/disp32 -1212 # . . discard args -1213 81 0/subop/add %esp 8/imm32 -1214 # check-ints-equal(_test-input-stream->read, 4, msg) -1215 # . . push args -1216 68/push "F - test-next-word-string-or-expression-without-metadata/updates-stream-read-correctly"/imm32 -1217 68/push 4/imm32 -1218 b8/copy-to-eax _test-input-stream/imm32 -1219 ff 6/subop/push *(eax+4) -1220 # . . call -1221 e8/call check-ints-equal/disp32 -1222 # . . discard args -1223 81 0/subop/add %esp 0xc/imm32 -1224 # check-ints-equal(slice->start - _test-input-stream->data, 2, msg) -1225 # . check-ints-equal(slice->start - _test-input-stream, 14, msg) -1226 # . . push args -1227 68/push "F - test-next-word-string-or-expression-without-metadata: start"/imm32 -1228 68/push 0xe/imm32 -1229 # . . push slice->start - _test-input-stream -1230 8b/-> *ecx 0/r32/eax -1231 81 5/subop/subtract %eax _test-input-stream/imm32 -1232 50/push-eax -1233 # . . call -1234 e8/call check-ints-equal/disp32 -1235 # . . discard args -1236 81 0/subop/add %esp 0xc/imm32 -1237 # check-ints-equal(slice->end - _test-input-stream->data, 4, msg) -1238 # . check-ints-equal(slice->end - _test-input-stream, 16, msg) -1239 # . . push args -1240 68/push "F - test-next-word-string-or-expression-without-metadata: end"/imm32 -1241 68/push 0x10/imm32 -1242 # . . push slice->end - _test-input-stream -1243 8b/-> *(ecx+4) 0/r32/eax -1244 81 5/subop/subtract %eax _test-input-stream/imm32 -1245 50/push-eax -1246 # . . call -1247 e8/call check-ints-equal/disp32 -1248 # . . discard args -1249 81 0/subop/add %esp 0xc/imm32 -1250 # . epilogue -1251 89/<- %esp 5/r32/ebp -1252 5d/pop-to-ebp -1253 c3/return -1254 -1255 test-next-word-string-or-expression-without-metadata-returns-whole-comment: -1256 # . prologue -1257 55/push-ebp -1258 89/<- %ebp 4/r32/esp -1259 # setup -1260 # . clear-stream(_test-input-stream) -1261 # . . push args -1262 68/push _test-input-stream/imm32 -1263 # . . call -1264 e8/call clear-stream/disp32 -1265 # . . discard args -1266 81 0/subop/add %esp 4/imm32 -1267 # var slice/ecx : slice -1268 68/push 0/imm32/end -1269 68/push 0/imm32/start -1270 89/<- %ecx 4/r32/esp -1271 # write(_test-input-stream, " # a") -1272 # . . push args -1273 68/push " # a"/imm32 -1274 68/push _test-input-stream/imm32 -1275 # . . call -1276 e8/call write/disp32 -1277 # . . discard args -1278 81 0/subop/add %esp 8/imm32 -1279 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1280 # . . push args -1281 51/push-ecx -1282 68/push _test-input-stream/imm32 -1283 # . . call -1284 e8/call next-word-string-or-expression-without-metadata/disp32 -1285 # . . discard args -1286 81 0/subop/add %esp 8/imm32 -1287 # check-ints-equal(_test-input-stream->read, 5, msg) -1288 # . . push args -1289 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-comment/updates-stream-read-correctly"/imm32 -1290 68/push 5/imm32 -1291 b8/copy-to-eax _test-input-stream/imm32 -1292 ff 6/subop/push *(eax+4) -1293 # . . call -1294 e8/call check-ints-equal/disp32 -1295 # . . discard args -1296 81 0/subop/add %esp 0xc/imm32 -1297 # check-ints-equal(slice->start - _test-input-stream->data, 2, msg) -1298 # . check-ints-equal(slice->start - _test-input-stream, 14, msg) -1299 # . . push args -1300 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-comment: start"/imm32 -1301 68/push 0xe/imm32 -1302 # . . push slice->start - _test-input-stream -1303 8b/-> *ecx 0/r32/eax -1304 81 5/subop/subtract %eax _test-input-stream/imm32 -1305 50/push-eax -1306 # . . call -1307 e8/call check-ints-equal/disp32 -1308 # . . discard args -1309 81 0/subop/add %esp 0xc/imm32 -1310 # check-ints-equal(slice->end - _test-input-stream->data, 5, msg) -1311 # . check-ints-equal(slice->end - _test-input-stream, 17, msg) -1312 # . . push args -1313 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-comment: end"/imm32 -1314 68/push 0x11/imm32 -1315 # . . push slice->end - _test-input-stream -1316 8b/-> *(ecx+4) 0/r32/eax -1317 81 5/subop/subtract %eax _test-input-stream/imm32 -1318 50/push-eax -1319 # . . call -1320 e8/call check-ints-equal/disp32 -1321 # . . discard args -1322 81 0/subop/add %esp 0xc/imm32 -1323 # . epilogue -1324 89/<- %esp 5/r32/ebp -1325 5d/pop-to-ebp -1326 c3/return -1327 -1328 test-next-word-string-or-expression-without-metadata-returns-empty-slice-on-eof: -1329 # . prologue -1330 55/push-ebp -1331 89/<- %ebp 4/r32/esp -1332 # setup -1333 # . clear-stream(_test-input-stream) -1334 # . . push args -1335 68/push _test-input-stream/imm32 -1336 # . . call -1337 e8/call clear-stream/disp32 -1338 # . . discard args -1339 81 0/subop/add %esp 4/imm32 -1340 # var slice/ecx : slice -1341 68/push 0/imm32/end -1342 68/push 0/imm32/start -1343 89/<- %ecx 4/r32/esp -1344 # write nothing to _test-input-stream -1345 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1346 # . . push args -1347 51/push-ecx -1348 68/push _test-input-stream/imm32 -1349 # . . call -1350 e8/call next-word-string-or-expression-without-metadata/disp32 -1351 # . . discard args -1352 81 0/subop/add %esp 8/imm32 -1353 # check-ints-equal(slice->end - slice->start, 0, msg) -1354 # . . push args -1355 68/push "F - test-next-word-string-or-expression-without-metadata-returns-empty-expression-on-eof"/imm32 -1356 68/push 0/imm32 -1357 # . . push slice->end - slice->start -1358 8b/-> *(ecx+4) 0/r32/eax -1359 2b/subtract-> *ecx 0/r32/eax # subtract *ecx from eax -1360 50/push-eax -1361 # . . call -1362 e8/call check-ints-equal/disp32 -1363 # . . discard args -1364 81 0/subop/add %esp 0xc/imm32 -1365 # . epilogue -1366 89/<- %esp 5/r32/ebp -1367 5d/pop-to-ebp -1368 c3/return -1369 -1370 test-next-word-string-or-expression-without-metadata-returns-string-literal: -1371 # . prologue -1372 55/push-ebp -1373 89/<- %ebp 4/r32/esp -1374 # setup -1375 # . clear-stream(_test-input-stream) -1376 # . . push args -1377 68/push _test-input-stream/imm32 -1378 # . . call -1379 e8/call clear-stream/disp32 -1380 # . . discard args -1381 81 0/subop/add %esp 4/imm32 -1382 # var slice/ecx : slice -1383 68/push 0/imm32/end -1384 68/push 0/imm32/start -1385 89/<- %ecx 4/r32/esp -1386 # write(_test-input-stream, " \"a b\" ") -1387 # . . push args -1388 68/push " \"a b\" "/imm32 -1389 68/push _test-input-stream/imm32 -1390 # . . call -1391 e8/call write/disp32 -1392 # . . discard args -1393 81 0/subop/add %esp 8/imm32 -1394 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1395 # . . push args -1396 51/push-ecx -1397 68/push _test-input-stream/imm32 -1398 # . . call -1399 e8/call next-word-string-or-expression-without-metadata/disp32 -1400 # . . discard args -1401 81 0/subop/add %esp 8/imm32 -1402 # check-ints-equal(slice->start - _test-input-stream->data, 1, msg) -1403 # . check-ints-equal(slice->start - _test-input-stream, 13, msg) -1404 # . . push args -1405 68/push "F - test-next-word-string-or-expression-without-metadata-returns-string-literal: start"/imm32 -1406 68/push 0xd/imm32 -1407 # . . push slice->start - _test-input-stream -1408 8b/-> *ecx 0/r32/eax -1409 81 5/subop/subtract %eax _test-input-stream/imm32 -1410 50/push-eax -1411 # . . call -1412 e8/call check-ints-equal/disp32 -1413 # . . discard args -1414 81 0/subop/add %esp 0xc/imm32 -1415 # check-ints-equal(slice->end - _test-input-stream->data, 6, msg) -1416 # . check-ints-equal(slice->end - _test-input-stream, 18, msg) -1417 # . . push args -1418 68/push "F - test-next-word-string-or-expression-without-metadata-returns-string-literal: end"/imm32 -1419 68/push 0x12/imm32 -1420 # . . push slice->end - _test-input-stream -1421 8b/-> *(ecx+4) 0/r32/eax -1422 81 5/subop/subtract %eax _test-input-stream/imm32 -1423 50/push-eax -1424 # . . call -1425 e8/call check-ints-equal/disp32 -1426 # . . discard args -1427 81 0/subop/add %esp 0xc/imm32 -1428 # . epilogue -1429 89/<- %esp 5/r32/ebp -1430 5d/pop-to-ebp -1431 c3/return -1432 -1433 test-next-word-string-or-expression-without-metadata-returns-string-with-escapes: -1434 # . prologue -1435 55/push-ebp -1436 89/<- %ebp 4/r32/esp -1437 # setup -1438 # . clear-stream(_test-input-stream) -1439 # . . push args -1440 68/push _test-input-stream/imm32 -1441 # . . call -1442 e8/call clear-stream/disp32 -1443 # . . discard args -1444 81 0/subop/add %esp 4/imm32 -1445 # var slice/ecx : slice -1446 68/push 0/imm32/end -1447 68/push 0/imm32/start -1448 89/<- %ecx 4/r32/esp -1449 # write(_test-input-stream, " \"a\\\"b\"") -1450 # . . push args -1451 68/push " \"a\\\"b\""/imm32 -1452 68/push _test-input-stream/imm32 -1453 # . . call -1454 e8/call write/disp32 -1455 # . . discard args -1456 81 0/subop/add %esp 8/imm32 -1457 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1458 # . . push args -1459 51/push-ecx -1460 68/push _test-input-stream/imm32 -1461 # . . call -1462 e8/call next-word-string-or-expression-without-metadata/disp32 -1463 # . . discard args -1464 81 0/subop/add %esp 8/imm32 -1465 # check-ints-equal(slice->start - _test-input-stream->data, 1, msg) -1466 # . check-ints-equal(slice->start - _test-input-stream, 13, msg) -1467 # . . push args -1468 68/push "F - test-next-word-string-or-expression-without-metadata-returns-string-with-escapes: start"/imm32 -1469 68/push 0xd/imm32 -1470 # . . push slice->start - _test-input-stream -1471 8b/-> *ecx 0/r32/eax -1472 81 5/subop/subtract %eax _test-input-stream/imm32 -1473 50/push-eax -1474 # . . call -1475 e8/call check-ints-equal/disp32 -1476 # . . discard args -1477 81 0/subop/add %esp 0xc/imm32 -1478 # check-ints-equal(slice->end - _test-input-stream->data, 7, msg) -1479 # . check-ints-equal(slice->end - _test-input-stream, 19, msg) -1480 # . . push args -1481 68/push "F - test-next-word-string-or-expression-without-metadata-returns-string-with-escapes: end"/imm32 -1482 68/push 0x13/imm32 -1483 # . . push slice->end - _test-input-stream -1484 8b/-> *(ecx+4) 0/r32/eax -1485 81 5/subop/subtract %eax _test-input-stream/imm32 -1486 50/push-eax -1487 # . . call -1488 e8/call check-ints-equal/disp32 -1489 # . . discard args -1490 81 0/subop/add %esp 0xc/imm32 -1491 # . epilogue -1492 89/<- %esp 5/r32/ebp -1493 5d/pop-to-ebp -1494 c3/return -1495 -1496 test-next-word-string-or-expression-without-metadata-returns-whole-expression: -1497 # . prologue -1498 55/push-ebp -1499 89/<- %ebp 4/r32/esp -1500 # setup -1501 # . clear-stream(_test-input-stream) -1502 # . . push args -1503 68/push _test-input-stream/imm32 -1504 # . . call -1505 e8/call clear-stream/disp32 -1506 # . . discard args -1507 81 0/subop/add %esp 4/imm32 -1508 # var slice/ecx : slice -1509 68/push 0/imm32/end -1510 68/push 0/imm32/start -1511 89/<- %ecx 4/r32/esp -1512 # write(_test-input-stream, " *(a b) ") -1513 # . . push args -1514 68/push " *(a b) "/imm32 -1515 68/push _test-input-stream/imm32 -1516 # . . call -1517 e8/call write/disp32 -1518 # . . discard args -1519 81 0/subop/add %esp 8/imm32 -1520 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1521 # . . push args -1522 51/push-ecx -1523 68/push _test-input-stream/imm32 -1524 # . . call -1525 e8/call next-word-string-or-expression-without-metadata/disp32 -1526 # . . discard args -1527 81 0/subop/add %esp 8/imm32 -1528 # check-ints-equal(slice->start - _test-input-stream->data, 1, msg) -1529 # . check-ints-equal(slice->start - _test-input-stream, 13, msg) -1530 # . . push args -1531 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-expression: start"/imm32 -1532 68/push 0xd/imm32 -1533 # . . push slice->start - _test-input-stream -1534 8b/-> *ecx 0/r32/eax -1535 81 5/subop/subtract %eax _test-input-stream/imm32 -1536 50/push-eax -1537 # . . call -1538 e8/call check-ints-equal/disp32 -1539 # . . discard args -1540 81 0/subop/add %esp 0xc/imm32 -1541 # check-ints-equal(slice->end - _test-input-stream->data, 7, msg) -1542 # . check-ints-equal(slice->end - _test-input-stream, 19, msg) -1543 # . . push args -1544 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-expression: end"/imm32 -1545 68/push 0x13/imm32 -1546 # . . push slice->end - _test-input-stream -1547 8b/-> *(ecx+4) 0/r32/eax -1548 81 5/subop/subtract %eax _test-input-stream/imm32 -1549 50/push-eax -1550 # . . call -1551 e8/call check-ints-equal/disp32 -1552 # . . discard args -1553 81 0/subop/add %esp 0xc/imm32 -1554 # . epilogue -1555 89/<- %esp 5/r32/ebp -1556 5d/pop-to-ebp -1557 c3/return -1558 -1559 test-next-word-string-or-expression-without-metadata-returns-eol-on-trailing-close-paren: -1560 # . prologue -1561 55/push-ebp -1562 89/<- %ebp 4/r32/esp -1563 # setup -1564 # . clear-stream(_test-input-stream) -1565 # . . push args -1566 68/push _test-input-stream/imm32 -1567 # . . call -1568 e8/call clear-stream/disp32 -1569 # . . discard args -1570 81 0/subop/add %esp 4/imm32 -1571 # var slice/ecx : slice -1572 68/push 0/imm32/end -1573 68/push 0/imm32/start -1574 89/<- %ecx 4/r32/esp -1575 # write(_test-input-stream, " ) ") -1576 # . . push args -1577 68/push " ) "/imm32 -1578 68/push _test-input-stream/imm32 -1579 # . . call -1580 e8/call write/disp32 -1581 # . . discard args -1582 81 0/subop/add %esp 8/imm32 -1583 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1584 # . . push args -1585 51/push-ecx -1586 68/push _test-input-stream/imm32 -1587 # . . call -1588 e8/call next-word-string-or-expression-without-metadata/disp32 -1589 # . . discard args -1590 81 0/subop/add %esp 8/imm32 -1591 # check-ints-equal(slice->start, 0, msg) -1592 # . . push args -1593 68/push "F - test-next-word-string-or-expression-without-metadata-returns-eol-on-trailing-close-paren: start"/imm32 -1594 68/push 0/imm32 -1595 ff 6/subop/push *ecx -1596 # . . call -1597 e8/call check-ints-equal/disp32 -1598 # . . discard args -1599 81 0/subop/add %esp 0xc/imm32 -1600 # check-ints-equal(slice->end, 0, msg) -1601 # . . push args -1602 68/push "F - test-next-word-string-or-expression-without-metadata-returns-eol-on-trailing-close-paren: end"/imm32 -1603 68/push 0/imm32 -1604 ff 6/subop/push *(ecx+4) -1605 # . . call -1606 e8/call check-ints-equal/disp32 -1607 # . . discard args -1608 81 0/subop/add %esp 0xc/imm32 -1609 # . epilogue -1610 89/<- %esp 5/r32/ebp -1611 5d/pop-to-ebp -1612 c3/return -1613 -1614 test-next-word-string-or-expression-without-metadata-handles-comment-after-trailing-close-paren: -1615 # . prologue -1616 55/push-ebp -1617 89/<- %ebp 4/r32/esp -1618 # setup -1619 # . clear-stream(_test-input-stream) -1620 # . . push args -1621 68/push _test-input-stream/imm32 -1622 # . . call -1623 e8/call clear-stream/disp32 -1624 # . . discard args -1625 81 0/subop/add %esp 4/imm32 -1626 # var slice/ecx : slice -1627 68/push 0/imm32/end -1628 68/push 0/imm32/start -1629 89/<- %ecx 4/r32/esp -1630 # write(_test-input-stream, " ) # abc ") -1631 # . . push args -1632 68/push " ) # abc "/imm32 -1633 68/push _test-input-stream/imm32 -1634 # . . call -1635 e8/call write/disp32 -1636 # . . discard args -1637 81 0/subop/add %esp 8/imm32 -1638 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1639 # . . push args -1640 51/push-ecx -1641 68/push _test-input-stream/imm32 -1642 # . . call -1643 e8/call next-word-string-or-expression-without-metadata/disp32 -1644 # . . discard args -1645 81 0/subop/add %esp 8/imm32 -1646 # check-ints-equal(slice->start, 0, msg) -1647 # . . push args -1648 68/push "F - test-next-word-string-or-expression-without-metadata-handles-comment-after-trailing-close-paren: start"/imm32 -1649 68/push 0/imm32 -1650 ff 6/subop/push *ecx -1651 # . . call -1652 e8/call check-ints-equal/disp32 -1653 # . . discard args -1654 81 0/subop/add %esp 0xc/imm32 -1655 # check-ints-equal(slice->end, 0, msg) -1656 # . . push args -1657 68/push "F - test-next-word-string-or-expression-without-metadata-handles-comment-after-trailing-close-paren: end"/imm32 -1658 68/push 0/imm32 -1659 ff 6/subop/push *(ecx+4) -1660 # . . call -1661 e8/call check-ints-equal/disp32 -1662 # . . discard args -1663 81 0/subop/add %esp 0xc/imm32 -1664 # . epilogue -1665 89/<- %esp 5/r32/ebp -1666 5d/pop-to-ebp -1667 c3/return -1668 -1669 test-next-word-string-or-expression-without-metadata-handles-newline-after-trailing-close-paren: -1670 # . prologue -1671 55/push-ebp -1672 89/<- %ebp 4/r32/esp -1673 # setup -1674 # . clear-stream(_test-input-stream) -1675 # . . push args -1676 68/push _test-input-stream/imm32 -1677 # . . call -1678 e8/call clear-stream/disp32 -1679 # . . discard args -1680 81 0/subop/add %esp 4/imm32 -1681 # var slice/ecx : slice -1682 68/push 0/imm32/end -1683 68/push 0/imm32/start -1684 89/<- %ecx 4/r32/esp -1685 # write(_test-input-stream, " )\n") -1686 # . . push args -1687 68/push " )\n"/imm32 -1688 68/push _test-input-stream/imm32 -1689 # . . call -1690 e8/call write/disp32 -1691 # . . discard args -1692 81 0/subop/add %esp 8/imm32 -1693 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1694 # . . push args -1695 51/push-ecx -1696 68/push _test-input-stream/imm32 -1697 # . . call -1698 e8/call next-word-string-or-expression-without-metadata/disp32 -1699 # . . discard args -1700 81 0/subop/add %esp 8/imm32 -1701 # check-ints-equal(slice->start, 0, msg) -1702 # . . push args -1703 68/push "F - test-next-word-string-or-expression-without-metadata-handles-newline-after-trailing-close-paren: start"/imm32 -1704 68/push 0/imm32 -1705 ff 6/subop/push *ecx -1706 # . . call -1707 e8/call check-ints-equal/disp32 -1708 # . . discard args -1709 81 0/subop/add %esp 0xc/imm32 -1710 # check-ints-equal(slice->end, 0, msg) -1711 # . . push args -1712 68/push "F - test-next-word-string-or-expression-without-metadata-handles-newline-after-trailing-close-paren: end"/imm32 -1713 68/push 0/imm32 -1714 ff 6/subop/push *(ecx+4) -1715 # . . call -1716 e8/call check-ints-equal/disp32 -1717 # . . discard args -1718 81 0/subop/add %esp 0xc/imm32 -1719 # . epilogue -1720 89/<- %esp 5/r32/ebp -1721 5d/pop-to-ebp -1722 c3/return -1723 -1724 test-next-word-string-or-expression-without-metadata-stops-at-close-paren: -1725 # . prologue -1726 55/push-ebp -1727 89/<- %ebp 4/r32/esp -1728 # setup -1729 # . clear-stream(_test-input-stream) -1730 # . . push args -1731 68/push _test-input-stream/imm32 -1732 # . . call -1733 e8/call clear-stream/disp32 -1734 # . . discard args -1735 81 0/subop/add %esp 4/imm32 -1736 # var slice/ecx : slice -1737 68/push 0/imm32/end -1738 68/push 0/imm32/start -1739 89/<- %ecx 4/r32/esp -1740 # write(_test-input-stream, " abc) # def") -1741 # . . push args -1742 68/push " abc) # def"/imm32 -1743 68/push _test-input-stream/imm32 -1744 # . . call -1745 e8/call write/disp32 -1746 # . . discard args -1747 81 0/subop/add %esp 8/imm32 -1748 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) -1749 # . . push args -1750 51/push-ecx -1751 68/push _test-input-stream/imm32 -1752 # . . call -1753 e8/call next-word-string-or-expression-without-metadata/disp32 -1754 # . . discard args -1755 81 0/subop/add %esp 8/imm32 -1756 # check-ints-equal(slice->start - _test-input-stream->data, 1, msg) -1757 # . check-ints-equal(slice->start - _test-input-stream, 13, msg) -1758 # . . push args -1759 68/push "F - test-next-word-string-or-expression-without-metadata-stops-at-close-paren: start"/imm32 -1760 68/push 0xd/imm32 -1761 # . . push slice->start - _test-input-stream -1762 8b/-> *ecx 0/r32/eax -1763 81 5/subop/subtract %eax _test-input-stream/imm32 -1764 50/push-eax -1765 # . . call -1766 e8/call check-ints-equal/disp32 -1767 # . . discard args -1768 81 0/subop/add %esp 0xc/imm32 -1769 # check-ints-equal(slice->end - _test-input-stream->data, 4, msg) -1770 # . check-ints-equal(slice->end - _test-input-stream, 16, msg) -1771 # . . push args -1772 68/push "F - test-next-word-string-or-expression-without-metadata-stops-at-close-paren: end"/imm32 -1773 68/push 0x10/imm32 -1774 # . . push slice->end - _test-input-stream -1775 8b/-> *(ecx+4) 0/r32/eax -1776 81 5/subop/subtract %eax _test-input-stream/imm32 -1777 50/push-eax -1778 # . . call -1779 e8/call check-ints-equal/disp32 -1780 # . . discard args -1781 81 0/subop/add %esp 0xc/imm32 -1782 # . epilogue -1783 89/<- %esp 5/r32/ebp -1784 5d/pop-to-ebp -1785 c3/return + 142 68/push 0x20/imm32/space + 143 56/push-esi + 144 # . . call + 145 e8/call skip-chars-matching/disp32 + 146 # . . discard args + 147 81 0/subop/add %esp 8/imm32 + 148 # if (line->data[line->read] == '(') goto convert-call + 149 # . ecx = line->read + 150 8b/-> *(esi+4) 1/r32/ecx + 151 # . eax = line->data[line->read] + 152 31/xor %eax 0/r32/eax + 153 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 154 # . if (eax == '(') goto convert-call + 155 3d/compare-eax-and 0x28/imm32/open-paren + 156 74/jump-if-= $subx-calls:convert-call/disp8 + 157 $subx-calls:pass-through: + 158 # write-stream-data(out, line) + 159 # . . push args + 160 56/push-esi + 161 ff 6/subop/push *(ebp+0xc) + 162 # . . call + 163 e8/call write-stream-data/disp32 + 164 # . . discard args + 165 81 0/subop/add %esp 8/imm32 + 166 # continue + 167 eb/jump $subx-calls:loop/disp8 + 168 $subx-calls:convert-call: + 169 # - emit comment + 170 # write-buffered(out, "# . ") + 171 # . . push args + 172 68/push "# . "/imm32 + 173 ff 6/subop/push *(ebp+0xc) + 174 # . . call + 175 e8/call write-buffered/disp32 + 176 # . . discard args + 177 81 0/subop/add %esp 8/imm32 + 178 # write-stream-data(out, line) + 179 # . . push args + 180 56/push-esi + 181 ff 6/subop/push *(ebp+0xc) + 182 # . . call + 183 e8/call write-stream-data/disp32 + 184 # . . discard args + 185 81 0/subop/add %esp 8/imm32 + 186 # - emit code + 187 # ++line->read to skip '(' + 188 ff 0/subop/increment *(esi+4) + 189 # clear-stream(words) + 190 # . . push args + 191 52/push-edx + 192 # . . call + 193 e8/call clear-stream/disp32 + 194 # . . discard args + 195 81 0/subop/add %esp 4/imm32 + 196 # words = parse-line(line) + 197 # . . push args + 198 52/push-edx + 199 56/push-esi + 200 # . . call + 201 e8/call parse-line/disp32 + 202 # . . discard args + 203 81 0/subop/add %esp 8/imm32 + 204 # emit-call(out, words) + 205 # . . push args + 206 52/push-edx + 207 ff 6/subop/push *(ebp+0xc) + 208 # . . call + 209 e8/call emit-call/disp32 + 210 # . . discard args + 211 81 0/subop/add %esp 8/imm32 + 212 # loop + 213 e9/jump $subx-calls:loop/disp32 + 214 $subx-calls:break: + 215 # flush(out) + 216 # . . push args + 217 ff 6/subop/push *(ebp+0xc) + 218 # . . call + 219 e8/call flush/disp32 + 220 # . . discard args + 221 81 0/subop/add %esp 4/imm32 + 222 $subx-calls:end: + 223 # . reclaim locals + 224 81 0/subop/add %esp 0x298/imm32 # 0x20c + 0x8c + 225 # . restore registers + 226 5e/pop-to-esi + 227 5a/pop-to-edx + 228 59/pop-to-ecx + 229 58/pop-to-eax + 230 # . epilogue + 231 89/<- %esp 5/r32/ebp + 232 5d/pop-to-ebp + 233 c3/return + 234 + 235 parse-line: # line : (addr stream byte), words : (addr stream slice) + 236 # pseudocode: + 237 # var word-slice : slice + 238 # while true + 239 # word-slice = next-word-string-or-expression-without-metadata(line) + 240 # if slice-empty?(word-slice) + 241 # break # end of line + 242 # write-int(words, word-slice->start) + 243 # write-int(words, word-slice->end) + 244 # + 245 # . prologue + 246 55/push-ebp + 247 89/<- %ebp 4/r32/esp + 248 # . save registers + 249 51/push-ecx + 250 # var word-slice/ecx : slice + 251 68/push 0/imm32/end + 252 68/push 0/imm32/start + 253 89/<- %ecx 4/r32/esp + 254 $parse-line:loop: + 255 # word-slice = next-word-string-or-expression-without-metadata(line) + 256 # . . push args + 257 51/push-ecx + 258 ff 6/subop/push *(ebp+8) + 259 # . . call + 260 e8/call next-word-string-or-expression-without-metadata/disp32 + 261 # . . discard args + 262 81 0/subop/add %esp 8/imm32 + 263 $parse-line:check1: + 264 # if (slice-empty?(word-slice)) break + 265 # . eax = slice-empty?(word-slice) + 266 # . . push args + 267 51/push-ecx + 268 # . . call + 269 e8/call slice-empty?/disp32 + 270 # . . discard args + 271 81 0/subop/add %esp 4/imm32 + 272 # . if (eax != false) break + 273 3d/compare-eax-and 0/imm32/false + 274 0f 85/jump-if-!= $parse-line:end/disp32 + 275 +-- 40 lines: #? # dump word-slice ----------------------------------------------------------------------------------------------------------------------- + 315 $parse-line:write-word: + 316 # write-int(words, word-slice->start) + 317 # . . push args + 318 ff 6/subop/push *ecx + 319 ff 6/subop/push *(ebp+0xc) + 320 # . . call + 321 e8/call write-int/disp32 + 322 # . . discard args + 323 81 0/subop/add %esp 8/imm32 + 324 # write-int(words, word-slice->end) + 325 # . . push args + 326 ff 6/subop/push *(ecx+4) + 327 ff 6/subop/push *(ebp+0xc) + 328 # . . call + 329 e8/call write-int/disp32 + 330 # . . discard args + 331 81 0/subop/add %esp 8/imm32 + 332 # loop + 333 e9/jump $parse-line:loop/disp32 + 334 $parse-line:end: + 335 # . reclaim locals + 336 81 0/subop/add %esp 8/imm32 + 337 # . restore registers + 338 59/pop-to-ecx + 339 # . epilogue + 340 89/<- %esp 5/r32/ebp + 341 5d/pop-to-ebp + 342 c3/return + 343 + 344 emit-call: # out : (addr buffered-file), words : (addr stream slice) + 345 # pseudocode: + 346 # if (words->write < 8) abort + 347 # curr = &words->data[words->write-8] + 348 # min = words->data + 349 # # emit pushes + 350 # while true + 351 # if (curr <= min) break + 352 # if *curr->start in '%' '*' + 353 # write-buffered(out, "ff 6/subop/push ") + 354 # write-slice-buffered(out, curr) + 355 # write-buffered(out, "\n") + 356 # else + 357 # write-buffered(out, "68/push ") + 358 # write-slice-buffered(out, curr) + 359 # write-buffered(out, "/imm32\n") + 360 # curr -= 8 + 361 # # emit call + 362 # write-buffered(out, "e8/call ") + 363 # write-slice-buffered(out, curr) + 364 # write-buffered(out, "/disp32\n") + 365 # # emit pops + 366 # write-buffered(out, "81 0/subop/add %esp ") + 367 # print-int32-buffered(out, words->write >> 1 - 4) + 368 # write-buffered(out, "/imm32\n") + 369 # + 370 # . prologue + 371 55/push-ebp + 372 89/<- %ebp 4/r32/esp + 373 # . save registers + 374 50/push-eax + 375 51/push-ecx + 376 52/push-edx + 377 56/push-esi + 378 # esi = words + 379 8b/-> *(ebp+0xc) 6/r32/esi + 380 # if (words->write < 8) abort + 381 # . ecx = words->write - 8 + 382 8b/-> *esi 1/r32/ecx + 383 81 5/subop/subtract %ecx 8/imm32 + 384 0f 8c/jump-if-< $emit-call:error1/disp32 + 385 # var curr/ecx : (addr slice) = &words->data[words->write-8] + 386 8d/copy-address *(esi+ecx+0xc) 1/r32/ecx + 387 # var min/edx : (addr byte) = words->data + 388 8d/copy-address *(esi+0xc) 2/r32/edx + 389 # - emit pushes + 390 $emit-call:push-loop: + 391 # if (curr <= min) break + 392 39/compare %ecx 2/r32/edx + 393 0f 8e/jump-if-<= $emit-call:call-instruction/disp32 + 394 # if (*curr->start in '%' '*') goto push-rm32 + 395 # . var start/eax : (addr byte) = curr->start + 396 8b/-> *ecx 0/r32/eax + 397 # . var c/eax : byte = *eax + 398 8b/-> *eax 0/r32/eax + 399 81 4/subop/and %eax 0xff/imm32 + 400 # . if (c == '%') goto push-rm32 + 401 3d/compare-eax-and 0x25/imm32/percent + 402 74/jump-if-= $emit-call:push-rm32/disp8 + 403 # . if (c == '*') goto push-rm32 + 404 3d/compare-eax-and 0x2a/imm32/asterisk + 405 74/jump-if-= $emit-call:push-rm32/disp8 + 406 $emit-call:push-imm32: + 407 # write-buffered(out, "68/push ") + 408 68/push "68/push "/imm32 + 409 ff 6/subop/push *(ebp+8) + 410 # . . call + 411 e8/call write-buffered/disp32 + 412 # . . discard args + 413 81 0/subop/add %esp 8/imm32 + 414 # write-slice-buffered(out, curr) + 415 # . . push args + 416 51/push-ecx + 417 ff 6/subop/push *(ebp+8) + 418 # . . call + 419 e8/call write-slice-buffered/disp32 + 420 # . . discard args + 421 81 0/subop/add %esp 8/imm32 + 422 # write-buffered(out, "/imm32\n") + 423 68/push "/imm32\n"/imm32 + 424 ff 6/subop/push *(ebp+8) + 425 # . . call + 426 e8/call write-buffered/disp32 + 427 # . . discard args + 428 81 0/subop/add %esp 8/imm32 + 429 # continue + 430 eb/jump $emit-call:next-push/disp8 + 431 $emit-call:push-rm32: + 432 # write-buffered(out, "ff 6/subop/push ") + 433 # . . push args + 434 68/push "ff 6/subop/push "/imm32 + 435 ff 6/subop/push *(ebp+8) + 436 # . . call + 437 e8/call write-buffered/disp32 + 438 # . . discard args + 439 81 0/subop/add %esp 8/imm32 + 440 # write-slice-buffered(out, curr) + 441 # . . push args + 442 51/push-ecx + 443 ff 6/subop/push *(ebp+8) + 444 # . . call + 445 e8/call write-slice-buffered/disp32 + 446 # . . discard args + 447 81 0/subop/add %esp 8/imm32 + 448 # write-buffered(out, "\n") + 449 68/push Newline/imm32 + 450 ff 6/subop/push *(ebp+8) + 451 # . . call + 452 e8/call write-buffered/disp32 + 453 # . . discard args + 454 81 0/subop/add %esp 8/imm32 + 455 $emit-call:next-push: + 456 # curr -= 8 + 457 81 5/subop/subtract %ecx 8/imm32 + 458 # loop + 459 e9/jump $emit-call:push-loop/disp32 + 460 $emit-call:call-instruction: + 461 # write-buffered(out, "e8/call ") + 462 68/push "e8/call "/imm32 + 463 ff 6/subop/push *(ebp+8) + 464 # . . call + 465 e8/call write-buffered/disp32 + 466 # . . discard args + 467 81 0/subop/add %esp 8/imm32 + 468 # write-slice-buffered(out, curr) + 469 # . . push args + 470 51/push-ecx + 471 ff 6/subop/push *(ebp+8) + 472 # . . call + 473 e8/call write-slice-buffered/disp32 + 474 # . . discard args + 475 81 0/subop/add %esp 8/imm32 + 476 # write-buffered(out, "/disp32\n") + 477 68/push "/disp32\n"/imm32 + 478 ff 6/subop/push *(ebp+8) + 479 # . . call + 480 e8/call write-buffered/disp32 + 481 # . . discard args + 482 81 0/subop/add %esp 8/imm32 + 483 $emit-call:pop-instruction: + 484 # write-buffered(out, "81 0/subop/add %esp ") + 485 68/push "81 0/subop/add %esp "/imm32 + 486 ff 6/subop/push *(ebp+8) + 487 # . . call + 488 e8/call write-buffered/disp32 + 489 # . . discard args + 490 81 0/subop/add %esp 8/imm32 + 491 # print-int32-buffered(out, words->write >> 1 - 4) + 492 # . . push args + 493 8b/-> *esi 0/r32/eax + 494 c1/shift 7/subop/arith-right %eax 1/imm8 + 495 2d/subtract-from-eax 4/imm32 + 496 50/push-eax + 497 ff 6/subop/push *(ebp+8) + 498 # . . call + 499 e8/call print-int32-buffered/disp32 + 500 # . . discard args + 501 81 0/subop/add %esp 8/imm32 + 502 # write-buffered(out, "/imm32\n") + 503 68/push "/imm32\n"/imm32 + 504 ff 6/subop/push *(ebp+8) + 505 # . . call + 506 e8/call write-buffered/disp32 + 507 # . . discard args + 508 81 0/subop/add %esp 8/imm32 + 509 $emit-call:end: + 510 # . restore registers + 511 5e/pop-to-esi + 512 5a/pop-to-edx + 513 59/pop-to-ecx + 514 58/pop-to-eax + 515 # . epilogue + 516 89/<- %esp 5/r32/ebp + 517 5d/pop-to-ebp + 518 c3/return + 519 + 520 $emit-call:error1: + 521 # print(stderr, "error: calls.subx: '()' is not a valid call") + 522 # . write-buffered(Stderr, "error: calls.subx: '()' is not a valid call") + 523 # . . push args + 524 68/push "error: calls.subx: '()' is not a valid call"/imm32 + 525 68/push Stderr/imm32 + 526 # . . call + 527 e8/call write-buffered/disp32 + 528 # . . discard args + 529 81 0/subop/add %esp 8/imm32 + 530 # . flush(Stderr) + 531 # . . push args + 532 68/push Stderr/imm32 + 533 # . . call + 534 e8/call flush/disp32 + 535 # . . discard args + 536 81 0/subop/add %esp 4/imm32 + 537 # . syscall(exit, 1) + 538 bb/copy-to-ebx 1/imm32 + 539 b8/copy-to-eax 1/imm32/exit + 540 cd/syscall 0x80/imm8 + 541 # never gets here + 542 + 543 test-subx-calls-passes-most-lines-through: + 544 # . prologue + 545 55/push-ebp + 546 89/<- %ebp 4/r32/esp + 547 # setup + 548 # . clear-stream(_test-input-stream) + 549 # . . push args + 550 68/push _test-input-stream/imm32 + 551 # . . call + 552 e8/call clear-stream/disp32 + 553 # . . discard args + 554 81 0/subop/add %esp 4/imm32 + 555 # . clear-stream($_test-input-buffered-file->buffer) + 556 # . . push args + 557 68/push $_test-input-buffered-file->buffer/imm32 + 558 # . . call + 559 e8/call clear-stream/disp32 + 560 # . . discard args + 561 81 0/subop/add %esp 4/imm32 + 562 # . clear-stream(_test-output-stream) + 563 # . . push args + 564 68/push _test-output-stream/imm32 + 565 # . . call + 566 e8/call clear-stream/disp32 + 567 # . . discard args + 568 81 0/subop/add %esp 4/imm32 + 569 # . clear-stream($_test-output-buffered-file->buffer) + 570 # . . push args + 571 68/push $_test-output-buffered-file->buffer/imm32 + 572 # . . call + 573 e8/call clear-stream/disp32 + 574 # . . discard args + 575 81 0/subop/add %esp 4/imm32 + 576 # . write(_test-input-stream, "== abcd 0x1\n") + 577 # . . push args + 578 68/push "== abcd 0x1\n"/imm32 + 579 68/push _test-input-stream/imm32 + 580 # . . call + 581 e8/call write/disp32 + 582 # . . discard args + 583 81 0/subop/add %esp 8/imm32 + 584 # subx-calls(_test-input-buffered-file, _test-output-buffered-file) + 585 # . . push args + 586 68/push _test-output-buffered-file/imm32 + 587 68/push _test-input-buffered-file/imm32 + 588 # . . call + 589 e8/call subx-calls/disp32 + 590 # . . discard args + 591 81 0/subop/add %esp 8/imm32 + 592 # check that the line just passed through + 593 # . flush(_test-output-buffered-file) + 594 # . . push args + 595 68/push _test-output-buffered-file/imm32 + 596 # . . call + 597 e8/call flush/disp32 + 598 # . . discard args + 599 81 0/subop/add %esp 4/imm32 + 600 # . check-stream-equal(_test-output-stream, "== abcd 0x1\n", msg) + 601 # . . push args + 602 68/push "F - test-subx-calls-passes-most-lines-through"/imm32 + 603 68/push "== abcd 0x1\n"/imm32 + 604 68/push _test-output-stream/imm32 + 605 # . . call + 606 e8/call check-stream-equal/disp32 + 607 # . . discard args + 608 81 0/subop/add %esp 0xc/imm32 + 609 # . epilogue + 610 89/<- %esp 5/r32/ebp + 611 5d/pop-to-ebp + 612 c3/return + 613 + 614 test-subx-calls-processes-calls: + 615 # . prologue + 616 55/push-ebp + 617 89/<- %ebp 4/r32/esp + 618 # setup + 619 # . clear-stream(_test-input-stream) + 620 # . . push args + 621 68/push _test-input-stream/imm32 + 622 # . . call + 623 e8/call clear-stream/disp32 + 624 # . . discard args + 625 81 0/subop/add %esp 4/imm32 + 626 # . clear-stream($_test-input-buffered-file->buffer) + 627 # . . push args + 628 68/push $_test-input-buffered-file->buffer/imm32 + 629 # . . call + 630 e8/call clear-stream/disp32 + 631 # . . discard args + 632 81 0/subop/add %esp 4/imm32 + 633 # . clear-stream(_test-output-stream) + 634 # . . push args + 635 68/push _test-output-stream/imm32 + 636 # . . call + 637 e8/call clear-stream/disp32 + 638 # . . discard args + 639 81 0/subop/add %esp 4/imm32 + 640 # . clear-stream($_test-output-buffered-file->buffer) + 641 # . . push args + 642 68/push $_test-output-buffered-file->buffer/imm32 + 643 # . . call + 644 e8/call clear-stream/disp32 + 645 # . . discard args + 646 81 0/subop/add %esp 4/imm32 + 647 # . write(_test-input-stream, "(foo %eax)\n") + 648 # . . push args + 649 68/push "(foo %eax)\n"/imm32 + 650 68/push _test-input-stream/imm32 + 651 # . . call + 652 e8/call write/disp32 + 653 # . . discard args + 654 81 0/subop/add %esp 8/imm32 + 655 # subx-calls(_test-input-buffered-file, _test-output-buffered-file) + 656 # . . push args + 657 68/push _test-output-buffered-file/imm32 + 658 68/push _test-input-buffered-file/imm32 + 659 # . . call + 660 e8/call subx-calls/disp32 + 661 # . . discard args + 662 81 0/subop/add %esp 8/imm32 + 663 # check that the line just passed through + 664 # . flush(_test-output-buffered-file) + 665 # . . push args + 666 68/push _test-output-buffered-file/imm32 + 667 # . . call + 668 e8/call flush/disp32 + 669 # . . discard args + 670 81 0/subop/add %esp 4/imm32 + 671 +-- 33 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- + 704 # . check-next-stream-line-equal(_test-output-stream, "# . (foo %eax)", msg) + 705 # . . push args + 706 68/push "F - test-subx-calls-processes-calls: comment"/imm32 + 707 68/push "# . (foo %eax)"/imm32 + 708 68/push _test-output-stream/imm32 + 709 # . . call + 710 e8/call check-next-stream-line-equal/disp32 + 711 # . . discard args + 712 81 0/subop/add %esp 0xc/imm32 + 713 # . check-next-stream-line-equal(_test-output-stream, "ff 6/subop/push %eax", msg) + 714 # . . push args + 715 68/push "F - test-subx-calls-processes-calls: arg 0"/imm32 + 716 68/push "ff 6/subop/push %eax"/imm32 + 717 68/push _test-output-stream/imm32 + 718 # . . call + 719 e8/call check-next-stream-line-equal/disp32 + 720 # . . discard args + 721 81 0/subop/add %esp 0xc/imm32 + 722 # . check-next-stream-line-equal(_test-output-stream, "e8/call foo/disp32", msg) + 723 # . . push args + 724 68/push "F - test-subx-calls-processes-calls: call"/imm32 + 725 68/push "e8/call foo/disp32"/imm32 + 726 68/push _test-output-stream/imm32 + 727 # . . call + 728 e8/call check-next-stream-line-equal/disp32 + 729 # . . discard args + 730 81 0/subop/add %esp 0xc/imm32 + 731 # . check-next-stream-line-equal(_test-output-stream, "81 0/subop/add %esp 4/imm32", msg) + 732 # . . push args + 733 68/push "F - test-subx-calls-processes-calls: pops"/imm32 + 734 68/push "81 0/subop/add %esp 0x00000004/imm32"/imm32 + 735 68/push _test-output-stream/imm32 + 736 # . . call + 737 e8/call check-next-stream-line-equal/disp32 + 738 # . . discard args + 739 81 0/subop/add %esp 0xc/imm32 + 740 # . epilogue + 741 89/<- %esp 5/r32/ebp + 742 5d/pop-to-ebp + 743 c3/return + 744 + 745 next-word-string-or-expression-without-metadata: # line : (addr stream byte), out : (addr slice) + 746 # pseudocode: + 747 # skip-chars-matching(line, ' ') + 748 # if line->read >= line->write # end of line + 749 # out = {0, 0} + 750 # return + 751 # out->start = &line->data[line->read] + 752 # if line->data[line->read] == '#' # comment + 753 # out->end = &line->data[line->write] # skip to end of line + 754 # return + 755 # if line->data[line->read] == '"' # string literal + 756 # skip-string(line) + 757 # out->end = &line->data[line->read] # no metadata + 758 # return + 759 # if line->data[line->read] == '*' # expression + 760 # if line->data[line->read + 1] == ' ' + 761 # abort + 762 # if line->data[line->read + 1] == '(' + 763 # skip-until-close-paren(line) + 764 # if (line->data[line->read] != ')' + 765 # abort + 766 # ++line->read to skip ')' + 767 # out->end = &line->data[line->read] + 768 # return + 769 # if line->data[line->read] == ')' + 770 # ++line->read to skip ')' + 771 # # make sure there's nothing else of importance + 772 # if line->read >= line->write + 773 # out = {0, 0} + 774 # return + 775 # if line->data[line->read] != ' ' + 776 # abort + 777 # skip-chars-matching-whitespace(line) + 778 # if line->read >= line->write + 779 # out = {0, 0} + 780 # return + 781 # if line->data[line->read] == '#' # only thing permitted after ')' is a comment + 782 # out = {0, 0} + 783 # return + 784 # abort + 785 # # default case: read a word -- but no metadata + 786 # while true + 787 # if line->read >= line->write + 788 # break + 789 # if line->data[line->read] == ' ' + 790 # break + 791 # if line->data[line->read] == ')' + 792 # break + 793 # if line->data[line->read] == '/' + 794 # abort + 795 # ++line->read + 796 # out->end = &line->data[line->read] + 797 # + 798 # registers: + 799 # ecx: often line->read + 800 # eax: often line->data[line->read] + 801 # + 802 # . prologue + 803 55/push-ebp + 804 89/<- %ebp 4/r32/esp + 805 # . save registers + 806 50/push-eax + 807 51/push-ecx + 808 56/push-esi + 809 57/push-edi + 810 # esi = line + 811 8b/-> *(ebp+8) 6/r32/esi + 812 # edi = out + 813 8b/-> *(ebp+0xc) 7/r32/edi + 814 # skip-chars-matching(line, ' ') + 815 # . . push args + 816 68/push 0x20/imm32/space + 817 ff 6/subop/push *(ebp+8) + 818 # . . call + 819 e8/call skip-chars-matching/disp32 + 820 # . . discard args + 821 81 0/subop/add %esp 8/imm32 + 822 $next-word-string-or-expression-without-metadata:check0: + 823 # if (line->read >= line->write) return out = {0, 0} + 824 # . ecx = line->read + 825 8b/-> *(esi+4) 1/r32/ecx + 826 # . if (ecx >= line->write) return out = {0, 0} + 827 3b/compare 1/r32/ecx *esi + 828 0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:return-eol/disp32 + 829 $next-word-string-or-expression-without-metadata:check-for-comment: + 830 # out->start = &line->data[line->read] + 831 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 832 89/<- *edi 0/r32/eax + 833 # if (line->data[line->read] != '#') goto next check + 834 # . var eax : byte = line->data[line->read] + 835 31/xor %eax 0/r32/eax + 836 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 837 # . if (eax != '#') goto next check + 838 3d/compare-eax-and 0x23/imm32/pound + 839 75/jump-if-!= $next-word-string-or-expression-without-metadata:check-for-string-literal/disp8 + 840 $next-word-string-or-expression-without-metadata:comment: + 841 # out->end = &line->data[line->write] + 842 8b/-> *esi 0/r32/eax + 843 8d/copy-address *(esi+eax+0xc) 0/r32/eax + 844 89/<- *(edi+4) 0/r32/eax + 845 # line->read = line->write # skip rest of line + 846 8b/-> *esi 0/r32/eax + 847 89/<- *(esi+4) 0/r32/eax + 848 # return + 849 e9/jump $next-word-string-or-expression-without-metadata:end/disp32 + 850 $next-word-string-or-expression-without-metadata:check-for-string-literal: + 851 # if (line->data[line->read] != '"') goto next check + 852 3d/compare-eax-and 0x22/imm32/dquote + 853 75/jump-if-!= $next-word-string-or-expression-without-metadata:check-for-expression/disp8 + 854 $next-word-string-or-expression-without-metadata:string-literal: + 855 # skip-string(line) + 856 # . . push args + 857 56/push-esi + 858 # . . call + 859 e8/call skip-string/disp32 + 860 # . . discard args + 861 81 0/subop/add %esp 4/imm32 + 862 # out->end = &line->data[line->read] + 863 8b/-> *(esi+4) 1/r32/ecx + 864 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 865 89/<- *(edi+4) 0/r32/eax + 866 # return + 867 e9/jump $next-word-string-or-expression-without-metadata:end/disp32 + 868 $next-word-string-or-expression-without-metadata:check-for-expression: + 869 # if (line->data[line->read] != '*') goto next check + 870 3d/compare-eax-and 0x2a/imm32/asterisk + 871 75/jump-if-!= $next-word-string-or-expression-without-metadata:check-for-end-of-call/disp8 + 872 # if (line->data[line->read + 1] == ' ') goto error1 + 873 8a/copy-byte *(esi+ecx+0xd) 0/r32/AL + 874 3d/compare-eax-and 0x20/imm32/space + 875 0f 84/jump-if-= $next-word-string-or-expression-without-metadata:error1/disp32 + 876 # if (line->data[line->read + 1] != '(') goto regular-word + 877 3d/compare-eax-and 0x28/imm32/open-paren + 878 0f 85/jump-if-!= $next-word-string-or-expression-without-metadata:regular-word-without-metadata/disp32 + 879 $next-word-string-or-expression-without-metadata:paren: + 880 # skip-until-close-paren(line) + 881 # . . push args + 882 56/push-esi + 883 # . . call + 884 e8/call skip-until-close-paren/disp32 + 885 # . . discard args + 886 81 0/subop/add %esp 4/imm32 + 887 # if (line->data[line->read] != ')') goto error2 + 888 # . eax = line->data[line->read] + 889 8b/-> *(esi+4) 1/r32/ecx + 890 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 891 # . if (eax != ')') goto error2 + 892 3d/compare-eax-and 0x29/imm32/close-paren + 893 0f 85/jump-if-!= $next-word-string-or-expression-without-metadata:error2/disp32 + 894 # ++line->read to skip ')' + 895 ff 0/subop/increment *(esi+4) + 896 # out->end = &line->data[line->read] + 897 8b/-> *(esi+4) 1/r32/ecx + 898 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 899 89/<- *(edi+4) 0/r32/eax + 900 # return + 901 e9/jump $next-word-string-or-expression-without-metadata:end/disp32 + 902 $next-word-string-or-expression-without-metadata:check-for-end-of-call: + 903 # if (line->data[line->read] != ')') goto next check + 904 3d/compare-eax-and 0x29/imm32/close-paren + 905 75/jump-if-!= $next-word-string-or-expression-without-metadata:regular-word-without-metadata/disp8 + 906 # ++line->read to skip ')' + 907 ff 0/subop/increment *(esi+4) + 908 # - error checking: make sure there's nothing else of importance on the line + 909 # if (line->read >= line->write) return out = {0, 0} + 910 # . ecx = line->read + 911 8b/-> *(esi+4) 1/r32/ecx + 912 # . if (ecx >= line->write) return {0, 0} + 913 3b/compare 1/r32/ecx *esi + 914 0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:return-eol/disp32 + 915 # if (line->data[line->read] == '/') goto error3 + 916 # . eax = line->data[line->read] + 917 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 918 # . if (eax == '/') goto error3 + 919 3d/compare-eax-and 0x2f/imm32/slash + 920 0f 84/jump-if-= $next-word-string-or-expression-without-metadata:error3/disp32 + 921 # skip-chars-matching-whitespace(line) + 922 # . . push args + 923 56/push-esi + 924 # . . call + 925 e8/call skip-chars-matching-whitespace/disp32 + 926 # . . discard args + 927 81 0/subop/add %esp 4/imm32 + 928 # if (line->read >= line->write) return out = {0, 0} + 929 # . ecx = line->read + 930 8b/-> *(esi+4) 1/r32/ecx + 931 # . if (ecx >= line->write) return {0, 0} + 932 3b/compare 1/r32/ecx *esi + 933 0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:return-eol/disp32 + 934 # if (line->data[line->read] == '#') return out = {0, 0} + 935 # . eax = line->data[line->read] + 936 8b/-> *(esi+4) 1/r32/ecx + 937 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 938 # . if (eax == '#') return out = {0, 0} + 939 3d/compare-eax-and 0x23/imm32/pound + 940 74/jump-if-= $next-word-string-or-expression-without-metadata:return-eol/disp8 + 941 # otherwise goto error4 + 942 e9/jump $next-word-string-or-expression-without-metadata:error4/disp32 + 943 $next-word-string-or-expression-without-metadata:regular-word-without-metadata: + 944 # if (line->read >= line->write) break + 945 # . ecx = line->read + 946 8b/-> *(esi+4) 1/r32/ecx + 947 # . if (ecx >= line->write) break + 948 3b/compare *esi 1/r32/ecx + 949 7d/jump-if->= $next-word-string-or-expression-without-metadata:regular-word-break/disp8 + 950 # if (line->data[line->read] == ' ') break + 951 # . eax = line->data[line->read] + 952 8b/-> *(esi+4) 1/r32/ecx + 953 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 954 # . if (eax == ' ') break + 955 3d/compare-eax-and 0x20/imm32/space + 956 74/jump-if-= $next-word-string-or-expression-without-metadata:regular-word-break/disp8 + 957 # if (line->data[line->read] == ')') break + 958 3d/compare-eax-and 0x29/imm32/close-paren + 959 0f 84/jump-if-= $next-word-string-or-expression-without-metadata:regular-word-break/disp32 + 960 # if (line->data[line->read] == '/') goto error5 + 961 3d/compare-eax-and 0x2f/imm32/slash + 962 0f 84/jump-if-= $next-word-string-or-expression-without-metadata:error5/disp32 + 963 # ++line->read + 964 ff 0/subop/increment *(esi+4) + 965 # loop + 966 e9/jump $next-word-string-or-expression-without-metadata:regular-word-without-metadata/disp32 + 967 $next-word-string-or-expression-without-metadata:regular-word-break: + 968 # out->end = &line->data[line->read] + 969 8b/-> *(esi+4) 1/r32/ecx + 970 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 971 89/<- *(edi+4) 0/r32/eax + 972 eb/jump $next-word-string-or-expression-without-metadata:end/disp8 + 973 $next-word-string-or-expression-without-metadata:return-eol: + 974 # return out = {0, 0} + 975 c7 0/subop/copy *edi 0/imm32 + 976 c7 0/subop/copy *(edi+4) 0/imm32 + 977 $next-word-string-or-expression-without-metadata:end: + 978 # . restore registers + 979 5f/pop-to-edi + 980 5e/pop-to-esi + 981 59/pop-to-ecx + 982 58/pop-to-eax + 983 # . epilogue + 984 89/<- %esp 5/r32/ebp + 985 5d/pop-to-ebp + 986 c3/return + 987 + 988 $next-word-string-or-expression-without-metadata:error1: + 989 # print(stderr, "error: no space allowed after '*' in '" line "'") + 990 # . write-buffered(Stderr, "error: no space allowed after '*' in '") + 991 # . . push args + 992 68/push "error: no space allowed after '*' in '"/imm32 + 993 68/push Stderr/imm32 + 994 # . . call + 995 e8/call write-buffered/disp32 + 996 # . . discard args + 997 81 0/subop/add %esp 8/imm32 + 998 # . write-stream-data(Stderr, line) + 999 # . . push args +1000 56/push-esi +1001 68/push Stderr/imm32 +1002 # . . call +1003 e8/call write-stream-data/disp32 +1004 # . . discard args +1005 81 0/subop/add %esp 8/imm32 +1006 # . write-buffered(Stderr, "'") +1007 # . . push args +1008 68/push "'"/imm32 +1009 68/push Stderr/imm32 +1010 # . . call +1011 e8/call write-buffered/disp32 +1012 # . . discard args +1013 81 0/subop/add %esp 8/imm32 +1014 # . flush(Stderr) +1015 # . . push args +1016 68/push Stderr/imm32 +1017 # . . call +1018 e8/call flush/disp32 +1019 # . . discard args +1020 81 0/subop/add %esp 4/imm32 +1021 # . syscall(exit, 1) +1022 bb/copy-to-ebx 1/imm32 +1023 b8/copy-to-eax 1/imm32/exit +1024 cd/syscall 0x80/imm8 +1025 # never gets here +1026 +1027 $next-word-string-or-expression-without-metadata:error2: +1028 # print(stderr, "error: *(...) expression must be all on a single line in '" line "'") +1029 # . write-buffered(Stderr, "error: *(...) expression must be all on a single line in '") +1030 # . . push args +1031 68/push "error: *(...) expression must be all on a single line in '"/imm32 +1032 68/push Stderr/imm32 +1033 # . . call +1034 e8/call write-buffered/disp32 +1035 # . . discard args +1036 81 0/subop/add %esp 8/imm32 +1037 # . write-stream-data(Stderr, line) +1038 # . . push args +1039 56/push-esi +1040 68/push Stderr/imm32 +1041 # . . call +1042 e8/call write-stream-data/disp32 +1043 # . . discard args +1044 81 0/subop/add %esp 8/imm32 +1045 # . write-buffered(Stderr, "'") +1046 # . . push args +1047 68/push "'"/imm32 +1048 68/push Stderr/imm32 +1049 # . . call +1050 e8/call write-buffered/disp32 +1051 # . . discard args +1052 81 0/subop/add %esp 8/imm32 +1053 # . flush(Stderr) +1054 # . . push args +1055 68/push Stderr/imm32 +1056 # . . call +1057 e8/call flush/disp32 +1058 # . . discard args +1059 81 0/subop/add %esp 4/imm32 +1060 # . syscall(exit, 1) +1061 bb/copy-to-ebx 1/imm32 +1062 b8/copy-to-eax 1/imm32/exit +1063 cd/syscall 0x80/imm8 +1064 # never gets here +1065 +1066 $next-word-string-or-expression-without-metadata:error3: +1067 # print(stderr, "error: no metadata after calls; just use a comment (in '" line "')") +1068 # . write-buffered(Stderr, "error: no metadata after calls; just use a comment (in '") +1069 # . . push args +1070 68/push "error: no metadata after calls; just use a comment (in '"/imm32 +1071 68/push Stderr/imm32 +1072 # . . call +1073 e8/call write-buffered/disp32 +1074 # . . discard args +1075 81 0/subop/add %esp 8/imm32 +1076 # . write-stream-data(Stderr, line) +1077 # . . push args +1078 56/push-esi +1079 68/push Stderr/imm32 +1080 # . . call +1081 e8/call write-stream-data/disp32 +1082 # . . discard args +1083 81 0/subop/add %esp 8/imm32 +1084 # . write-buffered(Stderr, "')") +1085 # . . push args +1086 68/push "')"/imm32 +1087 68/push Stderr/imm32 +1088 # . . call +1089 e8/call write-buffered/disp32 +1090 # . . discard args +1091 81 0/subop/add %esp 8/imm32 +1092 # . flush(Stderr) +1093 # . . push args +1094 68/push Stderr/imm32 +1095 # . . call +1096 e8/call flush/disp32 +1097 # . . discard args +1098 81 0/subop/add %esp 4/imm32 +1099 # . syscall(exit, 1) +1100 bb/copy-to-ebx 1/imm32 +1101 b8/copy-to-eax 1/imm32/exit +1102 cd/syscall 0x80/imm8 +1103 # never gets here +1104 +1105 $next-word-string-or-expression-without-metadata:error4: +1106 # print(stderr, "error: unexpected text after end of call in '" line "'") +1107 # . write-buffered(Stderr, "error: unexpected text after end of call in '") +1108 # . . push args +1109 68/push "error: unexpected text after end of call in '"/imm32 +1110 68/push Stderr/imm32 +1111 # . . call +1112 e8/call write-buffered/disp32 +1113 # . . discard args +1114 81 0/subop/add %esp 8/imm32 +1115 # . write-stream-data(Stderr, line) +1116 # . . push args +1117 56/push-esi +1118 68/push Stderr/imm32 +1119 # . . call +1120 e8/call write-stream-data/disp32 +1121 # . . discard args +1122 81 0/subop/add %esp 8/imm32 +1123 # . write-buffered(Stderr, "'") +1124 # . . push args +1125 68/push "'"/imm32 +1126 68/push Stderr/imm32 +1127 # . . call +1128 e8/call write-buffered/disp32 +1129 # . . discard args +1130 81 0/subop/add %esp 8/imm32 +1131 # . flush(Stderr) +1132 # . . push args +1133 68/push Stderr/imm32 +1134 # . . call +1135 e8/call flush/disp32 +1136 # . . discard args +1137 81 0/subop/add %esp 4/imm32 +1138 # . syscall(exit, 1) +1139 bb/copy-to-ebx 1/imm32 +1140 b8/copy-to-eax 1/imm32/exit +1141 cd/syscall 0x80/imm8 +1142 # never gets here +1143 +1144 $next-word-string-or-expression-without-metadata:error5: +1145 # print(stderr, "error: no metadata anywhere in calls (in '" line "')") +1146 # . write-buffered(Stderr, "error: no metadata anywhere in calls (in '") +1147 # . . push args +1148 68/push "error: no metadata anywhere in calls (in '"/imm32 +1149 68/push Stderr/imm32 +1150 # . . call +1151 e8/call write-buffered/disp32 +1152 # . . discard args +1153 81 0/subop/add %esp 8/imm32 +1154 # . write-stream-data(Stderr, line) +1155 # . . push args +1156 56/push-esi +1157 68/push Stderr/imm32 +1158 # . . call +1159 e8/call write-stream-data/disp32 +1160 # . . discard args +1161 81 0/subop/add %esp 8/imm32 +1162 # . write-buffered(Stderr, "')") +1163 # . . push args +1164 68/push "')"/imm32 +1165 68/push Stderr/imm32 +1166 # . . call +1167 e8/call write-buffered/disp32 +1168 # . . discard args +1169 81 0/subop/add %esp 8/imm32 +1170 # . flush(Stderr) +1171 # . . push args +1172 68/push Stderr/imm32 +1173 # . . call +1174 e8/call flush/disp32 +1175 # . . discard args +1176 81 0/subop/add %esp 4/imm32 +1177 # . syscall(exit, 1) +1178 bb/copy-to-ebx 1/imm32 +1179 b8/copy-to-eax 1/imm32/exit +1180 cd/syscall 0x80/imm8 +1181 # never gets here +1182 +1183 test-next-word-string-or-expression-without-metadata: +1184 # . prologue +1185 55/push-ebp +1186 89/<- %ebp 4/r32/esp +1187 # setup +1188 # . clear-stream(_test-input-stream) +1189 # . . push args +1190 68/push _test-input-stream/imm32 +1191 # . . call +1192 e8/call clear-stream/disp32 +1193 # . . discard args +1194 81 0/subop/add %esp 4/imm32 +1195 # var slice/ecx : slice +1196 68/push 0/imm32/end +1197 68/push 0/imm32/start +1198 89/<- %ecx 4/r32/esp +1199 # write(_test-input-stream, " ab") +1200 # . . push args +1201 68/push " ab"/imm32 +1202 68/push _test-input-stream/imm32 +1203 # . . call +1204 e8/call write/disp32 +1205 # . . discard args +1206 81 0/subop/add %esp 8/imm32 +1207 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1208 # . . push args +1209 51/push-ecx +1210 68/push _test-input-stream/imm32 +1211 # . . call +1212 e8/call next-word-string-or-expression-without-metadata/disp32 +1213 # . . discard args +1214 81 0/subop/add %esp 8/imm32 +1215 # check-ints-equal(_test-input-stream->read, 4, msg) +1216 # . . push args +1217 68/push "F - test-next-word-string-or-expression-without-metadata/updates-stream-read-correctly"/imm32 +1218 68/push 4/imm32 +1219 b8/copy-to-eax _test-input-stream/imm32 +1220 ff 6/subop/push *(eax+4) +1221 # . . call +1222 e8/call check-ints-equal/disp32 +1223 # . . discard args +1224 81 0/subop/add %esp 0xc/imm32 +1225 # check-ints-equal(slice->start - _test-input-stream->data, 2, msg) +1226 # . check-ints-equal(slice->start - _test-input-stream, 14, msg) +1227 # . . push args +1228 68/push "F - test-next-word-string-or-expression-without-metadata: start"/imm32 +1229 68/push 0xe/imm32 +1230 # . . push slice->start - _test-input-stream +1231 8b/-> *ecx 0/r32/eax +1232 81 5/subop/subtract %eax _test-input-stream/imm32 +1233 50/push-eax +1234 # . . call +1235 e8/call check-ints-equal/disp32 +1236 # . . discard args +1237 81 0/subop/add %esp 0xc/imm32 +1238 # check-ints-equal(slice->end - _test-input-stream->data, 4, msg) +1239 # . check-ints-equal(slice->end - _test-input-stream, 16, msg) +1240 # . . push args +1241 68/push "F - test-next-word-string-or-expression-without-metadata: end"/imm32 +1242 68/push 0x10/imm32 +1243 # . . push slice->end - _test-input-stream +1244 8b/-> *(ecx+4) 0/r32/eax +1245 81 5/subop/subtract %eax _test-input-stream/imm32 +1246 50/push-eax +1247 # . . call +1248 e8/call check-ints-equal/disp32 +1249 # . . discard args +1250 81 0/subop/add %esp 0xc/imm32 +1251 # . epilogue +1252 89/<- %esp 5/r32/ebp +1253 5d/pop-to-ebp +1254 c3/return +1255 +1256 test-next-word-string-or-expression-without-metadata-returns-whole-comment: +1257 # . prologue +1258 55/push-ebp +1259 89/<- %ebp 4/r32/esp +1260 # setup +1261 # . clear-stream(_test-input-stream) +1262 # . . push args +1263 68/push _test-input-stream/imm32 +1264 # . . call +1265 e8/call clear-stream/disp32 +1266 # . . discard args +1267 81 0/subop/add %esp 4/imm32 +1268 # var slice/ecx : slice +1269 68/push 0/imm32/end +1270 68/push 0/imm32/start +1271 89/<- %ecx 4/r32/esp +1272 # write(_test-input-stream, " # a") +1273 # . . push args +1274 68/push " # a"/imm32 +1275 68/push _test-input-stream/imm32 +1276 # . . call +1277 e8/call write/disp32 +1278 # . . discard args +1279 81 0/subop/add %esp 8/imm32 +1280 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1281 # . . push args +1282 51/push-ecx +1283 68/push _test-input-stream/imm32 +1284 # . . call +1285 e8/call next-word-string-or-expression-without-metadata/disp32 +1286 # . . discard args +1287 81 0/subop/add %esp 8/imm32 +1288 # check-ints-equal(_test-input-stream->read, 5, msg) +1289 # . . push args +1290 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-comment/updates-stream-read-correctly"/imm32 +1291 68/push 5/imm32 +1292 b8/copy-to-eax _test-input-stream/imm32 +1293 ff 6/subop/push *(eax+4) +1294 # . . call +1295 e8/call check-ints-equal/disp32 +1296 # . . discard args +1297 81 0/subop/add %esp 0xc/imm32 +1298 # check-ints-equal(slice->start - _test-input-stream->data, 2, msg) +1299 # . check-ints-equal(slice->start - _test-input-stream, 14, msg) +1300 # . . push args +1301 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-comment: start"/imm32 +1302 68/push 0xe/imm32 +1303 # . . push slice->start - _test-input-stream +1304 8b/-> *ecx 0/r32/eax +1305 81 5/subop/subtract %eax _test-input-stream/imm32 +1306 50/push-eax +1307 # . . call +1308 e8/call check-ints-equal/disp32 +1309 # . . discard args +1310 81 0/subop/add %esp 0xc/imm32 +1311 # check-ints-equal(slice->end - _test-input-stream->data, 5, msg) +1312 # . check-ints-equal(slice->end - _test-input-stream, 17, msg) +1313 # . . push args +1314 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-comment: end"/imm32 +1315 68/push 0x11/imm32 +1316 # . . push slice->end - _test-input-stream +1317 8b/-> *(ecx+4) 0/r32/eax +1318 81 5/subop/subtract %eax _test-input-stream/imm32 +1319 50/push-eax +1320 # . . call +1321 e8/call check-ints-equal/disp32 +1322 # . . discard args +1323 81 0/subop/add %esp 0xc/imm32 +1324 # . epilogue +1325 89/<- %esp 5/r32/ebp +1326 5d/pop-to-ebp +1327 c3/return +1328 +1329 test-next-word-string-or-expression-without-metadata-returns-empty-slice-on-eof: +1330 # . prologue +1331 55/push-ebp +1332 89/<- %ebp 4/r32/esp +1333 # setup +1334 # . clear-stream(_test-input-stream) +1335 # . . push args +1336 68/push _test-input-stream/imm32 +1337 # . . call +1338 e8/call clear-stream/disp32 +1339 # . . discard args +1340 81 0/subop/add %esp 4/imm32 +1341 # var slice/ecx : slice +1342 68/push 0/imm32/end +1343 68/push 0/imm32/start +1344 89/<- %ecx 4/r32/esp +1345 # write nothing to _test-input-stream +1346 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1347 # . . push args +1348 51/push-ecx +1349 68/push _test-input-stream/imm32 +1350 # . . call +1351 e8/call next-word-string-or-expression-without-metadata/disp32 +1352 # . . discard args +1353 81 0/subop/add %esp 8/imm32 +1354 # check-ints-equal(slice->end - slice->start, 0, msg) +1355 # . . push args +1356 68/push "F - test-next-word-string-or-expression-without-metadata-returns-empty-expression-on-eof"/imm32 +1357 68/push 0/imm32 +1358 # . . push slice->end - slice->start +1359 8b/-> *(ecx+4) 0/r32/eax +1360 2b/subtract-> *ecx 0/r32/eax # subtract *ecx from eax +1361 50/push-eax +1362 # . . call +1363 e8/call check-ints-equal/disp32 +1364 # . . discard args +1365 81 0/subop/add %esp 0xc/imm32 +1366 # . epilogue +1367 89/<- %esp 5/r32/ebp +1368 5d/pop-to-ebp +1369 c3/return +1370 +1371 test-next-word-string-or-expression-without-metadata-returns-string-literal: +1372 # . prologue +1373 55/push-ebp +1374 89/<- %ebp 4/r32/esp +1375 # setup +1376 # . clear-stream(_test-input-stream) +1377 # . . push args +1378 68/push _test-input-stream/imm32 +1379 # . . call +1380 e8/call clear-stream/disp32 +1381 # . . discard args +1382 81 0/subop/add %esp 4/imm32 +1383 # var slice/ecx : slice +1384 68/push 0/imm32/end +1385 68/push 0/imm32/start +1386 89/<- %ecx 4/r32/esp +1387 # write(_test-input-stream, " \"a b\" ") +1388 # . . push args +1389 68/push " \"a b\" "/imm32 +1390 68/push _test-input-stream/imm32 +1391 # . . call +1392 e8/call write/disp32 +1393 # . . discard args +1394 81 0/subop/add %esp 8/imm32 +1395 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1396 # . . push args +1397 51/push-ecx +1398 68/push _test-input-stream/imm32 +1399 # . . call +1400 e8/call next-word-string-or-expression-without-metadata/disp32 +1401 # . . discard args +1402 81 0/subop/add %esp 8/imm32 +1403 # check-ints-equal(slice->start - _test-input-stream->data, 1, msg) +1404 # . check-ints-equal(slice->start - _test-input-stream, 13, msg) +1405 # . . push args +1406 68/push "F - test-next-word-string-or-expression-without-metadata-returns-string-literal: start"/imm32 +1407 68/push 0xd/imm32 +1408 # . . push slice->start - _test-input-stream +1409 8b/-> *ecx 0/r32/eax +1410 81 5/subop/subtract %eax _test-input-stream/imm32 +1411 50/push-eax +1412 # . . call +1413 e8/call check-ints-equal/disp32 +1414 # . . discard args +1415 81 0/subop/add %esp 0xc/imm32 +1416 # check-ints-equal(slice->end - _test-input-stream->data, 6, msg) +1417 # . check-ints-equal(slice->end - _test-input-stream, 18, msg) +1418 # . . push args +1419 68/push "F - test-next-word-string-or-expression-without-metadata-returns-string-literal: end"/imm32 +1420 68/push 0x12/imm32 +1421 # . . push slice->end - _test-input-stream +1422 8b/-> *(ecx+4) 0/r32/eax +1423 81 5/subop/subtract %eax _test-input-stream/imm32 +1424 50/push-eax +1425 # . . call +1426 e8/call check-ints-equal/disp32 +1427 # . . discard args +1428 81 0/subop/add %esp 0xc/imm32 +1429 # . epilogue +1430 89/<- %esp 5/r32/ebp +1431 5d/pop-to-ebp +1432 c3/return +1433 +1434 test-next-word-string-or-expression-without-metadata-returns-string-with-escapes: +1435 # . prologue +1436 55/push-ebp +1437 89/<- %ebp 4/r32/esp +1438 # setup +1439 # . clear-stream(_test-input-stream) +1440 # . . push args +1441 68/push _test-input-stream/imm32 +1442 # . . call +1443 e8/call clear-stream/disp32 +1444 # . . discard args +1445 81 0/subop/add %esp 4/imm32 +1446 # var slice/ecx : slice +1447 68/push 0/imm32/end +1448 68/push 0/imm32/start +1449 89/<- %ecx 4/r32/esp +1450 # write(_test-input-stream, " \"a\\\"b\"") +1451 # . . push args +1452 68/push " \"a\\\"b\""/imm32 +1453 68/push _test-input-stream/imm32 +1454 # . . call +1455 e8/call write/disp32 +1456 # . . discard args +1457 81 0/subop/add %esp 8/imm32 +1458 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1459 # . . push args +1460 51/push-ecx +1461 68/push _test-input-stream/imm32 +1462 # . . call +1463 e8/call next-word-string-or-expression-without-metadata/disp32 +1464 # . . discard args +1465 81 0/subop/add %esp 8/imm32 +1466 # check-ints-equal(slice->start - _test-input-stream->data, 1, msg) +1467 # . check-ints-equal(slice->start - _test-input-stream, 13, msg) +1468 # . . push args +1469 68/push "F - test-next-word-string-or-expression-without-metadata-returns-string-with-escapes: start"/imm32 +1470 68/push 0xd/imm32 +1471 # . . push slice->start - _test-input-stream +1472 8b/-> *ecx 0/r32/eax +1473 81 5/subop/subtract %eax _test-input-stream/imm32 +1474 50/push-eax +1475 # . . call +1476 e8/call check-ints-equal/disp32 +1477 # . . discard args +1478 81 0/subop/add %esp 0xc/imm32 +1479 # check-ints-equal(slice->end - _test-input-stream->data, 7, msg) +1480 # . check-ints-equal(slice->end - _test-input-stream, 19, msg) +1481 # . . push args +1482 68/push "F - test-next-word-string-or-expression-without-metadata-returns-string-with-escapes: end"/imm32 +1483 68/push 0x13/imm32 +1484 # . . push slice->end - _test-input-stream +1485 8b/-> *(ecx+4) 0/r32/eax +1486 81 5/subop/subtract %eax _test-input-stream/imm32 +1487 50/push-eax +1488 # . . call +1489 e8/call check-ints-equal/disp32 +1490 # . . discard args +1491 81 0/subop/add %esp 0xc/imm32 +1492 # . epilogue +1493 89/<- %esp 5/r32/ebp +1494 5d/pop-to-ebp +1495 c3/return +1496 +1497 test-next-word-string-or-expression-without-metadata-returns-whole-expression: +1498 # . prologue +1499 55/push-ebp +1500 89/<- %ebp 4/r32/esp +1501 # setup +1502 # . clear-stream(_test-input-stream) +1503 # . . push args +1504 68/push _test-input-stream/imm32 +1505 # . . call +1506 e8/call clear-stream/disp32 +1507 # . . discard args +1508 81 0/subop/add %esp 4/imm32 +1509 # var slice/ecx : slice +1510 68/push 0/imm32/end +1511 68/push 0/imm32/start +1512 89/<- %ecx 4/r32/esp +1513 # write(_test-input-stream, " *(a b) ") +1514 # . . push args +1515 68/push " *(a b) "/imm32 +1516 68/push _test-input-stream/imm32 +1517 # . . call +1518 e8/call write/disp32 +1519 # . . discard args +1520 81 0/subop/add %esp 8/imm32 +1521 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1522 # . . push args +1523 51/push-ecx +1524 68/push _test-input-stream/imm32 +1525 # . . call +1526 e8/call next-word-string-or-expression-without-metadata/disp32 +1527 # . . discard args +1528 81 0/subop/add %esp 8/imm32 +1529 # check-ints-equal(slice->start - _test-input-stream->data, 1, msg) +1530 # . check-ints-equal(slice->start - _test-input-stream, 13, msg) +1531 # . . push args +1532 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-expression: start"/imm32 +1533 68/push 0xd/imm32 +1534 # . . push slice->start - _test-input-stream +1535 8b/-> *ecx 0/r32/eax +1536 81 5/subop/subtract %eax _test-input-stream/imm32 +1537 50/push-eax +1538 # . . call +1539 e8/call check-ints-equal/disp32 +1540 # . . discard args +1541 81 0/subop/add %esp 0xc/imm32 +1542 # check-ints-equal(slice->end - _test-input-stream->data, 7, msg) +1543 # . check-ints-equal(slice->end - _test-input-stream, 19, msg) +1544 # . . push args +1545 68/push "F - test-next-word-string-or-expression-without-metadata-returns-whole-expression: end"/imm32 +1546 68/push 0x13/imm32 +1547 # . . push slice->end - _test-input-stream +1548 8b/-> *(ecx+4) 0/r32/eax +1549 81 5/subop/subtract %eax _test-input-stream/imm32 +1550 50/push-eax +1551 # . . call +1552 e8/call check-ints-equal/disp32 +1553 # . . discard args +1554 81 0/subop/add %esp 0xc/imm32 +1555 # . epilogue +1556 89/<- %esp 5/r32/ebp +1557 5d/pop-to-ebp +1558 c3/return +1559 +1560 test-next-word-string-or-expression-without-metadata-returns-eol-on-trailing-close-paren: +1561 # . prologue +1562 55/push-ebp +1563 89/<- %ebp 4/r32/esp +1564 # setup +1565 # . clear-stream(_test-input-stream) +1566 # . . push args +1567 68/push _test-input-stream/imm32 +1568 # . . call +1569 e8/call clear-stream/disp32 +1570 # . . discard args +1571 81 0/subop/add %esp 4/imm32 +1572 # var slice/ecx : slice +1573 68/push 0/imm32/end +1574 68/push 0/imm32/start +1575 89/<- %ecx 4/r32/esp +1576 # write(_test-input-stream, " ) ") +1577 # . . push args +1578 68/push " ) "/imm32 +1579 68/push _test-input-stream/imm32 +1580 # . . call +1581 e8/call write/disp32 +1582 # . . discard args +1583 81 0/subop/add %esp 8/imm32 +1584 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1585 # . . push args +1586 51/push-ecx +1587 68/push _test-input-stream/imm32 +1588 # . . call +1589 e8/call next-word-string-or-expression-without-metadata/disp32 +1590 # . . discard args +1591 81 0/subop/add %esp 8/imm32 +1592 # check-ints-equal(slice->start, 0, msg) +1593 # . . push args +1594 68/push "F - test-next-word-string-or-expression-without-metadata-returns-eol-on-trailing-close-paren: start"/imm32 +1595 68/push 0/imm32 +1596 ff 6/subop/push *ecx +1597 # . . call +1598 e8/call check-ints-equal/disp32 +1599 # . . discard args +1600 81 0/subop/add %esp 0xc/imm32 +1601 # check-ints-equal(slice->end, 0, msg) +1602 # . . push args +1603 68/push "F - test-next-word-string-or-expression-without-metadata-returns-eol-on-trailing-close-paren: end"/imm32 +1604 68/push 0/imm32 +1605 ff 6/subop/push *(ecx+4) +1606 # . . call +1607 e8/call check-ints-equal/disp32 +1608 # . . discard args +1609 81 0/subop/add %esp 0xc/imm32 +1610 # . epilogue +1611 89/<- %esp 5/r32/ebp +1612 5d/pop-to-ebp +1613 c3/return +1614 +1615 test-next-word-string-or-expression-without-metadata-handles-comment-after-trailing-close-paren: +1616 # . prologue +1617 55/push-ebp +1618 89/<- %ebp 4/r32/esp +1619 # setup +1620 # . clear-stream(_test-input-stream) +1621 # . . push args +1622 68/push _test-input-stream/imm32 +1623 # . . call +1624 e8/call clear-stream/disp32 +1625 # . . discard args +1626 81 0/subop/add %esp 4/imm32 +1627 # var slice/ecx : slice +1628 68/push 0/imm32/end +1629 68/push 0/imm32/start +1630 89/<- %ecx 4/r32/esp +1631 # write(_test-input-stream, " ) # abc ") +1632 # . . push args +1633 68/push " ) # abc "/imm32 +1634 68/push _test-input-stream/imm32 +1635 # . . call +1636 e8/call write/disp32 +1637 # . . discard args +1638 81 0/subop/add %esp 8/imm32 +1639 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1640 # . . push args +1641 51/push-ecx +1642 68/push _test-input-stream/imm32 +1643 # . . call +1644 e8/call next-word-string-or-expression-without-metadata/disp32 +1645 # . . discard args +1646 81 0/subop/add %esp 8/imm32 +1647 # check-ints-equal(slice->start, 0, msg) +1648 # . . push args +1649 68/push "F - test-next-word-string-or-expression-without-metadata-handles-comment-after-trailing-close-paren: start"/imm32 +1650 68/push 0/imm32 +1651 ff 6/subop/push *ecx +1652 # . . call +1653 e8/call check-ints-equal/disp32 +1654 # . . discard args +1655 81 0/subop/add %esp 0xc/imm32 +1656 # check-ints-equal(slice->end, 0, msg) +1657 # . . push args +1658 68/push "F - test-next-word-string-or-expression-without-metadata-handles-comment-after-trailing-close-paren: end"/imm32 +1659 68/push 0/imm32 +1660 ff 6/subop/push *(ecx+4) +1661 # . . call +1662 e8/call check-ints-equal/disp32 +1663 # . . discard args +1664 81 0/subop/add %esp 0xc/imm32 +1665 # . epilogue +1666 89/<- %esp 5/r32/ebp +1667 5d/pop-to-ebp +1668 c3/return +1669 +1670 test-next-word-string-or-expression-without-metadata-handles-newline-after-trailing-close-paren: +1671 # . prologue +1672 55/push-ebp +1673 89/<- %ebp 4/r32/esp +1674 # setup +1675 # . clear-stream(_test-input-stream) +1676 # . . push args +1677 68/push _test-input-stream/imm32 +1678 # . . call +1679 e8/call clear-stream/disp32 +1680 # . . discard args +1681 81 0/subop/add %esp 4/imm32 +1682 # var slice/ecx : slice +1683 68/push 0/imm32/end +1684 68/push 0/imm32/start +1685 89/<- %ecx 4/r32/esp +1686 # write(_test-input-stream, " )\n") +1687 # . . push args +1688 68/push " )\n"/imm32 +1689 68/push _test-input-stream/imm32 +1690 # . . call +1691 e8/call write/disp32 +1692 # . . discard args +1693 81 0/subop/add %esp 8/imm32 +1694 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1695 # . . push args +1696 51/push-ecx +1697 68/push _test-input-stream/imm32 +1698 # . . call +1699 e8/call next-word-string-or-expression-without-metadata/disp32 +1700 # . . discard args +1701 81 0/subop/add %esp 8/imm32 +1702 # check-ints-equal(slice->start, 0, msg) +1703 # . . push args +1704 68/push "F - test-next-word-string-or-expression-without-metadata-handles-newline-after-trailing-close-paren: start"/imm32 +1705 68/push 0/imm32 +1706 ff 6/subop/push *ecx +1707 # . . call +1708 e8/call check-ints-equal/disp32 +1709 # . . discard args +1710 81 0/subop/add %esp 0xc/imm32 +1711 # check-ints-equal(slice->end, 0, msg) +1712 # . . push args +1713 68/push "F - test-next-word-string-or-expression-without-metadata-handles-newline-after-trailing-close-paren: end"/imm32 +1714 68/push 0/imm32 +1715 ff 6/subop/push *(ecx+4) +1716 # . . call +1717 e8/call check-ints-equal/disp32 +1718 # . . discard args +1719 81 0/subop/add %esp 0xc/imm32 +1720 # . epilogue +1721 89/<- %esp 5/r32/ebp +1722 5d/pop-to-ebp +1723 c3/return +1724 +1725 test-next-word-string-or-expression-without-metadata-stops-at-close-paren: +1726 # . prologue +1727 55/push-ebp +1728 89/<- %ebp 4/r32/esp +1729 # setup +1730 # . clear-stream(_test-input-stream) +1731 # . . push args +1732 68/push _test-input-stream/imm32 +1733 # . . call +1734 e8/call clear-stream/disp32 +1735 # . . discard args +1736 81 0/subop/add %esp 4/imm32 +1737 # var slice/ecx : slice +1738 68/push 0/imm32/end +1739 68/push 0/imm32/start +1740 89/<- %ecx 4/r32/esp +1741 # write(_test-input-stream, " abc) # def") +1742 # . . push args +1743 68/push " abc) # def"/imm32 +1744 68/push _test-input-stream/imm32 +1745 # . . call +1746 e8/call write/disp32 +1747 # . . discard args +1748 81 0/subop/add %esp 8/imm32 +1749 # next-word-string-or-expression-without-metadata(_test-input-stream, slice) +1750 # . . push args +1751 51/push-ecx +1752 68/push _test-input-stream/imm32 +1753 # . . call +1754 e8/call next-word-string-or-expression-without-metadata/disp32 +1755 # . . discard args +1756 81 0/subop/add %esp 8/imm32 +1757 # check-ints-equal(slice->start - _test-input-stream->data, 1, msg) +1758 # . check-ints-equal(slice->start - _test-input-stream, 13, msg) +1759 # . . push args +1760 68/push "F - test-next-word-string-or-expression-without-metadata-stops-at-close-paren: start"/imm32 +1761 68/push 0xd/imm32 +1762 # . . push slice->start - _test-input-stream +1763 8b/-> *ecx 0/r32/eax +1764 81 5/subop/subtract %eax _test-input-stream/imm32 +1765 50/push-eax +1766 # . . call +1767 e8/call check-ints-equal/disp32 +1768 # . . discard args +1769 81 0/subop/add %esp 0xc/imm32 +1770 # check-ints-equal(slice->end - _test-input-stream->data, 4, msg) +1771 # . check-ints-equal(slice->end - _test-input-stream, 16, msg) +1772 # . . push args +1773 68/push "F - test-next-word-string-or-expression-without-metadata-stops-at-close-paren: end"/imm32 +1774 68/push 0x10/imm32 +1775 # . . push slice->end - _test-input-stream +1776 8b/-> *(ecx+4) 0/r32/eax +1777 81 5/subop/subtract %eax _test-input-stream/imm32 +1778 50/push-eax +1779 # . . call +1780 e8/call check-ints-equal/disp32 +1781 # . . discard args +1782 81 0/subop/add %esp 0xc/imm32 +1783 # . epilogue +1784 89/<- %esp 5/r32/ebp +1785 5d/pop-to-ebp +1786 c3/return -- cgit 1.4.1-2-gfad0