diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-01-19 17:36:50 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-01-19 17:37:11 -0800 |
commit | 622f1be099f434f89819876d1931f80c1a3e47e7 (patch) | |
tree | ed1f70c33ddbb5f64c89b2a63c617cfeb51130ef /072slice.subx | |
parent | 6070c23e5e1c60d3bb169e43bddfa59b1d322427 (diff) | |
download | mu-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.subx | 43 |
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) |