about summary refs log tree commit diff stats
path: root/baremetal/313index-bounds-check.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2021-01-15 21:36:25 -0800
committerKartik Agaram <vc@akkartik.com>2021-01-16 09:06:01 -0800
commita8dd0d40942485a65995ac59c3f1bc4a6727e236 (patch)
treebbf447b6a5c44799dcbb6f78e698f9371d2172dc /baremetal/313index-bounds-check.subx
parent0d246473c5270a0f13a2706a1f0204d375f62d30 (diff)
downloadmu-a8dd0d40942485a65995ac59c3f1bc4a6727e236.tar.gz
7525
Bring back runtime support for bounds-checking arrays. Again, the error
messages kinda suck, because I can't yet print integers. But something
is better than nothing.
Diffstat (limited to 'baremetal/313index-bounds-check.subx')
-rw-r--r--baremetal/313index-bounds-check.subx36
1 files changed, 35 insertions, 1 deletions
diff --git a/baremetal/313index-bounds-check.subx b/baremetal/313index-bounds-check.subx
index 4624a2ac..422d1d84 100644
--- a/baremetal/313index-bounds-check.subx
+++ b/baremetal/313index-bounds-check.subx
@@ -1,4 +1,5 @@
-# TODO: bring this back
+# Helper to check an array's bounds, and to abort if they're violated.
+# Really only intended to be called from code generated by mu.subx.
 
 == code
 
@@ -6,8 +7,41 @@ __check-mu-array-bounds:  # index: int, elem-size: int, arr-size: int, function-
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
+    # . save registers
+    50/push-eax
+    51/push-ecx
+    52/push-edx
+    # . not bothering saving ebx; it's only clobbered if we're going to abort
+    # ecx = arr-size
+    8b/-> *(ebp+0x10) 1/r32/ecx
+    # var overflow/edx: int = 0
+    ba/copy-to-edx 0/imm32
+    # var offset/eax: int = index * elem-size
+    8b/-> *(ebp+8) 0/r32/eax
+    f7 4/subop/multiply-eax-with *(ebp+0xc)
+    # check for overflow
+    81 7/subop/compare %edx 0/imm32
+    0f 85/jump-if-!= __check-mu-array-bounds:overflow/disp32
+    # check bounds
+    39/compare %eax 1/r32/ecx
+    0f 82/jump-if-unsigned< $__check-mu-array-bounds:end/disp32  # negative index should always abort
+    # abort if necessary
+    (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "offset too large for array" 3)  # 3=cyan
+    {
+      eb/jump loop/disp8
+    }
 $__check-mu-array-bounds:end:
+    # . restore registers
+    5a/pop-to-edx
+    59/pop-to-ecx
+    58/pop-to-eax
     # . epilogue
     89/<- %esp 5/r32/ebp
     5d/pop-to-ebp
     c3/return
+
+__check-mu-array-bounds:overflow:
+    (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "offset to array overflowed 32 bits" 3)  # 3=cyan
+    {
+      eb/jump loop/disp8
+    }