about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--313index-bounds-check.subx2
-rw-r--r--baremetal/313index-bounds-check.subx36
2 files changed, 37 insertions, 1 deletions
diff --git a/313index-bounds-check.subx b/313index-bounds-check.subx
index 1349e3d4..615935b3 100644
--- a/313index-bounds-check.subx
+++ b/313index-bounds-check.subx
@@ -37,6 +37,7 @@ __check-mu-array-bounds:  # index: int, elem-size: int, arr-size: int, function-
     # exit(1)
     bb/copy-to-ebx 1/imm32
     e8/call syscall_exit/disp32
+    # never gets here
 $__check-mu-array-bounds:end:
     # . restore registers
     5a/pop-to-edx
@@ -58,6 +59,7 @@ __check-mu-array-bounds:overflow:
     # exit(1)
     bb/copy-to-ebx 1/imm32
     e8/call syscall_exit/disp32
+    # never gets here
 
 # potential alternative
 
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
+    }