diff --git a/109stream-equal.subx b/109stream-equal.subx index e7bb9487..8f6cf1bf 100644 --- a/109stream-equal.subx +++ b/109stream-equal.subx @@ -562,7 +562,7 @@ test-next-stream-line-equal-always-fails-after-Eof: c3/return # helper for later tests -check-next-stream-line-equal: +check-next-stream-line-equal: # f: (addr stream byte), s: (addr array byte), msg: (addr array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp diff --git a/306files.subx b/306files.subx index ee1a2d6b..bbeece76 100644 --- a/306files.subx +++ b/306files.subx @@ -1,7 +1,15 @@ +# Methods for constructing buffered-file objects. +# +# TODO: There are hard-coded parameters here for buffer sizes. When they +# overflow, tracking down what's going on can get hairy. +# +# HACK: buffered-file stores naked addrs. This is safe because buffered-file +# objects are opaque. But still sub-optimal; they'll be harder to reclaim when +# we get around to that. + == code open: # filename: (addr array byte), write?: boolean, out: (addr handle buffered-file) - # hard-coded parameter: file-buffer-size of created buffered-file # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -61,3 +69,85 @@ $open:end: 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return + +populate-buffered-file-containing: # contents: (addr array byte), out: (addr handle buffered-file) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + 56/push-esi + 57/push-edi + # esi = contents + 8b/-> *(ebp+8) 6/r32/esi + # var n/ecx: int = len(contents) + 8b/-> *esi 1/r32/ecx + # var stream/edi: (handle stream byte) + 68/push 0/imm32 + 68/push 0/imm32 + 89/<- %edi 4/r32/esp + # allocate stream + (new-stream Heap %ecx 1 %edi) + # var stream-addr/edi: (addr stream byte) = lookup(stream) + (lookup *edi *(edi+4)) # => eax + 89/<- %edi 0/r32/eax + # write contents to stream + (write %edi %esi) + # allocate buffered-file + (allocate Heap 0x110 *(ebp+0xc)) + # var out-addr/eax: (addr buffered-file) + 8b/-> *(ebp+0xc) 0/r32/eax + (lookup *eax *(eax+4)) # => eax + # out-addr->size = 256 bytes + c7 0/subop/copy *(eax+0xc) 0x100/imm32/file-buffer-size + # out-addr->fd = stream + 89/<- *eax 7/r32/edi +$populate-buffered-file-containing:end: + # . reclaim locals + 81 0/subop/add %esp 8/imm32 + # . restore registers + 5f/pop-to-edi + 5e/pop-to-esi + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +new-buffered-file: # out: (addr handle buffered-file) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + # var stream/ecx: (handle stream byte) + 68/push 0/imm32 + 68/push 0/imm32 + 89/<- %ecx 4/r32/esp + # allocate stream + (new-stream Heap 0x100 1 %ecx) + # var stream-addr/ecx: (addr stream byte) = lookup(stream) + (lookup *ecx *(ecx+4)) # => eax + 89/<- %ecx 0/r32/eax + # allocate buffered-file + (allocate Heap 0x110 *(ebp+8)) + # var out-addr/eax: (addr buffered-file) + 8b/-> *(ebp+8) 0/r32/eax + (lookup *eax *(eax+4)) # => eax + # out-addr->size = 256 bytes + c7 0/subop/copy *(eax+0xc) 0x100/imm32/file-buffer-size + # out-addr->fd = stream + 89/<- *eax 1/r32/ecx +$new-buffered-file:end: + # . reclaim locals + 81 0/subop/add %esp 8/imm32 + # . restore registers + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return diff --git a/400.mu b/400.mu index b1970f15..80cd63a0 100644 --- a/400.mu +++ b/400.mu @@ -46,7 +46,7 @@ sig write f: (addr stream byte), s: (addr array byte) # writing to file descrip sig stream-data-equal? f: (addr stream byte), s: (addr array byte) -> result/eax: boolean sig check-stream-equal f: (addr stream byte), s: (addr array byte), msg: (addr array byte) sig next-stream-line-equal? f: (addr stream byte), s: (addr array byte) -> result/eax: boolean -sig check-next-stream-line-equal +sig check-next-stream-line-equal f: (addr stream byte), s: (addr array byte), msg: (addr array byte) sig tailor-exit-descriptor ed: (addr exit-descriptor), nbytes: int sig stop ed: (addr exit-descriptor), value: int #sig read f: fd or (addr stream byte), s: (addr stream byte) -> num-bytes-read/eax: int @@ -158,6 +158,8 @@ sig enable-keyboard-immediate-mode sig enable-keyboard-type-mode sig read-key -> result/eax: byte sig open filename: (addr array byte), write?: boolean, out: (addr handle buffered-file) +sig populate-buffered-file-containing contents: (addr array byte), out: (addr handle buffered-file) +sig new-buffered-file out: (addr handle buffered-file) #sig size in: (addr array _) -> result/eax: int sig stream-empty? s: (addr stream _) -> result/eax: boolean diff --git a/404stream.mu b/404stream.mu index d0120046..19bbb6e5 100644 --- a/404stream.mu +++ b/404stream.mu @@ -44,3 +44,26 @@ fn test-stream-full { tmp <- stream-full? s2 check-true tmp, "F - test-stream-full?" } + +fn test-fake-input-buffered-file { + var foo: (handle buffered-file) + var foo-ah/eax: (addr handle buffered-file) <- address foo + populate-buffered-file-containing "abc", foo-ah + var foo-addr/eax: (addr buffered-file) <- lookup foo + var s: (stream byte 0x100) + var result/ecx: (addr stream byte) <- address s + read-line-buffered foo-addr, result + check-stream-equal result, "abc", "F - test-fake-input-buffered-file" +} + +fn test-fake-output-buffered-file { + var foo: (handle buffered-file) + var foo-ah/eax: (addr handle buffered-file) <- address foo + new-buffered-file foo-ah + var foo-addr/eax: (addr buffered-file) <- lookup foo + write-buffered foo-addr, "abc" + var s: (stream byte 0x100) + var result/ecx: (addr stream byte) <- address s + read-line-buffered foo-addr, result + check-stream-equal result, "abc", "F - test-fake-output-buffered-file" +} diff --git a/apps/mu b/apps/mu index 0a95526a..e44e8e4e 100755 Binary files a/apps/mu and b/apps/mu differ