298 lines
7.4 KiB
Plaintext
298 lines
7.4 KiB
Plaintext
# Some unsafe methods not intended to be used directly in SubX, only through
|
|
# Mu after proper type-checking.
|
|
|
|
== code
|
|
|
|
stream-empty?: # s: (addr stream _) -> result/eax: boolean
|
|
# . prologue
|
|
55/push-ebp
|
|
89/<- %ebp 4/r32/esp
|
|
# . save registers
|
|
51/push-ecx
|
|
56/push-esi
|
|
# result = false
|
|
b8/copy-to-eax 0/imm32/false
|
|
# esi = s
|
|
8b/-> *(ebp+8) 6/r32/esi
|
|
# return s->read >= s->write
|
|
8b/-> *esi 1/r32/ecx
|
|
39/compare-with *(esi+4) 1/r32/ecx
|
|
0f 9d/set-if->= %al
|
|
$stream-empty?:end:
|
|
# . restore registers
|
|
5e/pop-to-esi
|
|
59/pop-to-ecx
|
|
# . epilogue
|
|
89/<- %esp 5/r32/ebp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
stream-full?: # s: (addr stream _) -> result/eax: boolean
|
|
# . prologue
|
|
55/push-ebp
|
|
89/<- %ebp 4/r32/esp
|
|
# . save registers
|
|
51/push-ecx
|
|
56/push-esi
|
|
# result = false
|
|
b8/copy-to-eax 0/imm32/false
|
|
# esi = s
|
|
8b/-> *(ebp+8) 6/r32/esi
|
|
# return s->write >= s->size
|
|
8b/-> *(esi+8) 1/r32/ecx
|
|
39/compare-with *esi 1/r32/ecx
|
|
0f 9d/set-if->= %al
|
|
$stream-full?:end:
|
|
# . restore registers
|
|
5e/pop-to-esi
|
|
59/pop-to-ecx
|
|
# . epilogue
|
|
89/<- %esp 5/r32/ebp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
write-to-stream: # s: (addr stream _), in: (addr byte), n: int
|
|
# . prologue
|
|
55/push-ebp
|
|
89/<- %ebp 4/r32/esp
|
|
# . save registers
|
|
50/push-eax
|
|
51/push-ecx
|
|
52/push-edx
|
|
53/push-ebx
|
|
57/push-edi
|
|
# edi = s
|
|
8b/-> *(ebp+8) 7/r32/edi
|
|
# var swrite/edx: int = s->write
|
|
8b/-> *edi 2/r32/edx
|
|
# if (swrite + n > s->size) abort
|
|
8b/-> *(ebp+0x10) 1/r32/ecx
|
|
01/add-to %ecx 2/r32/edx
|
|
3b/compare 1/r32/ecx *(edi+8)
|
|
0f 8f/jump-if-> $write-to-stream:abort/disp32
|
|
# var out/edx: (addr byte) = s->data + s->write
|
|
8d/copy-address *(edi+edx+0xc) 2/r32/edx
|
|
# var outend/ebx: (addr byte) = out + n
|
|
8b/-> *(ebp+0x10) 3/r32/ebx
|
|
8d/copy-address *(edx+ebx) 3/r32/ebx
|
|
# eax = in
|
|
8b/-> *(ebp+0xc) 0/r32/eax
|
|
# var inend/ecx: (addr byte) = in + n
|
|
8b/-> *(ebp+0x10) 1/r32/ecx
|
|
8d/copy-address *(eax+ecx) 1/r32/ecx
|
|
#
|
|
(_append-4 %edx %ebx %eax %ecx) # => eax
|
|
# s->write += n
|
|
8b/-> *(ebp+0x10) 1/r32/ecx
|
|
01/add-to *edi 1/r32/ecx
|
|
$write-to-stream:end:
|
|
# . restore registers
|
|
5f/pop-to-edi
|
|
5b/pop-to-ebx
|
|
5a/pop-to-edx
|
|
59/pop-to-ecx
|
|
58/pop-to-eax
|
|
# . epilogue
|
|
89/<- %esp 5/r32/ebp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
$write-to-stream:abort:
|
|
(abort "write-to-stream: stream full")
|
|
# never gets here
|
|
|
|
read-from-stream: # s: (addr stream _), out: (addr byte), n: int
|
|
# . prologue
|
|
55/push-ebp
|
|
89/<- %ebp 4/r32/esp
|
|
# . save registers
|
|
50/push-eax
|
|
51/push-ecx
|
|
52/push-edx
|
|
53/push-ebx
|
|
56/push-esi
|
|
# esi = s
|
|
8b/-> *(ebp+8) 6/r32/esi
|
|
# var sread/edx: int = s->read
|
|
8b/-> *(esi+4) 2/r32/edx
|
|
# if (sread + n > s->write) abort
|
|
8b/-> *(ebp+0x10) 1/r32/ecx
|
|
01/add-to %ecx 2/r32/edx
|
|
3b/compare 1/r32/ecx *esi
|
|
0f 8f/jump-if-> $read-from-stream:abort/disp32
|
|
# var in/edx: (addr byte) = s->data + s->read
|
|
8d/copy-address *(esi+edx+0xc) 2/r32/edx
|
|
# var inend/ebx: (addr byte) = in + n
|
|
8b/-> *(ebp+0x10) 3/r32/ebx
|
|
8d/copy-address *(edx+ebx) 3/r32/ebx
|
|
# eax = out
|
|
8b/-> *(ebp+0xc) 0/r32/eax
|
|
# var outend/ecx: (addr byte) = out + n
|
|
8b/-> *(ebp+0x10) 1/r32/ecx
|
|
8d/copy-address *(eax+ecx) 1/r32/ecx
|
|
#
|
|
(_append-4 %eax %ecx %edx %ebx) # => eax
|
|
# s->read += n
|
|
8b/-> *(ebp+0x10) 1/r32/ecx
|
|
01/add-to *(esi+4) 1/r32/ecx
|
|
$read-from-stream:end:
|
|
# . restore registers
|
|
5e/pop-to-esi
|
|
5b/pop-to-ebx
|
|
5a/pop-to-edx
|
|
59/pop-to-ecx
|
|
58/pop-to-eax
|
|
# . epilogue
|
|
89/<- %esp 5/r32/ebp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
$read-from-stream:abort:
|
|
(abort "read-from-stream: stream empty")
|
|
# never gets here
|
|
|
|
stream-first: # s: (addr stream byte) -> result/eax: byte
|
|
# . prologue
|
|
55/push-ebp
|
|
89/<- %ebp 4/r32/esp
|
|
# . save registers
|
|
51/push-ecx
|
|
56/push-esi
|
|
# result = false
|
|
b8/copy-to-eax 0/imm32
|
|
# esi = s
|
|
8b/-> *(ebp+8) 6/r32/esi
|
|
# var idx/ecx: int = s->read
|
|
8b/-> *(esi+4) 1/r32/ecx
|
|
# if idx >= s->write return 0
|
|
3b/compare-with 1/r32/ecx *esi
|
|
7d/jump-if->= $stream-first:end/disp8
|
|
# result = s->data[idx]
|
|
8a/byte-> *(esi+ecx+0xc) 0/r32/AL
|
|
$stream-first:end:
|
|
# . restore registers
|
|
5e/pop-to-esi
|
|
59/pop-to-ecx
|
|
# . epilogue
|
|
89/<- %esp 5/r32/ebp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
stream-final: # s: (addr stream byte) -> result/eax: byte
|
|
# . prologue
|
|
55/push-ebp
|
|
89/<- %ebp 4/r32/esp
|
|
# . save registers
|
|
51/push-ecx
|
|
56/push-esi
|
|
# result = false
|
|
b8/copy-to-eax 0/imm32
|
|
# esi = s
|
|
8b/-> *(ebp+8) 6/r32/esi
|
|
# var max/ecx: int = s->write
|
|
8b/-> *esi 1/r32/ecx
|
|
# if s->read >= max return 0
|
|
39/compare-with *(esi+4) 1/r32/ecx
|
|
7d/jump-if->= $stream-final:end/disp8
|
|
# var idx/ecx: int = max - 1
|
|
49/decrement-ecx
|
|
# result = s->data[idx]
|
|
8a/byte-> *(esi+ecx+0xc) 0/r32/AL
|
|
$stream-final:end:
|
|
# . restore registers
|
|
5e/pop-to-esi
|
|
59/pop-to-ecx
|
|
# . epilogue
|
|
89/<- %esp 5/r32/ebp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
# compare all the data in two streams (ignoring the read pointer)
|
|
streams-data-equal?: # f: (addr stream byte), s: (addr array byte) -> result/eax: boolean
|
|
# pseudocode:
|
|
# awrite = a->write
|
|
# if (awrite != b->write) return false
|
|
# i = 0
|
|
# curra = a->data
|
|
# currb = b->data
|
|
# while i < awrite
|
|
# i1 = *curra
|
|
# i2 = *currb
|
|
# if (c1 != c2) return false
|
|
# i+=4, curra+=4, currb+=4
|
|
# return true
|
|
#
|
|
# registers:
|
|
# i: ecx
|
|
# awrite: edx
|
|
# curra: esi
|
|
# currb: edi
|
|
# i1: eax
|
|
# i2: ebx
|
|
#
|
|
# . prologue
|
|
55/push-ebp
|
|
89/<- %ebp 4/r32/esp
|
|
# . save registers
|
|
51/push-ecx
|
|
52/push-edx
|
|
53/push-ebx
|
|
56/push-esi
|
|
57/push-edi
|
|
# esi = a
|
|
8b/-> *(ebp+8) 6/r32/esi
|
|
# edi = b
|
|
8b/-> *(ebp+0xc) 7/r32/edi
|
|
# var awrite/edx: int = a->write
|
|
8b/-> *esi 2/r32/edx
|
|
$streams-data-equal?:sizes:
|
|
# if (awrite != b->write) return false
|
|
39/compare *edi 2/r32/edx
|
|
75/jump-if-!= $streams-data-equal?:false/disp8
|
|
# var curra/esi: (addr byte) = a->data
|
|
81 0/subop/add %esi 0xc/imm32
|
|
# var currb/edi: (addr byte) = b->data
|
|
81 0/subop/add %edi 0xc/imm32
|
|
# var i/ecx: int = 0
|
|
31/xor-with %ecx 1/r32/ecx
|
|
# var vala/eax: int
|
|
31/xor-with %eax 0/r32/eax
|
|
# var valb/ebx: int
|
|
31/xor-with %ebx 3/r32/ebx
|
|
$streams-data-equal?:loop:
|
|
{
|
|
# if (i >= awrite) return true
|
|
39/compare %ecx 2/r32/edx
|
|
7d/jump-if->= $streams-data-equal?:true/disp8
|
|
# var vala/eax: int = *curra
|
|
8a/byte-> *esi 0/r32/eax
|
|
# var valb/ebx: int = *currb
|
|
8a/byte-> *edi 3/r32/ebx
|
|
# if (vala != valb) return false
|
|
39/compare %eax 3/r32/ebx
|
|
75/jump-if-!= $streams-data-equal?:false/disp8
|
|
# i++
|
|
41/increment-ecx
|
|
# curra++
|
|
46/increment-esi
|
|
# currb++
|
|
47/increment-edi
|
|
eb/jump loop/disp8
|
|
}
|
|
$streams-data-equal?:true:
|
|
b8/copy-to-eax 1/imm32
|
|
eb/jump $streams-data-equal?:end/disp8
|
|
$streams-data-equal?:false:
|
|
b8/copy-to-eax 0/imm32
|
|
$streams-data-equal?: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/<- %esp 5/r32/ebp
|
|
5d/pop-to-ebp
|
|
c3/return
|