Cleaner way to compare streams in tests.
This commit is contained in:
Kartik Agaram 2019-02-03 23:31:03 -08:00
parent 51b4f888dd
commit ddd2e9891e
16 changed files with 273 additions and 78 deletions

View File

@ -1,8 +1,8 @@
# streams: data structure for operating on arrays in a stateful manner
#
# A stream looks like this:
# read : int # index that we've read until
# write : int # index at which writes go
# read : int # index that we've read until
# data : (array byte) # prefixed by length as usual
#
# primitives for operating on streams:

View File

@ -1,8 +1,8 @@
# primitives for emitting traces to a 'trace' stream, and for tests to make assertions on its contents
#
# A trace stream looks like this:
# read : int # index that we've read until
# A trace stream looks like a regular stream:
# write : int # index at which writes go
# read : int # index that we've read until
# data : (array byte) # prefixed by length as usual
# In a real trace the data will be in a special segment set aside for the purpose.
#

225
subx/058stream-equal.subx Normal file
View File

@ -0,0 +1,225 @@
== code
# instruction effective address register displacement immediate
# . op subop mod rm32 base index scale r32
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
# main:
#? e8/call test-stream-data-equal/disp32
e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
# syscall(exit, Num-test-failures)
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX
b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8
# compare all the data in a stream (ignoring the read pointer)
stream-data-equal?: # f : (address stream), s : (address string) -> EAX : boolean
# . prolog
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
56/push-ESI
57/push-EDI
# ESI = f
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI
# max/EDX = f->data + f->write
8b/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy *ESI to EAX
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX . 2/r32/EDX 0xc/disp8 . # copy ESI+EAX+12 to EDX
# currf/ESI = f->data
81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 0xc/imm32 # add to ESI
# EDI = s
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 . # copy *(EBP+12) to EDI
# if (f->write != s->length) return false;
39/compare 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # compare *EDI and EAX
75/jump-if-not-equal $stream-data-equal?:false/disp8
# currs/EDI = s->data
81 0/subop/add 3/mod/direct 7/rm32/EDI . . . . . 4/imm32 # add to EDI
# EAX = ECX = 0
31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX
31/xor 3/mod/direct 1/rm32/ECX . . . 1/r32/ECX . . # clear ECX
$stream-data-equal?:loop:
# if (curr >= max) return true
39/compare 3/mod/direct 6/rm32/ESI . . . 2/r32/EDX . . # compare ESI with EDX
7d/jump-if-greater-or-equal $stream-data-equal?:true/disp8
# AL = *s
8a/copy-byte 0/mod/indirect 6/rm32/ESI . . . 0/r32/AL . . # copy byte at *ESI to AL
# CL = *curr
8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 1/r32/CL . . # copy byte at *EDI to CL
# if (EAX != ECX) return false
39/compare 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # compare EAX and ECX
75/jump-if-not-equal $stream-data-equal?:false/disp8
# ++f
46/increment-ESI
# ++curr
47/increment-EDI
eb/jump $stream-data-equal?:loop/disp8
$stream-data-equal?:false:
b8/copy-to-EAX 0/imm32
eb/jump $stream-data-equal?:end/disp8
$stream-data-equal?:true:
b8/copy-to-EAX 1/imm32
$stream-data-equal?:end:
# . restore registers
5f/pop-to-EDI
5e/pop-to-ESI
5a/pop-to-EDX
59/pop-to-ECX
# . epilog
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
c3/return
test-stream-data-equal:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# clear-stream(_test-stream)
# . . push args
68/push _test-stream/imm32
# . . call
e8/call clear-stream/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# write(_test-stream, "Abc")
# . . push args
68/push "Abc"/imm32
68/push _test-stream/imm32
# . . call
e8/call write/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# EAX = stream-data-equal?(_test-stream, "Abc")
# . . push args
68/push "Abc"/imm32
68/push _test-stream/imm32
# . . call
e8/call stream-data-equal?/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-stream-data-equal"/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
# . epilog
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
c3/return
test-stream-data-equal-2:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# clear-stream(_test-stream)
# . . push args
68/push _test-stream/imm32
# . . call
e8/call clear-stream/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# write(_test-stream, "Abc")
# . . push args
68/push "Abc"/imm32
68/push _test-stream/imm32
# . . call
e8/call write/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# EAX = stream-data-equal?(_test-stream, "Abd")
# . . push args
68/push "Abd"/imm32
68/push _test-stream/imm32
# . . call
e8/call stream-data-equal?/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-stream-data-equal-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
# . epilog
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
c3/return
test-stream-data-equal-length-check:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# clear-stream(_test-stream)
# . . push args
68/push _test-stream/imm32
# . . call
e8/call clear-stream/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# write(_test-stream, "Abc")
# . . push args
68/push "Abc"/imm32
68/push _test-stream/imm32
# . . call
e8/call write/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# EAX = stream-data-equal?(_test-stream, "Abcd")
# . . push args
68/push "Abcd"/imm32
68/push _test-stream/imm32
# . . call
e8/call stream-data-equal?/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-stream-data-equal-length-check"/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
# . epilog
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
c3/return
# helper for tests
check-stream-equal: # f : (address stream), s : (address string), msg : (address string)
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# . save registers
50/push-EAX
# EAX = stream-data-equal?(f, s)
# . . push args
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12)
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8)
# . . call
e8/call stream-data-equal?/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
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 . # push *(EBP+16)
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
# . restore registers
58/pop-to-EAX
# . epilog
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
c3/return

View File

@ -220,15 +220,13 @@ test-read-single:
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# check-ints-equal(*_test-stream-buffer->data, 41/A 62/b 00 00, msg)
# check-stream-equal(_test-stream-buffer, "Ab", msg)
# . . push args
68/push "F - test-read-single"/imm32
68/push 0x006241/imm32/Ab
# . . push *_test-stream-buffer->data
b8/copy-to-EAX _test-stream-buffer/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "Ab"/imm32
68/push _test-stream-buffer/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# end
@ -282,15 +280,13 @@ test-read-is-stateful:
e8/call read/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(*_test-stream-buffer->data, 43/C 44/D 00 00, msg)
# check-stream-equal(_test-stream-buffer, "CD", msg)
# . . push args
68/push "F - test-read-is-stateful"/imm32
68/push 0x00004443/imm32/C-D
# . . push *_test-stream-buffer->data
b8/copy-to-EAX _test-stream-buffer/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "CD"/imm32
68/push _test-stream-buffer/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# end

View File

@ -12,7 +12,7 @@
#? 68/push 1/imm32/stdout
#? e8/call write-stream/disp32
# automatic test
#? e8/call test-write-stream-appends/disp32
#? e8/call test-write-stream-single/disp32
e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
# syscall(exit, Num-test-failures)
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX
@ -150,15 +150,13 @@ test-write-stream-single:
e8/call write-stream/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(*_test-stream->data, 41/A 62/b 00 00, msg)
# check-stream-equal(_test-stream, "Ab", msg)
# . . push args
68/push "F - test-write-stream-single"/imm32
68/push 0x006241/imm32/Ab
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "Ab"/imm32
68/push _test-stream/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# . end
@ -214,15 +212,13 @@ test-write-stream-appends:
e8/call write-stream/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(*_test-stream->data, 43/C 44/D 00 00, msg)
# check-stream-equal(_test-stream, "CD", msg)
# . . push args
68/push "F - test-write-stream-appends"/imm32
68/push 0x00004443/imm32/C-D
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "CD"/imm32
68/push _test-stream/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# . end

View File

@ -146,15 +146,13 @@ test-write-byte-single:
e8/call flush/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# check-ints-equal(*_test-stream->data, 'A', msg)
# check-stream-equal(_test-stream, "A", msg)
# . . push args
68/push "F - test-write-byte-single"/imm32
68/push 0x41/imm32
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "A"/imm32
68/push _test-stream/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# . end
@ -205,26 +203,13 @@ test-write-byte-multiple-flushes:
e8/call flush/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# check-ints-equal(_test-stream->data[0..3], 'abcd', msg)
# check-stream-equal(_test-stream, "abcdef", msg)
# . . push args
68/push "F - test-write-byte-multiple-flushes: 1"/imm32
68/push 0x64636261/imm32
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "abcdefg"/imm32
68/push _test-stream/imm32
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# check-ints-equal(_test-stream->data[4..8], 'efg', msg)
# . . push args
68/push "F - test-write-byte-multiple-flushes"/imm32
68/push 0x00676665/imm32
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0x10/disp8 . # push *(EAX+16)
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# . end

View File

@ -87,15 +87,13 @@ test-print-byte:
e8/call flush/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# check-ints-equal(*_test-stream->data, '0a', msg)
# check-stream-equal(_test-stream, "0a", msg)
# . . push args
68/push "F - test-print-byte"/imm32
68/push 0x6130/imm32/0a
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "0a"/imm32
68/push _test-stream/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# . end

View File

@ -146,15 +146,13 @@ test-write-buffered:
e8/call flush/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# check-ints-equal(*_test-stream->data, "Abc", msg)
# check-stream-equal(_test-stream, "Abc", msg)
# . . push args
68/push "F - test-write-buffered-single"/imm32
68/push 0x636241/imm32
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "Abc"/imm32
68/push _test-stream/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# . end
@ -203,7 +201,7 @@ test-write-buffered-with-intermediate-flush:
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# and 1 byte should still be in _test-buffered-file
# . check-ints-equal(*_test-buffered-file>write, 1, msg)
# . check-ints-equal(*_test-buffered-file->write, 1, msg)
# . . push args
68/push "F - test-write-buffered-with-intermediate-flush: unflushed bytes"/imm32
68/push 1/imm32

View File

@ -184,7 +184,8 @@ test-read-line:
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# check-ints-equal(*_test-stream-buffer->data, 61/a 62/b 0a/newline 00, msg)
# check-stream-equal(_test-stream-buffer, "ab\n")
# . check-ints-equal(*_test-stream-buffer->data, 61/a 62/b 0a/newline 00, msg)
# . . push args
68/push "F - test-read-line"/imm32
68/push 0x000a6261/imm32
@ -295,15 +296,13 @@ test-read-line-reads-final-line-until-eof:
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# check-ints-equal(*_test-stream-buffer->data, 63/c 64/d 00 00, msg)
# check-stream-equal(_test-stream-buffer, "cd", msg)
# . . push args
68/push "F - test-read-line-reads-final-line-until-eof"/imm32
68/push 0x00006463/imm32
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream-buffer/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "cd"/imm32
68/push _test-stream-buffer/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# end

View File

@ -120,7 +120,7 @@ slice-equal?: # s : (address slice), p : (address string) -> EAX : boolean
75/jump-if-not-equal $slice-equal?:false/disp8
# skip p->length
81 0/subop/add 3/mod/direct 3/rm32/EBX . . . . . 4/imm32 # add to EBX
# EAX = ECX = false
# EAX = ECX = 0
31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX
31/xor 3/mod/direct 1/rm32/ECX . . . 1/r32/ECX . . # clear ECX
$slice-equal?:loop:
@ -489,15 +489,13 @@ test-write-slice:
e8/call flush/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# check-ints-equal(*_test-stream->data, "Abc", msg)
# check-stream-equal(_test-stream, "Abc", msg)
# . . push args
68/push "F - test-write-slice"/imm32
68/push 0x636241/imm32
# . . push *_test-stream->data
b8/copy-to-EAX _test-stream/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
68/push "Abc"/imm32
68/push _test-stream/imm32
# . . call
e8/call check-ints-equal/disp32
e8/call check-stream-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# . epilog

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.