about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--313index-bounds-check.subx3
-rw-r--r--linux/313index-bounds-check.subx8
-rwxr-xr-xlinux/mubin603681 -> 604512 bytes
-rw-r--r--linux/mu.subx48
-rw-r--r--mu_instructions6
5 files changed, 51 insertions, 14 deletions
diff --git a/313index-bounds-check.subx b/313index-bounds-check.subx
index 6185e969..de9642fd 100644
--- a/313index-bounds-check.subx
+++ b/313index-bounds-check.subx
@@ -57,3 +57,6 @@ __check-mu-array-bounds:overflow:
       eb/jump loop/disp8
     }
     # never gets here
+
+__mu-abort-null-get-base-address:
+    (abort "null address in 'get'")
diff --git a/linux/313index-bounds-check.subx b/linux/313index-bounds-check.subx
index 615935b3..1d7384c1 100644
--- a/linux/313index-bounds-check.subx
+++ b/linux/313index-bounds-check.subx
@@ -84,3 +84,11 @@ __check-mu-array-bounds:overflow:
 #            "81 0/subop/add %esp 4/imm32"  # drop function name
 #            # actually save the index addr in reg
 #            "8d/copy-address *(" rega "+" regi "<<" log2(size-of(T)) "+4) " reg "/r32"
+
+__mu-abort-null-get-base-address:
+    (write-buffered Stderr "null address in 'get'\n")
+    (flush Stderr)
+    # exit(1)
+    bb/copy-to-ebx 1/imm32
+    e8/call syscall_exit/disp32
+    # never gets here
diff --git a/linux/mu b/linux/mu
index a8d00898..2b2b8476 100755
--- a/linux/mu
+++ b/linux/mu
Binary files differdiff --git a/linux/mu.subx b/linux/mu.subx
index 2326f4b1..4ccf4854 100644
--- a/linux/mu.subx
+++ b/linux/mu.subx
@@ -6879,16 +6879,20 @@ test-convert-function-and-type-definition:
     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-function-and-type-definition/6")
     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000000/r32"  "F - test-convert-function-and-type-definition/7")
     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-function-and-type-definition/8")
-    (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + 0x00000000) 0x00000001/r32"  "F - test-convert-function-and-type-definition/9")
-    (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + 0x00000004) 0x00000001/r32"  "F - test-convert-function-and-type-definition/11")
-    (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13")
-    (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14")
-    (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-and-type-definition/15")
-    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-and-type-definition/16")
-    (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-and-type-definition/17")
-    (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-and-type-definition/18")
-    (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-and-type-definition/19")
-    (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-and-type-definition/20")
+    (check-next-stream-line-equal _test-output-stream "    81 7/subop/compare %eax 0/imm32"  "F - test-convert-function-and-type-definition/9")
+    (check-next-stream-line-equal _test-output-stream "    0f 84/jump-if-= __mu-abort-null-get-base-address/disp32"  "F - test-convert-function-and-type-definition/10")
+    (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + 0x00000000) 0x00000001/r32"  "F - test-convert-function-and-type-definition/11")
+    (check-next-stream-line-equal _test-output-stream "    81 7/subop/compare %eax 0/imm32"  "F - test-convert-function-and-type-definition/12")
+    (check-next-stream-line-equal _test-output-stream "    0f 84/jump-if-= __mu-abort-null-get-base-address/disp32"  "F - test-convert-function-and-type-definition/13")
+    (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + 0x00000004) 0x00000001/r32"  "F - test-convert-function-and-type-definition/14")
+    (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/15")
+    (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/16")
+    (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-and-type-definition/17")
+    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-and-type-definition/18")
+    (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-and-type-definition/19")
+    (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-and-type-definition/20")
+    (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-and-type-definition/21")
+    (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-and-type-definition/22")
     # . epilogue
     89/<- %esp 5/r32/ebp
     5d/pop-to-ebp
@@ -29754,17 +29758,35 @@ translate-mu-get-stmt:  # out: (addr buffered-file), stmt: (addr stmt)
     50/push-eax
     51/push-ecx
     52/push-edx
-    #
-    (emit-indent *(ebp+8) *Curr-block-depth)
-    (write-buffered *(ebp+8) "8d/copy-address ")
     # ecx = stmt
     8b/-> *(ebp+0xc) 1/r32/ecx
+    # var base/eax: (addr var) = stmt->inouts->value
+    (lookup *(ecx+0xc) *(ecx+0x10))  # Stmt1-inouts Stmt1-inouts => eax
+    (lookup *eax *(eax+4))  # Stmt-var-value Stmt-var-value => eax
+    # if base is in a register, insert a null check
+    81 7/subop/compare *(eax+0x18) 0/imm32  # Var-register
+    {
+      0f 84/jump-if-= break/disp32
+$translate-mu-get-stmt:emit-null-check-for-register-input:
+      # emit "81 7/subop/compare %" base->register " 0/imm32\n"
+      (emit-indent *(ebp+8) *Curr-block-depth)
+      (write-buffered *(ebp+8) "81 7/subop/compare %")
+      (lookup *(eax+0x18) *(eax+0x1c))  # Var-register Var-register => eax
+      (write-buffered *(ebp+8) %eax)
+      (write-buffered *(ebp+8) " 0/imm32\n")
+      #
+      (emit-indent *(ebp+8) *Curr-block-depth)
+      (write-buffered *(ebp+8) "0f 84/jump-if-= __mu-abort-null-get-base-address/disp32\n")
+    }
     # var offset/edx: int = get offset of stmt
     (mu-get-offset %ecx)  # => eax
     89/<- %edx 0/r32/eax
     # var base/eax: (addr var) = stmt->inouts->value
     (lookup *(ecx+0xc) *(ecx+0x10))  # Stmt1-inouts Stmt1-inouts => eax
     (lookup *eax *(eax+4))  # Stmt-var-value Stmt-var-value => eax
+    #
+    (emit-indent *(ebp+8) *Curr-block-depth)
+    (write-buffered *(ebp+8) "8d/copy-address ")
     # if base is in a register
     81 7/subop/compare *(eax+0x18) 0/imm32  # Var-register
     {
diff --git a/mu_instructions b/mu_instructions
index 945528ad..ea58866e 100644
--- a/mu_instructions
+++ b/mu_instructions
@@ -374,10 +374,14 @@ If a record (product) type T was defined to have elements a, b, c, ... of
 types T_a, T_b, T_c, ..., then accessing one of those elements f of type T_f:
 
 var/reg: (addr T_f) <- get var2/reg2: (addr T), f
-  => "8d/copy-address *(" reg2 "+" offset(f) ") " reg "/r32"
+  => "81 7/subop/compare %" reg2 " 0/imm32"
+     "0f 84/jump-if-= __mu-abort-null-get-base-address/disp32"
+     "8d/copy-address *(" reg2 "+" offset(f) ") " reg "/r32"
 var/reg: (addr T_f) <- get var2: T, f
   => "8d/copy-address *(ebp+" var2.stack-offset "+" offset(f) ") " reg "/r32"
 
+When the base is an address we perform a null check.
+
 # Allocating memory
 
 allocate in: (addr handle T)