about summary refs log tree commit diff stats
path: root/072slice.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-01-19 17:36:50 -0800
committerKartik Agaram <vc@akkartik.com>2020-01-19 17:37:11 -0800
commit622f1be099f434f89819876d1931f80c1a3e47e7 (patch)
treeed1f70c33ddbb5f64c89b2a63c617cfeb51130ef /072slice.subx
parent6070c23e5e1c60d3bb169e43bddfa59b1d322427 (diff)
downloadmu-622f1be099f434f89819876d1931f80c1a3e47e7.tar.gz
5898 - strengthen slice-empty? check
Anytime we create a slice, the first check tends to be whether it's empty.
If we handle ill-formed slices here where start > end, that provides a
measure of safety.

In the Mu translator (mu.subx) we often check for a trailing ':' or ','
and decrement slice->end to ignore it. But that could conceivably yield
ill-formed slices if the slice started out empty. Now we make sure we never
operate on such ill-formed slices.
Diffstat (limited to '072slice.subx')
-rw-r--r--072slice.subx43
1 files changed, 36 insertions, 7 deletions
diff --git a/072slice.subx b/072slice.subx
index 65db1c16..f7299074 100644
--- a/072slice.subx
+++ b/072slice.subx
@@ -14,13 +14,13 @@ slice-empty?:  # s : (addr slice) -> eax : boolean
     51/push-ecx
     # ecx = s
     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(ebp+8) to ecx
-    # if (s->start == s->end) return true
+    # if (s->start >= s->end) return true
     # . eax = s->start
     8b/copy                         0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # copy *ecx to eax
-    # . compare eax and s->end
-    39/compare                      1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/eax   4/disp8         .                 # compare eax and *(ecx+4)
+    # . if (eax >= s->end) return true
+    3b/compare                      1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/eax   4/disp8         .                 # compare eax with *(ecx+4)
     b8/copy-to-eax  1/imm32/true
-    74/jump-if-=  $slice-empty?:end/disp8
+    73/jump-if-addr>=  $slice-empty?:end/disp8
     b8/copy-to-eax  0/imm32/false
 $slice-empty?:end:
     # . restore registers
@@ -63,9 +63,9 @@ test-slice-empty-false:
     # . prologue
     55/push-ebp
     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # var slice/ecx : slice = {34, 23}
-    68/push  23/imm32/end
-    68/push  34/imm32/start
+    # var slice/ecx : slice = {32, 34}
+    68/push  34/imm32/end
+    68/push  32/imm32/start
     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
     # slice-empty?(slice)
     # . . push args
@@ -88,6 +88,35 @@ test-slice-empty-false:
     5d/pop-to-ebp
     c3/return
 
+test-slice-empty-if-start-greater-than-end:
+    # . prologue
+    55/push-ebp
+    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+    # var slice/ecx : slice = {34, 32}
+    68/push  32/imm32/end
+    68/push  34/imm32/start
+    89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+    # slice-empty?(slice)
+    # . . push args
+    51/push-ecx
+    # . . call
+    e8/call  slice-empty?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+    # check-ints-equal(eax, 1, msg)
+    # . . push args
+    68/push  "F - test-slice-empty-if-start-greater-than-end"/imm32
+    68/push  1/imm32
+    50/push-eax
+    # . . call
+    e8/call  check-ints-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
 slice-equal?:  # s : (addr slice), p : (addr array byte) -> eax : boolean
     # pseudocode:
     #   if (p == 0) return (s == 0)