# Methods for constructing buffered-file objects. # # 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 # TODO: hard-coded parameter 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