diff options
Diffstat (limited to 'linux/306files.subx')
-rw-r--r-- | linux/306files.subx | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/linux/306files.subx b/linux/306files.subx new file mode 100644 index 00000000..028c290a --- /dev/null +++ b/linux/306files.subx @@ -0,0 +1,169 @@ +# 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) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + # var new-fd/ecx: fd + (open-fd *(ebp+8) *(ebp+0xc)) # => eax + 89/<- %ecx 0/r32/eax + # if fd < 0 return + 3d/compare-eax-with 0/imm32 + 7c/jump-if-< $open:end/disp8 + # allocate a buffered-file + (allocate Heap 0x1010 *(ebp+0x10)) # file-buffer-size + 16 for other fields + # var out-addr/eax: (addr buffered-file) + 8b/-> *(ebp+0x10) 0/r32/eax + (lookup *eax *(eax+4)) # => eax + # out-addr->size = 4KB + c7 0/subop/copy *(eax+0xc) 0x1000/imm32/file-buffer-size # Stream-size + 4 for fd + # out-addr->fd = fd + 89/<- *eax 1/r32/ecx +$open:end: + # . restore registers + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +open-fd: # filename: (addr array byte), write?: boolean -> result/eax: fd + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + 52/push-edx + 53/push-ebx + 56/push-esi + # ecx = filename + 8b/-> *(ebp+8) 1/r32/ecx + # var size/edx: int = filename->length + 1 for the trailing null character + 8b/-> *ecx 2/r32/edx + 42/increment-edx + # var s/esi: (stream size) + 29/subtract-from %esp 2/r32/edx + 52/push-edx # size + 68/push 0/imm32/read + 68/push 0/imm32/write + 89/<- %esi 4/r32/esp + # copy filename and a final null character + (clear-stream %esi) + (write %esi %ecx) + # spill edx + 52/push-edx + # var fd/eax: fd = open(filename) + 8d/copy-address *(esi+0xc) 3/r32/ebx + 8b/-> *(ebp+0xc) 1/r32/ecx/flags + ba/copy-to-edx 0x180/imm32/permissions + e8/call syscall_open/disp32 + # restore edx + 5a/pop-to-edx +$open-fd:end: + # . reclaim locals + 01/add-to %esp 2/r32/edx + 81 0/subop/add %esp 0xc/imm32 + # . restore registers + 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 + +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 |