about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xapps/mubin511153 -> 512725 bytes
-rw-r--r--apps/mu.subx183
-rw-r--r--apps/tile/environment.mu2
3 files changed, 173 insertions, 12 deletions
diff --git a/apps/mu b/apps/mu
index 9e2d67d5..c8cceb3c 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx
index 48473781..479a2808 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -6749,6 +6749,35 @@ test-copy-invalid-value-to-address:
     5d/pop-to-ebp
     c3/return
 
+test-copy-deref-address:
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # setup
+    (clear-stream _test-input-stream)
+    (clear-stream $_test-input-buffered-file->buffer)
+    (clear-stream _test-output-stream)
+    (clear-stream $_test-output-buffered-file->buffer)
+    #
+    (write _test-input-stream "fn foo {\n")
+    (write _test-input-stream "  var x/eax: (addr addr int) <- copy 0\n")
+    (write _test-input-stream "  var y/ecx: (addr int) <- copy *x\n")
+    (write _test-input-stream "}\n")
+    # convert
+    (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
+    (flush _test-output-buffered-file)
+#?     # dump _test-error-stream {{{
+#?     (write 2 "^")
+#?     (write-stream 2 _test-error-stream)
+#?     (write 2 "$\n")
+#?     (rewind-stream _test-error-stream)
+#?     # }}}
+    # not bothering checking output
+    (check-next-stream-line-equal _test-error-stream  ""  "F - test-copy-deref-address: error message")
+    # . epilogue
+    5d/pop-to-ebp
+    c3/return
+
 test-copy-to-non-register:
     # . prologue
     55/push-ebp
@@ -7111,6 +7140,36 @@ test-copy-to-invalid-value-to-address:
     5d/pop-to-ebp
     c3/return
 
+test-copy-to-deref-address:
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # setup
+    (clear-stream _test-input-stream)
+    (clear-stream $_test-input-buffered-file->buffer)
+    (clear-stream _test-output-stream)
+    (clear-stream $_test-output-buffered-file->buffer)
+    #
+    (write _test-input-stream "fn foo {\n")
+    (write _test-input-stream "  var x/eax: (addr int) <- copy 0\n")
+    (write _test-input-stream "  var y/ecx: (addr addr int) <- copy 0\n")
+    (write _test-input-stream "  copy-to *y, x\n")
+    (write _test-input-stream "}\n")
+    # convert
+    (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
+    (flush _test-output-buffered-file)
+#?     # dump _test-error-stream {{{
+#?     (write 2 "^")
+#?     (write-stream 2 _test-error-stream)
+#?     (write 2 "$\n")
+#?     (rewind-stream _test-error-stream)
+#?     # }}}
+    # not bothering checking output
+    (check-next-stream-line-equal _test-error-stream  ""  "F - test-copy-to-deref-address: error message")
+    # . epilogue
+    5d/pop-to-ebp
+    c3/return
+
 test-copy-to-non-scalar:
     # . prologue
     55/push-ebp
@@ -7415,6 +7474,36 @@ test-compare-address:
     5d/pop-to-ebp
     c3/return
 
+test-compare-deref-address:
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # setup
+    (clear-stream _test-input-stream)
+    (clear-stream $_test-input-buffered-file->buffer)
+    (clear-stream _test-output-stream)
+    (clear-stream $_test-output-buffered-file->buffer)
+    #
+    (write _test-input-stream "fn foo {\n")
+    (write _test-input-stream "  var x/eax: (addr int) <- copy 0\n")
+    (write _test-input-stream "  var y/ecx: (addr addr int) <- copy 0\n")
+    (write _test-input-stream "  compare *y, x\n")
+    (write _test-input-stream "}\n")
+    # convert
+    (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
+    (flush _test-output-buffered-file)
+#?     # dump _test-error-stream {{{
+#?     (write 2 "^")
+#?     (write-stream 2 _test-error-stream)
+#?     (write 2 "$\n")
+#?     (rewind-stream _test-error-stream)
+#?     # }}}
+    # not bothering checking output
+    (check-next-stream-line-equal _test-error-stream  ""  "F - test-compare-deref-address: error message")
+    # . epilogue
+    5d/pop-to-ebp
+    c3/return
+
 test-compare-two-vars-in-memory:
     # . prologue
     55/push-ebp
@@ -17199,17 +17288,29 @@ $check-mu-numberlike-arg:check-literal:
     # if t is an int, return
     (is-simple-mu-type? %esi 0)  # literal => eax
     3d/compare-eax-and 0/imm32/false
-    75/jump-if-!= $check-mu-numberlike-arg:end/disp8
+    0f 85/jump-if-!= $check-mu-numberlike-arg:end/disp32
 $check-mu-numberlike-arg:check-addr:
-    # if t is an addr and v is dereferenced, return
+    # if t is an addr and v is dereferenced, return whether t->payload is an addr
     {
       (is-mu-addr-type? %esi)  # => eax
       3d/compare-eax-and 0/imm32/false
       74/jump-if-= break/disp8
       8b/-> *(ebp+8) 0/r32/eax
-      8b/-> *(eax+0x10) 0/r32/eax
+      8b/-> *(eax+0x10) 0/r32/eax  # Stmt-var-is-deref
       3d/compare-eax-and 0/imm32/false
-      75/jump-if-!= $check-mu-numberlike-arg:end/disp8
+      {
+        74/jump-if-= break/disp8
+        (lookup *(esi+0xc) *(esi+0x10))  # Type-tree-right Type-tree-right => eax
+        # if t->right is null, t = t->left
+        81 7/subop/compare *(eax+0xc) 0/imm32  # Type-tree-right
+        {
+          75/jump-if-!= break/disp8
+          (lookup *(eax+4) *(eax+8))  # Type-tree-left Type-tree-left => eax
+        }
+        (is-mu-addr-type? %eax)  # => eax
+        3d/compare-eax-and 0/imm32/false
+        74/jump-if-= $check-mu-numberlike-arg:end/disp8
+      }
     }
 $check-mu-numberlike-arg:output-checks:
     (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18))
@@ -17339,6 +17440,20 @@ $check-mu-copy-stmt:types:
     (lookup *esi *(esi+4))  # Stmt-var-value Stmt-var-value => eax
     (lookup *(eax+8) *(eax+0xc))  # Var-type Var-type => eax
     89/<- %ecx 0/r32/eax
+    # if (inout->is-deref?) inout-type = inout-type->payload
+    8b/-> *(esi+0x10) 0/r32/eax  # Stmt-var-is-deref
+    3d/compare-eax-and 0/imm32/false
+    {
+      74/jump-if-= break/disp8
+      (lookup *(ecx+0xc) *(ecx+0x10))  # Type-tree-right Type-tree-right => eax
+      # if inout-type->right is null, t = inout-type->left
+      81 7/subop/compare *(eax+0xc) 0/imm32  # Type-tree-right
+      {
+        75/jump-if-!= break/disp8
+        (lookup *(eax+4) *(eax+8))  # Type-tree-left Type-tree-left => eax
+      }
+      89/<- %ecx 0/r32/eax
+    }
     # if output not in register, abort
     (lookup *edi *(edi+4))  # Stmt-var-value Stmt-var-value => eax
     (lookup *(eax+0x18) *(eax+0x1c))  # Var-register Var-register => eax
@@ -17462,6 +17577,7 @@ check-mu-copy-to-stmt:  # stmt: (addr stmt), fn: (addr function), err: (addr buf
     50/push-eax
     51/push-ecx
     52/push-edx
+    53/push-ebx
     56/push-esi
     57/push-edi
     # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8)
@@ -17519,11 +17635,26 @@ $check-mu-copy-to-stmt:types:
     (size-of %eax)  # => eax
     3d/compare-eax-and 4/imm32
     0f 8f/jump-if-> $check-mu-copy-to-stmt:error-src-too-large/disp32
-    # var dest-type/eax: (addr type-tree) = dest->value->type
+    # var dest-type/ebx: (addr type-tree) = dest->value->type
     (lookup *edi *(edi+4))  # Stmt-var-value Stmt-var-value => eax
     (lookup *(eax+8) *(eax+0xc))  # Var-type Var-type => eax
+    89/<- %ebx 0/r32/eax
+    # if (dest->is-deref?) dest-type = dest-type->payload
+    8b/-> *(edi+0x10) 0/r32/eax  # Stmt-var-is-deref
+    3d/compare-eax-and 0/imm32/false
+    {
+      74/jump-if-= break/disp8
+      (lookup *(ebx+0xc) *(ebx+0x10))  # Type-tree-right Type-tree-right => eax
+      # if dest-type->right is null, dest-type = dest-type->left
+      81 7/subop/compare *(eax+0xc) 0/imm32  # Type-tree-right
+      {
+        75/jump-if-!= break/disp8
+        (lookup *(eax+4) *(eax+8))  # Type-tree-left Type-tree-left => eax
+      }
+      89/<- %ebx 0/r32/eax
+    }
     # if (src-type == dest-type) return
-    (type-match? %eax %ecx %edx)  # => eax
+    (type-match? %ebx %ecx %edx)  # => eax
     3d/compare-eax-and 0/imm32
     0f 85/jump-if-!= $check-mu-copy-to-stmt:end/disp32
     # if dest is an addr and src is 0, return
@@ -17548,6 +17679,7 @@ $check-mu-copy-to-stmt:end:
     # . restore registers
     5f/pop-to-edi
     5e/pop-to-esi
+    5b/pop-to-ebx
     5a/pop-to-edx
     59/pop-to-ecx
     58/pop-to-eax
@@ -17608,6 +17740,7 @@ check-mu-compare-stmt:  # stmt: (addr stmt), fn: (addr function), err: (addr buf
     50/push-eax
     51/push-ecx
     52/push-edx
+    53/push-ebx
     56/push-esi
     57/push-edi
     # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8)
@@ -17669,23 +17802,50 @@ $check-mu-compare-stmt:types:
     (lookup *esi *(esi+4))  # Stmt-var-value Stmt-var-value => eax
     (lookup *(eax+8) *(eax+0xc))  # Var-type Var-type => eax
     89/<- %ecx 0/r32/eax
+    # if (right->is-deref?) right-type = right-type->payload
+    8b/-> *(esi+0x10) 0/r32/eax  # Stmt-var-is-deref
+    3d/compare-eax-and 0/imm32/false
+    {
+      74/jump-if-= break/disp8
+      (lookup *(ecx+0xc) *(ecx+0x10))  # Type-tree-right Type-tree-right => eax
+      # if right-type->right is null, right-type = right-type->left
+      81 7/subop/compare *(eax+0xc) 0/imm32  # Type-tree-right
+      {
+        75/jump-if-!= break/disp8
+        (lookup *(eax+4) *(eax+8))  # Type-tree-left Type-tree-left => eax
+      }
+      89/<- %ecx 0/r32/eax
+    }
     # if right is not a scalar, abort
     (lookup *esi *(esi+4))  # Stmt-var-value Stmt-var-value => eax
     (size-of %eax)  # => eax
     3d/compare-eax-and 4/imm32
     0f 8f/jump-if-> $check-mu-compare-stmt:error-right-too-large/disp32
-    # var left-type/eax: (addr type-tree) = left->value->type
-    (lookup *edi *(edi+4))  # Stmt-var-value Stmt-var-value => eax
-    (lookup *(eax+8) *(eax+0xc))  # Var-type Var-type => eax
     # if left is not a scalar, abort
     (lookup *edi *(edi+4))  # Stmt-var-value Stmt-var-value => eax
     (size-of %eax)  # => eax
     3d/compare-eax-and 4/imm32
     0f 8f/jump-if-> $check-mu-compare-stmt:error-left-too-large/disp32
-    # if (left-type == right-type) return
+    # var left-type/ebx: (addr type-tree) = left->value->type
     (lookup *edi *(edi+4))  # Stmt-var-value Stmt-var-value => eax
     (lookup *(eax+8) *(eax+0xc))  # Var-type Var-type => eax
-    (type-match? %eax %ecx %edx)  # => eax
+    89/<- %ebx 0/r32/eax
+    # if (left->is-deref?) left-type = left-type->payload
+    8b/-> *(edi+0x10) 0/r32/eax  # Stmt-var-is-deref
+    3d/compare-eax-and 0/imm32/false
+    {
+      74/jump-if-= break/disp8
+      (lookup *(ebx+0xc) *(ebx+0x10))  # Type-tree-right Type-tree-right => eax
+      # if left-type->right is null, left-type = left-type->left
+      81 7/subop/compare *(eax+0xc) 0/imm32  # Type-tree-right
+      {
+        75/jump-if-!= break/disp8
+        (lookup *(eax+4) *(eax+8))  # Type-tree-left Type-tree-left => eax
+      }
+      89/<- %ebx 0/r32/eax
+    }
+    # if (left-type == right-type) return
+    (type-match? %ebx %ecx %edx)  # => eax
     3d/compare-eax-and 0/imm32
     0f 85/jump-if-!= $check-mu-compare-stmt:end/disp32
     # if left is an addr and right is 0, return
@@ -17710,6 +17870,7 @@ $check-mu-compare-stmt:end:
     # . restore registers
     5f/pop-to-edi
     5e/pop-to-esi
+    5b/pop-to-ebx
     5a/pop-to-edx
     59/pop-to-ecx
     58/pop-to-eax
diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu
index 3105ed89..a4b7580f 100644
--- a/apps/tile/environment.mu
+++ b/apps/tile/environment.mu
@@ -814,7 +814,7 @@ fn bound-function? w: (addr word), functions-ah: (addr handle function) -> _/ebx
 }
 
 fn arg-exists? _f-ah: (addr handle function), arg: (addr word) -> _/ebx: boolean {
-  var f-ah/eax: (addr handle function) <- copy *_f-ah
+  var f-ah/eax: (addr handle function) <- copy _f-ah
   var f/eax: (addr function) <- lookup *f-ah
   var args-ah/eax: (addr handle word) <- get f, args
   var result/ebx: boolean <- word-exists? args-ah, arg