about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--mu.arc10
-rw-r--r--mu.arc.t18
2 files changed, 23 insertions, 5 deletions
diff --git a/mu.arc b/mu.arc
index 768485b5..56152fbd 100644
--- a/mu.arc
+++ b/mu.arc
@@ -46,6 +46,7 @@
               integer-boolean-pair (obj size 2  record t  elems '(integer boolean))
               integer-boolean-pair-address (obj size 1  address t  elem 'integer-boolean-pair)
               integer-boolean-pair-array (obj array t  elem 'integer-boolean-pair)
+              integer-boolean-pair-array-address (obj size 1  address t  elem 'integer-boolean-pair-array)
               integer-integer-pair (obj size 2  record t  elems '(integer integer))
               integer-point-pair (obj size 2  record t  elems '(integer integer-integer-pair))
               ; tagged-values are the foundation of dynamic types
@@ -132,7 +133,8 @@
   operand.1)  ; assume type is always first bit of metadata, and it's always present
 
 (def typeinfo (operand)
-  (types* ty.operand))
+  (or (types* ty.operand)
+      (err "unknown type @operand")))
 
 (def sz (operand)
   (trace "sz" operand)
@@ -201,12 +203,10 @@
               (= (memory* dest) src)))))))
 
 (def array-len (operand)
-;?   (prn operand)
-;?   (prn (memory* 1000))
   (if typeinfo.operand!array
         (m `(,v.operand integer))
       (and typeinfo.operand!address (pos 'deref metadata.operand))
-        (array-len (m operand) typeinfo.operand!elem)
+        (m `(,v.operand integer-address ,@(cut operand 2)))
       :else
         (err "can't take len of non-array @operand")))
 
@@ -437,7 +437,7 @@
                   (sizeof (m arg.0))
                 len
                   (let base arg.0
-                    (if typeinfo.base!array
+                    (if (or typeinfo.base!array typeinfo.base!address)
                       array-len.base
                       -1))
 
diff --git a/mu.arc.t b/mu.arc.t
index 9d0fe7fb..5da21e91 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -538,6 +538,24 @@
 (if (~iso memory* (obj 1 2  2 23 3 nil  4 24 5 t  6 2))
   (prn "F - 'len' accesses length of array"))
 
+(reset)
+(new-trace "len-array-indirect")
+(add-fns
+  '((main
+      ((1 integer) <- copy (2 literal))
+      ((2 integer) <- copy (23 literal))
+      ((3 boolean) <- copy (nil literal))
+      ((4 integer) <- copy (24 literal))
+      ((5 boolean) <- copy (t literal))
+      ((6 integer-address) <- copy (1 literal))
+      ((7 integer) <- len (6 integer-boolean-pair-array-address deref)))))
+;? (set dump-trace*)
+;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "cvt0" "cvt1")))
+(run 'main)
+;? (prn memory*)
+(if (~iso memory* (obj 1 2  2 23 3 nil  4 24 5 t  6 1  7 2))
+  (prn "F - 'len' accesses length of array address"))
+
 ; 'sizeof' is a helper to determine the amount of memory required by a type.
 
 (reset)