about summary refs log tree commit diff stats
path: root/linux/306files.subx
blob: 028c290ac0c799c2df18d7e7c0da8789bc149a5c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
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