diff options
-rw-r--r-- | mu.arc | 24 | ||||
-rw-r--r-- | mu.arc.t | 18 |
2 files changed, 31 insertions, 11 deletions
diff --git a/mu.arc b/mu.arc index 366895bd..47d50cea 100644 --- a/mu.arc +++ b/mu.arc @@ -203,21 +203,19 @@ (err "can't take len of non-array @operand"))) (def array-ref-addr (operand idx) -;? (prn "aref addr: @operand @idx") (assert typeinfo.operand!array) - (assert (< -1 idx (array-len operand))) + (unless (< -1 idx (array-len operand)) + (die "aref-addr: out of bounds index @idx for @operand of size @array-len.operand")) (withs (elem typeinfo.operand!elem offset (+ 1 (* idx sz.elem))) (+ v.operand offset))) (def array-ref (operand idx) -;? (prn "aref: @operand @idx") (assert typeinfo.operand!array) - (assert (< -1 idx (array-len operand))) -;? (prn "aref2: @operand @idx") + (unless (< -1 idx (array-len operand)) + (die "aref: out of bounds index @idx for @operand of size @array-len.operand")) (withs (elem typeinfo.operand!elem offset (+ 1 (* idx sz.elem))) -;? (prn "aref3: @elem @v.operand @offset") (m `(,(+ v.operand offset) ,elem)))) ; data structure: routine @@ -269,9 +267,10 @@ (let (oargs _ _) (parse-instr ((body routine 1) (pc routine 1))) oargs)) -(= running-routines* (queue)) -(= completed-routines* (queue)) -(= routine* nil) +(on-init + (= running-routines* (queue)) + (= completed-routines* (queue)) + (= routine* nil)) (def run fn-names (ret result 0 @@ -287,6 +286,11 @@ (enq routine* running-routines*) (enq-limit routine* completed-routines*))))) +(def die (msg) + (= rep.routine*!error msg) + (= rep.routine*!stack-trace rep.routine*!call-stack) + (wipe rep.routine*!call-stack)) + ($:require "charterm/main.rkt") (def run-for-time-slice (time-slice) @@ -493,6 +497,8 @@ (err "no such op @op")) (continue)) ) + (when rep.routine*!error + (return time-slice)) ; opcode generated some value, stored in 'tmp' ; copy to output args ;? (prn "store: " tmp " " oarg) diff --git a/mu.arc.t b/mu.arc.t index 52327ef2..8fbbf7ad 100644 --- a/mu.arc.t +++ b/mu.arc.t @@ -519,8 +519,6 @@ (if (~iso memory* (obj 1 2 2 23 3 nil 4 24 5 t 6 1 7 4)) (prn "F - 'index-address' returns addresses of indices of arrays")) -; todo: test that out-of-bounds access throws an error - ; Array values know their length. Record lengths are saved in the types table. (reset) @@ -1340,6 +1338,22 @@ ; Eventually we want the right stack-management primitives to build delimited ; continuations in mu. +; Routines can throw errors. +(reset) +(new-trace "array-bounds-check") +(add-fns + '((main + ((1 integer) <- copy (2 literal)) + ((2 integer) <- copy (23 literal)) + ((3 integer) <- copy (24 literal)) + ((4 integer) <- index (1 integer-array) (2 literal))))) +;? (set dump-trace*) +(run 'main) +;? (prn memory*) +(let last-routine (deq completed-routines*) + (if (no rep.last-routine!error) + (prn "F - 'index' throws an error if out of bounds"))) + ; --- (reset) |