about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-10-29 16:22:40 -0700
committerKartik Agaram <vc@akkartik.com>2018-10-29 16:34:47 -0700
commitf94442fe2da11e3938f01b3065546b36313ef342 (patch)
treeda514f0b7ea1319e9887169d3e675e65eee99b17
parent3d94e2db0e809530f277220c5d5fea6996ee47d6 (diff)
downloadmu-f94442fe2da11e3938f01b3065546b36313ef342.tar.gz
4736
We'll use a common stream data structure for input and output streams.

Having separate types makes more sense in a more high-level language, where
we have type checking and where functions for handling the different types
are more concise. But in machine code the sweet spot is more toward fewer
types.
-rw-r--r--subx/056write.subx91
-rwxr-xr-xsubx/apps/crenshaw2-1bin3334 -> 3345 bytes
-rwxr-xr-xsubx/apps/factorialbin3351 -> 3362 bytes
3 files changed, 48 insertions, 43 deletions
diff --git a/subx/056write.subx b/subx/056write.subx
index ba131e42..7ac0dfd0 100644
--- a/subx/056write.subx
+++ b/subx/056write.subx
@@ -1,26 +1,29 @@
-# write: like _write, but also support in-memory output streams (`ostream`s)
-# in addition to file descriptors.
+# write: like _write, but also support in-memory streams in addition to file
+# descriptors.
 #
 # Our first dependency-injected and testable primitive. We can pass it either
-# a file descriptor or an address to an ostream. If a file descriptor is
-# passed in, we _write to it using the right syscall. If a 'fake file descriptor'
-# or ostream is passed in, we append to the ostream. This lets us redirect
-# output in tests and check it later.
+# a file descriptor or an address to a stream. If a file descriptor is passed
+# in, we _write to it using the right syscall. If a 'fake file descriptor' or
+# stream is passed in, we append to the stream. This lets us redirect output
+# in tests and check it later.
 #
 # We assume our data segment will never begin at an address shorter than
 # 0x08000000, so any smaller arguments are assumed to be real file descriptors.
 #
-# An ostream looks like this:
+# A stream looks like this:
+#   read: int  # index at which to read next
 #   write: int  # index at which writes go
 #   data: (array byte)  # prefixed by length as usual
 
 == data
 
-# In-memory ostream for tests to write() to.
-# Also illustrates the layout of ostreams.
-Test-ostream:
+# In-memory stream for tests to write() to.
+# Also illustrates the layout of streams.
+Test-stream:
   # current write index
   00 00 00 00
+  # current read index
+  00 00 00 00
   # length (= 8)
   08 00 00 00
   # data
@@ -39,7 +42,7 @@ Test-ostream:
   b8/copy-to-EAX  1/imm32
   cd/syscall  0x80/imm8
 
-write:  # f : fd or (address ostream), s : (address array byte) -> <void>
+write:  # f : fd or (address stream), s : (address array byte) -> <void>
   # prolog
   55/push-EBP
   89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
@@ -55,7 +58,7 @@ write:  # f : fd or (address ostream), s : (address array byte) -> <void>
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
   eb/jump  $write:end/disp8
 $write:fake:
-  # otherwise, treat 'f' as an ostream to append to
+  # otherwise, treat 'f' as an stream to append to
   # save registers
   50/push-EAX
   51/push-ECX
@@ -66,15 +69,15 @@ $write:fake:
   # EDX = f.write
   8b/copy                         0/mod/indirect  1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # copy *ECX to EDX
   # EBX = f.length
-  8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           3/r32/EBX   4/disp8         .                 # copy *(ECX+4) to EBX
+  8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           3/r32/EBX   8/disp8         .                 # copy *(ECX+8) to EBX
   # EAX = _append(&f.data[f.write], &f.data[f.length], s)
     # push s
   ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0xc/disp8       .                 # push *(EBP+12)
     # push &f.data[f.length]
-  8d/copy-address                 1/mod/*+disp8   4/rm32/sib    1/base/ECX  3/index/EBX   .           3/r32/EBX   8/disp8         .                 # copy ECX+EBX+8 to EBX
+  8d/copy-address                 1/mod/*+disp8   4/rm32/sib    1/base/ECX  3/index/EBX   .           3/r32/EBX   0xc/disp8       .                 # copy ECX+EBX+12 to EBX
   53/push-EBX
     # push &f.data[f.write]
-  8d/copy-address                 1/mod/*+disp8   4/rm32/sib    1/base/ECX  2/index/EDX   .           3/r32/EBX   8/disp8         .                 # copy ECX+EBX+8 to EBX
+  8d/copy-address                 1/mod/*+disp8   4/rm32/sib    1/base/ECX  2/index/EDX   .           3/r32/EBX   0xc/disp8       .                 # copy ECX+EDX+12 to EBX
   53/push-EBX
     # call
   e8/call  _append/disp32
@@ -93,7 +96,7 @@ $write:end:
   5d/pop-to-EBP
   c3/return
 
-clear-ostream:  # f : (address ostream)
+clear-stream:  # f : (address stream)
   # prolog
   55/push-EBP
   89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
@@ -103,24 +106,26 @@ clear-ostream:  # f : (address ostream)
   # EAX = f
   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none              0/r32/EAX   8/disp8         .                 # copy *(EBP+8) to EAX
   # ECX = f.length
-  8b/copy                         1/mod/*+disp8   0/rm32/EAX    .           .             .           1/r32/ECX   4/disp8         .                 # copy *(EAX+4) to ECX
+  8b/copy                         1/mod/*+disp8   0/rm32/EAX    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EAX+8) to ECX
   # ECX = &f.data[f.length]
-  8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   8/disp8         .                 # copy EAX+ECX+8 to ECX
+  8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   0xc/disp8       .                 # copy EAX+ECX+12 to ECX
   # f.write = 0
   c7/copy                         0/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # copy to *EAX
+  # f.read = 0
+  c7/copy                         1/mod/*+disp8   0/rm32/EAX    .           .             .           .           4/disp8         0/imm32           # copy to *(EAX+4)
   # EAX = f.data
-  81          0/subop/add         3/mod/direct    0/rm32/EAX    .           .             .           .           .               8/imm32           # add to EAX
+  81          0/subop/add         3/mod/direct    0/rm32/EAX    .           .             .           .           .               0xc/imm32         # add to EAX
   # while (true)
-$clear-ostream:loop:
+$clear-stream:loop:
   # if EAX >= ECX break
   39/compare                      3/mod/direct    0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # compare EAX with ECX
-  7d/jump-if-greater-or-equal  $clear-ostream:end/disp8
+  7d/jump-if-greater-or-equal  $clear-stream:end/disp8
   # *EAX = 0
   c7/copy                         0/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # copy to *EAX
   # EAX += 4
   81          0/subop/add         3/mod/direct    0/rm32/EAX    .           .             .           .           .               4/imm32           # add to EAX
-  eb/jump  $clear-ostream:loop/disp8
-$clear-ostream:end:
+  eb/jump  $clear-stream:loop/disp8
+$clear-stream:end:
   # restore registers
   59/pop-to-ECX
   58/pop-to-EAX
@@ -130,28 +135,28 @@ $clear-ostream:end:
   c3/return
 
 test-write-single:
-  # clear-ostream(Test-ostream)
+  # clear-stream(Test-stream)
     # push args
-  68/push  Test-ostream/imm32
+  68/push  Test-stream/imm32
     # call
-  e8/call  clear-ostream/disp32
+  e8/call  clear-stream/disp32
     # discard args
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-  # write(Test-ostream, "Ab")
+  # write(Test-stream, "Ab")
     # push args
   68/push  "Ab"/imm32
-  68/push  Test-ostream/imm32
+  68/push  Test-stream/imm32
     # call
   e8/call  write/disp32
     # discard args
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-  # check-ints-equal(*Test-ostream.data, 41/A 62/b 00 00, msg)
+  # check-ints-equal(*Test-stream.data, 41/A 62/b 00 00, msg)
     # push args
   68/push  "F - test-write-single"/imm32
   68/push  0x006241/imm32/Ab
-    # push *Test-ostream.data
-  b8/copy-to-EAX  Test-ostream/imm32
-  ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           8/disp8         .                 # push *(EAX+8)
+    # push *Test-stream.data
+  b8/copy-to-EAX  Test-stream/imm32
+  ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           0xc/disp8       .                 # push *(EAX+12)
     # call
   e8/call  check-ints-equal/disp32
     # discard args
@@ -160,36 +165,36 @@ test-write-single:
   c3/return
 
 test-write-appends:
-  # clear-ostream(Test-ostream)
+  # clear-stream(Test-stream)
     # push args
-  68/push  Test-ostream/imm32
+  68/push  Test-stream/imm32
     # call
-  e8/call  clear-ostream/disp32
+  e8/call  clear-stream/disp32
     # discard args
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-  # write(Test-ostream, "C")
+  # write(Test-stream, "C")
     # push args
   68/push  "C"/imm32
-  68/push  Test-ostream/imm32
+  68/push  Test-stream/imm32
     # call
   e8/call  write/disp32
     # discard args
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-  # write(Test-ostream, "D")
+  # write(Test-stream, "D")
     # push args
   68/push  "D"/imm32
-  68/push  Test-ostream/imm32
+  68/push  Test-stream/imm32
     # call
   e8/call  write/disp32
     # discard args
   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-  # check-ints-equal(*Test-ostream.data, 43/C 44/D 00 00, msg)
+  # check-ints-equal(*Test-stream.data, 43/C 44/D 00 00, msg)
     # push args
   68/push  "F - test-write-appends"/imm32
   68/push  0x00004443/imm32/C-D
-    # push *Test-ostream.data
-  b8/copy-to-EAX  Test-ostream/imm32
-  ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           8/disp8         .                 # push *(EAX+8)
+    # push *Test-stream.data
+  b8/copy-to-EAX  Test-stream/imm32
+  ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           0xc/disp8       .                 # push *(EAX+12)
     # call
   e8/call  check-ints-equal/disp32
     # discard args
diff --git a/subx/apps/crenshaw2-1 b/subx/apps/crenshaw2-1
index 9ac09053..2c20170f 100755
--- a/subx/apps/crenshaw2-1
+++ b/subx/apps/crenshaw2-1
Binary files differdiff --git a/subx/apps/factorial b/subx/apps/factorial
index 540b6c82..4a36fa37 100755
--- a/subx/apps/factorial
+++ b/subx/apps/factorial
Binary files differ