/archive/1.vm/
- ../
- 000organization.cc
- 001help.cc
- 002test.cc
- 003trace.cc
- 003trace.test.cc
- 010vm.cc
- 011load.cc
- 012transform.cc
- 013update_operation.cc
- 014literal_string.cc
- 015literal_noninteger.cc
- 016dilated_reagent.cc
- 017parse_tree.cc
- 018constant.cc
- 019type_abbreviations.cc
- 020run.cc
- 021check_instruction.cc
- 022arithmetic.cc
- 023boolean.cc
- 024jump.cc
- 025compare.cc
- 026call.cc
- 027call_ingredient.cc
- 028call_return.cc
- 029tools.cc
- 030container.cc
- 031merge.cc
- 032array.cc
- 033exclusive_container.cc
- 034address.cc
- 035lookup.cc
- 036abandon.cc
- 038new_text.cc
- 040brace.cc
- 041jump_target.cc
- 042name.cc
- 043space.cc
- 044space_surround.cc
- 045closure_name.cc
- 046check_type_by_name.cc
- 050scenario.cc
- 051scenario_test.mu
- 052tangle.cc
- 053recipe_header.cc
- 054static_dispatch.cc
- 055shape_shifting_container.cc
- 056shape_shifting_recipe.cc
- 057immutable.cc
- 058to_text.cc
- 059to_text.mu
- 060rewrite_literal_string.cc
- 061text.mu
- 062convert_ingredients_to_text.cc
- 063array.mu
- 064list.mu
- 065duplex_list.mu
- 066stream.mu
- 067random.cc
- 068random.mu
- 069hash.cc
- 070table.mu
- 072recipe.cc
- 073scheduler.cc
- 074wait.cc
- 075channel.mu
- 076continuation.cc
- 080display.cc
- 081print.mu
- 082scenario_screen.cc
- 083scenario_screen_test.mu
- 084console.mu
- 085scenario_console.cc
- 086scenario_console_test.mu
- 087file.cc
- 088file.mu
- 089scenario_filesystem.cc
- 090scenario_filesystem_test.mu
- 091socket.cc
- 092socket.mu
- 099hardware_checks.cc
- 101run_sandboxed.cc
- read and return true.
trace-scan: # line : (address array byte) -> result/eax : boolean
# pseudocode:
# push Trace-stream->read
# while true:
# if Trace-stream->read >= Trace-stream->write
# break
# if next-line-matches?(Trace-stream, line)
# skip-next-line(Trace-stream)
# dump saved copy of Trace-stream->read
# return true
# skip-next-line(Trace-stream)
# pop saved copy of Trace-stream->read
# return false
#
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
51/push-ecx
56/push-esi
# esi = *Trace-stream
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 6/r32/esi Trace-stream/disp32 # copy *Trace-stream to esi
# ecx = Trace-stream->write
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . # copy *esi to ecx
# push Trace-stream->read
ff 6/subop/push 1/mod/*+disp8 6/rm32/esi . . . . 4/disp8 . # push *(esi+4)
$trace-scan:loop:
# if (Trace-stream->read >= Trace-stream->write) return false
39/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # compare ecx with *(esi+4)
7d/jump-if-greater-or-equal $trace-scan:false/disp8
# eax = next-line-matches?(Trace-stream, line)
# . . push args
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
56/push-esi
# . . call
e8/call next-line-matches?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# if (eax == false) continue
3d/compare-eax-and 0/imm32/false
74/jump-if-equal $trace-scan:continue/disp8
$trace-scan:true:
# skip-next-line(Trace-stream)
# . . push args
56/push-esi
# . . call
e8/call skip-next-line/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# dump saved copy of Trace-stream->read
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# return true
b8/copy-to-eax 1/imm32/true
eb/jump $trace-scan:end/disp8
$trace-scan:continue:
# skip-next-line(Trace-stream)
# . . push args
56/push-esi
# . . call
e8/call skip-next-line/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
eb/jump $trace-scan:loop/disp8
$trace-scan:false:
# restore saved copy of Trace-stream->read
8f 0/subop/pop 1/mod/*+disp8 6/rm32/esi . . . . 4/disp8 . # pop to *(esi+4)
# return false
b8/copy-to-eax 0/imm32/false
$trace-scan:end:
# . restore registers
59/pop-to-ecx
# . epilogue
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
5d/pop-to-ebp
c3/return
test-trace-scan-first:
# push *Trace-stream
ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # push *Trace-stream
# setup
# . *Trace-stream = _test-trace-stream
b8/copy-to-eax _test-trace-stream/imm32
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream
# . clear-trace-stream()
e8/call clear-trace-stream/disp32
# . trace("Ab")
# . . push args
68/push "Ab"/imm32
# . . call
e8/call trace/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# eax = trace-scan("Ab")
# . . push args
68/push "Ab"/imm32
# . . call
e8/call trace-scan/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# check-ints-equal(eax, 1, msg)
# . . push args
68/push "F - test-trace-scan-first"/imm32
68/push 1/imm32
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# pop into *Trace-stream
8f 0/subop/pop 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # pop into *Trace-stream
# . end
c3/return
test-trace-scan-skips-lines-until-found:
# push *Trace-stream
ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # push *Trace-stream
# setup
# . *Trace-stream = _test-trace-stream
b8/copy-to-eax _test-trace-stream/imm32
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream
# . clear-trace-stream()
e8/call clear-trace-stream/disp32
# . trace("Ab")
# . . push args
68/push "Ab"/imm32
# . . call
e8/call trace/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# . trace("cd")
# . . push args
68/push "cd"/imm32
# . . call
e8/call trace/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# eax = trace-scan("cd")
# . . push args
68/push "cd"/imm32
# . . call
e8/call trace-scan/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# check-ints-equal(eax, 1, msg)
# . . push args
68/push "F - test-trace-scan-skips-lines-until-found"/imm32
68/push 1/imm32
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# pop into *Trace-stream
8f 0/subop/pop 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # pop into *Trace-stream
# . end
c3/return
test-trace-second-scan-starts-where-first-left-off:
# push *Trace-stream
ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # push *Trace-stream
# setup
# . *Trace-stream = _test-trace-stream
b8/copy-to-eax _test-trace-stream/imm32
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream
# . clear-trace-stream()
e8/call clear-trace-stream/disp32
# . trace("Ab")
# . . push args
68/push "Ab"/imm32
# . . call
e8/call trace/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# . eax = trace-scan("Ab")
# . . push args
68/push "Ab"/imm32
# . . call
e8/call trace-scan/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# second scan fails
# . eax = trace-scan("Ab")
# . . push args
68/push "Ab"/imm32
# . . call
e8/call trace-scan/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# check-ints-equal(eax, 0, msg)
# . . push args
68/push "F - test-trace-second-scan-starts-where-first-left-off"/imm32
68/push 0/imm32
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# pop into *Trace-stream
8f 0/subop/pop 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # pop into *Trace-stream
# . end
c3/return
test-trace-scan-failure-leaves-read-index-untouched:
# push *Trace-stream
ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # push *Trace-stream
# setup
# . *Trace-stream = _test-trace-stream
b8/copy-to-eax _test-trace-stream/imm32
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream
# . clear-trace-stream()
e8/call clear-trace-stream/disp32
# . trace("Ab")
# . . push args
68/push "Ab"/imm32
# . . call
e8/call trace/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# . check-ints-equal(_test-trace-stream->read, 0, msg)
# . . push args
68/push "F - test-trace-second-scan-starts-where-first-left-off/precondition-failure"/imm32
68/push 0/imm32
b8/copy-to-eax _test-trace-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4)
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# perform a failing scan
# . eax = trace-scan("Ax")
# . . push args
68/push "Ax"/imm32
# . . call
e8/call trace-scan/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# no change in read index
# . check-ints-equal(_test-trace-stream->read, 0, msg)
# . . push args
68/push "F - test-trace-second-scan-starts-where-first-left-off"/imm32
68/push 0/imm32
b8/copy-to-eax _test-trace-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4)
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# pop into *Trace-stream
8f 0/subop/pop 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # pop into *Trace-stream
# . end
c3/return
next-line-matches?: # t : (address stream byte), line : (address array byte) -> result/eax : boolean
# pseudocode:
# while true:
# if (currl >= maxl) break
# if (currt >= maxt) return false
# if (*currt != *currl) return false
# ++currt
# ++currl
# return *currt == '\n'
#
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
51/push-ecx
52/push-edx
53/push-ebx
56/push-esi
57/push-edi
# edx = line
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
# var currl/esi : (address byte) = line->data
# . esi = line/edx->data
8d/copy-address 1/mod/*+disp8 2/rm32/edx . . . 6/r32/esi 4/disp8 . # copy edx+4 to esi
# var maxl/ecx : (address byte) = &line->data[line->size]
# . eax = line/edx->size
8b/copy 0/mod/indirect 2/rm32/edx . . 0/r32/eax . . # copy *edx to eax
# . maxl = &line->data[line->size]
8d/copy-address 0/mod/indirect 4/rm32/sib 6/base/esi 0/index/eax . 1/r32/ecx . . # copy edx+eax to ecx
# edi = t
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# var ebx : (address byte) = t->data
8d/copy-address 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 0xc/disp8 . # copy edi+12 to ebx
# var maxt/edx : (address byte) = &t->data[t->write]
# . eax = t->write
8b/copy 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax
# . maxt = &t->data[t->write]
8d/copy-address 0/mod/indirect 4/rm32/sib 3/base/ebx 0/index/eax . 2/r32/edx . . # copy ebx+eax to edx
# var currt/edi : (address byte) = &t->data[t->read]
# . eax = t/edi->read
8b/copy 1/mod/*+disp8 7/rm32/edi . . 0/r32/eax 4/disp8 . # copy *(edi+4) to eax
# . currt = &t->data[t->read]
8d/copy-address 0/mod/indirect 4/rm32/sib 3/base/ebx 0/index/eax . 7/r32/edi . . # copy ebx+eax to edi
$next-line-matches?:loop:
# if (currl >= maxl) break
39/compare 3/mod/direct 6/rm32/esi . . . 1/r32/ecx . . # compare esi and ecx
73/jump-if-greater-or-equal-unsigned $next-line-matches?:break/disp8
# if (currt >= maxt) return false
# . eax = false
b8/copy-to-eax 0/imm32/false
39/compare 3/mod/direct 7/rm32/edi . . . 2/r32/edx . . # compare edi and edx
73/jump-if-greater-or-equal-unsigned $next-line-matches?:end/disp8
# if (*currt != *currl) return false
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
31/xor 3/mod/direct 3/rm32/eax . . . 3/r32/eax . . # clear ebx
# . eax : byte = *currt
8a/copy-byte 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax
# . ebx : byte = *currl
8a/copy-byte 0/mod/indirect 6/rm32/esi . . 3/r32/ebx . . # copy *esi to ebx
# . eax >= ebx
39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx
# . eax = false
b8/copy-to-eax 0/imm32/false
75/jump-if-not-equal $next-line-matches?:end/disp8
# ++currt
47/increment-edi
# ++currl
46/increment-esi
eb/jump $next-line-matches?:loop/disp8
$next-line-matches?:break:
# return *currt == '\n'
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# . eax : byte = *currt
8a/copy-byte 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax
3d/compare-eax-and 0xa/imm32/newline
# . eax = false
b8/copy-to-eax 1/imm32/true
74/jump-if-equal $next-line-matches?:end/disp8
b8/copy-to-eax 0/imm32/true
$next-line-matches?:end:
# . restore registers
5f/pop-to-edi
5e/pop-to-esi
5b/pop-to-ebx
5a/pop-to-edx
59/pop-to-ecx
# . epilogue
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
5d/pop-to-ebp
c3/return
test-next-line-matches?-no-match-1:
# next line of "ABABA" does not match "blah blah"
# . eax = next-line-matches?(_test-stream-line-ABABA, "blah blah")
# . . push args
68/push "blah blah"/imm32
68/push _test-stream-line-ABABA/imm32
# . . call
e8/call next-line-matches?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# . check-ints-equal(eax, 0, msg)
# . . push args
68/push "F - test-next-line-matches?-no-match-1"/imm32
68/push 0/imm32
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return
test-next-line-matches?-no-match-2:
# next line of "ABABA" does not match ""
# . eax = next-line-matches?(_test-stream-line-ABABA, "")
# . . push args
68/push ""/imm32
68/push _test-stream-line-ABABA/imm32
# . . call
e8/call next-line-matches?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# . check-ints-equal(eax, 0, msg)
# . . push args
68/push "F - test-next-line-matches?-no-match-2"/imm32
68/push 0/imm32
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return
test-next-line-matches?-no-match-3:
# next line of "ABABA" does not match "AA"
# . eax = next-line-matches?(_test-stream-line-ABABA, "AA")
# . . push args
68/push "AA"/imm32
68/push _test-stream-line-ABABA/imm32
# . . call
e8/call next-line-matches?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# . check-ints-equal(eax, 0, msg)
# . . push args
68/push "F - test-next-line-matches?-no-match-3"/imm32
68/push 0/imm32
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return
test-next-line-matches?-match:
# next line of "ABABA" matches "ABABA"
# . eax = next-line-matches?(_test-stream-line-ABABA, "ABABA")
# . . push args
68/push "ABABA"/imm32
68/push _test-stream-line-ABABA/imm32
# . . call
e8/call next-line-matches?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# . check-ints-equal(eax, 1, msg)
# . . push args
68/push "F - test-next-line-matches?-match"/imm32
68/push 1/imm32
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return
# move t->read to _after_ next newline
skip-next-line: # t : (address stream byte)
# pseudocode:
# max = &t->data[t->write]
# i = t->read
# curr = &t->data[t->read]
# while true
# if (curr >= max) break
# ++i
# if (*curr == '\n') break
# ++curr
# t->read = i
#
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
50/push-eax
51/push-ecx
52/push-edx
53/push-ebx
# ecx = t
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
# edx = t->data
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 0xc/disp8 . # copy ecx+12 to edx
# eax = t->write
8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax
# var max/ebx : (address byte) = &t->data[t->write]
8d/copy-address 0/mod/indirect 4/rm32/sib 2/base/edx 0/index/eax . 3/r32/ebx . . # copy edx+eax to ebx
# eax = t->read
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy *(ecx+4) to edx
# var curr/ecx : (address byte) = &t->data[t->read]
8d/copy-address 0/mod/indirect 4/rm32/sib 2/base/edx 0/index/eax . 1/r32/ecx . . # copy edx+eax to ecx
# var i/edx : int = t->read
89/copy 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # copy eax to edx
$skip-next-line:loop:
# if (curr >= max) break
39/compare 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # compare ecx and ebx
73/jump-if-greater-or-equal-unsigned $skip-next-line:end/disp8
# ++i
42/increment-edx
# if (*curr == '\n') break
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax
3d/compare-eax-and 0a/imm32/newline
74/jump-if-equal $skip-next-line:end/disp8
# ++curr
41/increment-ecx
# loop
eb/jump $skip-next-line:loop/disp8
$skip-next-line:end:
# ecx = t
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
# t->read = i
89/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy edx to *(ecx+4)
# . restore registers
5b/pop-to-ebx
5a/pop-to-edx
59/pop-to-ecx
58/pop-to-eax
# . epilogue
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
5d/pop-to-ebp
c3/return
test-skip-next-line-empty:
# skipping next line in empty stream leaves read pointer at 0
# . skip-next-line(_test-stream-empty)
# . . push args
68/push _test-stream-empty/imm32
# . . call
e8/call skip-next-line/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# . check-ints-equal(_test-stream-empty->read, 0, msg)
# . . push args
68/push "F - test-skip-next-line-empty"/imm32
68/push 0/imm32
b8/copy-to-eax _test-stream-empty/imm32
8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return
test-skip-next-line-filled:
# skipping next line increments read pointer by length of line + 1 (for newline)
# . skip-next-line(_test-stream-filled)
# . . push args
68/push _test-stream-filled/imm32
# . . call
e8/call skip-next-line/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# . check-ints-equal(_test-stream-filled->read, 5, msg)
# . . push args
68/push "F - test-skip-next-line-filled"/imm32
68/push 5/imm32
b8/copy-to-eax _test-stream-filled/imm32
8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax
50/push-eax
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return
clear-trace-stream:
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# clear-stream(*Trace-stream)
# . . push args
ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Trace-stream/disp32 # push *Trace-stream
# . . call
e8/call clear-stream/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
$clear-trace-stream:end:
# . epilogue
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
5d/pop-to-ebp
c3/return
# - helpers
# 3-argument variant of _append
_append-3: # out : (address byte), outend : (address byte), s : (address array byte) -> num_bytes_appended/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
51/push-ecx
# eax = _append-4(out, outend, &s->data[0], &s->data[s->length])
# . . push &s->data[s->length]
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
51/push-ecx
# . . push &s->data[0]
8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy eax+4 to ecx
51/push-ecx
# . . push outend
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12)
# . . push out
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
# . . call
e8/call _append-4/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp
$_append-3:end:
# . restore registers
59/pop-to-ecx
# . epilogue
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
5d/pop-to-ebp
c3/return
# 4-argument variant of _append
_append-4: # out : (address byte), outend : (address byte), in : (address byte), inend : (address byte) -> num_bytes_appended/eax : int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
51/push-ecx
52/push-edx
53/push-ebx
56/push-esi
57/push-edi
# num_bytes_appended = 0
b8/copy-to-eax 0/imm32
# edi = out
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# edx = outend
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
# esi = in
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0x10/disp8 . # copy *(ebp+16) to esi
# ecx = inend
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x14/disp8 . # copy *(ebp+20) to ecx
$_append-4:loop:
# if (in >= inend) break
39/compare 3/mod/direct 6/rm32/esi . . . 1/r32/ecx . . # compare esi with ecx
73/jump-if-greater-or-equal-unsigned $_append-4:end/disp8
# if (out >= outend) abort # just to catch test failures fast
39/compare 3/mod/direct 7/rm32/edi . . . 2/r32/edx . . # compare edi with edx
73/jump-if-greater-or-equal-unsigned $_append-4:abort/disp8
# *out = *in
8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 3/r32/BL . . # copy byte at *esi to BL
88/copy-byte 0/mod/indirect 7/rm32/edi . . . 3/r32/BL . . # copy byte at BL to *edi
# ++num_bytes_appended
40/increment-eax
# ++in
46/increment-esi
# ++out
47/increment-edi
eb/jump $_append-4:loop/disp8
$_append-4:end:
# . restore registers
5f/pop-to-edi
5e/pop-to-esi
5b/pop-to-ebx
5a/pop-to-edx
59/pop-to-ecx
# . epilogue
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
5d/pop-to-ebp
c3/return
$_append-4:abort:
# . _write(2/stderr, error)
# . . push args
68/push "stream overflow\n"/imm32
68/push 2/imm32/stderr
# . . call
e8/call _write/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# . syscall(exit, 1)
bb/copy-to-ebx 1/imm32
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
# never gets here
== data
_test-stream-line-ABABA: # (ref stream byte)
# write
8/imm32
# read
0/imm32
# length
8/imm32
# data
41 42 41 42 41 0a 00 00 # 8 bytes
_test-stream-empty: # (ref stream byte)
# write
0/imm32
# read
0/imm32
# length
8/imm32
# data
00 00 00 00 00 00 00 00 # 8 bytes
_test-stream-filled: # (ref stream byte)
# write
8/imm32
# read
0/imm32
# length
8/imm32
# data
41 41 41 41 0a 41 41 41 # 8 bytes
# . . vim:nowrap:textwidth=0