about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-04-22 17:13:59 -0700
committerKartik Agaram <vc@akkartik.com>2020-05-18 00:44:47 -0700
commitdcab37e1d47d0289999dedc0c8d7525865a5cdaa (patch)
tree819941bcff662c1f1d2397924751f814ab1c0d0d
parentee69e953f6fd554979034db311d02135ecf7f05b (diff)
downloadmu-dcab37e1d47d0289999dedc0c8d7525865a5cdaa.tar.gz
mu.subx: find-or-create-typeinfo
-rw-r--r--apps/mu.subx94
1 files changed, 65 insertions, 29 deletions
diff --git a/apps/mu.subx b/apps/mu.subx
index b0cec0f7..845c94ae 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -5963,70 +5963,106 @@ $container-type:end:
     5d/pop-to-ebp
     c3/return
 
-find-or-create-typeinfo:  # t: type-id -> result/eax: (handle typeinfo)
+find-or-create-typeinfo:  # t: type-id, out: (addr handle typeinfo)
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
     # . save registers
+    50/push-eax
     51/push-ecx
-    # eax = find-typeinfo(t)
-    (find-typeinfo *(ebp+8))  # => eax
+    52/push-edx
+    57/push-edi
+    # edi = out
+    8b/-> *(ebp+0xc) 7/r32/edi
+    # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry))
+    68/push 0/imm32
+    68/push 0/imm32
+    89/<- %ecx 4/r32/esp
+    # find-typeinfo(t, out)
+    (find-typeinfo *(ebp+8) %edi)
     {
-      # if (curr != 0) break
-      3d/compare-eax-and 0/imm32
+      # if (*out != 0) break
+      81 7/subop/compare *edi 0/imm32
       75/jump-if-!= break/disp8
 $find-or-create-typeinfo:create:
-      (allocate Heap *Typeinfo-size)  # => eax
-      # result->id = t
-      8b/-> *(ebp+8) 1/r32/ecx
-      89/<- *eax 1/r32/ecx  # Typeinfo-id
-      # result->fields = new table
-      # . ecx = new table
-      50/push-eax
-      (new-stream Heap 0x40 *Typeinfo-fields-row-size)  # => eax
-      89/<- %ecx 0/r32/eax
-      58/pop-to-eax
-      # . result->fields = ecx
-      89/<- *(eax+4) 1/r32/ecx  # Typeinfo-fields
-      # result->next = Program->types
+      # *out = allocate
+      (allocate Heap *Typeinfo-size %edi)
+      # var tmp/eax: (addr typeinfo) = lookup(*out)
+      (lookup *edi *(edi+4))  # => eax
+      # tmp->id = t
+      8b/-> *(ebp+8) 2/r32/edx
+      89/<- *eax 2/r32/edx  # Typeinfo-id
+      # tmp->fields = new table
+      # . fields = new table
+      (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx)
+      # . tmp->fields = fields
+      8b/-> *ecx 2/r32/edx
+      89/<- *(eax+4) 2/r32/edx  # Typeinfo-fields
+      8b/-> *(ecx+4) 2/r32/edx
+      89/<- *(eax+8) 2/r32/edx  # Typeinfo-fields
+      # tmp->next = Program->types
       8b/-> *_Program-types 1/r32/ecx
-      89/<- *(eax+0xc) 1/r32/ecx  # Typeinfo-next
-      # Program->types = result
-      89/<- *_Program-types 0/r32/eax
+      89/<- *(eax+0x10) 1/r32/ecx  # Typeinfo-next
+      8b/-> *_Program-types->payload 1/r32/ecx
+      89/<- *(eax+0x14) 1/r32/ecx  # Typeinfo-next
+      # Program->types = out
+      8b/-> *edi 1/r32/ecx
+      89/<- *_Program-types 1/r32/ecx
+      8b/-> *(edi+4) 1/r32/ecx
+      89/<- *_Program-types->payload 1/r32/ecx
     }
 $find-or-create-typeinfo:end:
     # . restore registers
+    5f/pop-to-edi
+    5a/pop-to-edx
     59/pop-to-ecx
+    58/pop-to-eax
     # . epilogue
     89/<- %esp 5/r32/ebp
     5d/pop-to-ebp
     c3/return
 
-find-typeinfo:  # t: type-id -> result/eax: (handle typeinfo)
+find-typeinfo:  # t: type-id, out: (addr handle typeinfo)
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
     # . save registers
+    50/push-eax
     51/push-ecx
+    52/push-edx
+    57/push-edi
     # ecx = t
     8b/-> *(ebp+8) 1/r32/ecx
-    # var curr/eax: (handle typeinfo) = Program->types
+    # edi = out
+    8b/-> *(ebp+0xc) 7/r32/edi
+    # *out = Program->types
     8b/-> *_Program-types 0/r32/eax
+    89/<- *edi 0/r32/eax
+    8b/-> *_Program-types->payload 0/r32/eax
+    89/<- *(edi+4) 0/r32/eax
     {
-      # if (curr == 0) break
-      3d/compare-eax-and 0/imm32
+      # if (*out == 0) break
+      81 7/subop/compare *edi 0/imm32
       74/jump-if-= break/disp8
-      # if (curr->id == t) return curr
+      # var tmp/eax: (addr typeinfo) = lookup(out)
+      (lookup *edi *(edi+4))  # => eax
+      # if (tmp->id == t) break
       39/compare *eax 1/r32/ecx  # Typeinfo-id
-      0f 84/jump-if-= $find-or-create-typeinfo:end/disp32
-      # curr = curr->next
-      8b/-> *(eax+0xc) 0/r32/eax  # Typeinfo-next
+      74/jump-if-= break/disp8
+      # *out = tmp->next
+      8b/-> *(eax+0x10) 2/r32/edx  # Typeinfo-next
+      89/<- *edi 2/r32/edx
+      8b/-> *(eax+0x14) 2/r32/edx  # Typeinfo-next
+      89/<- *(edi+4) 2/r32/edx
       #
       eb/jump loop/disp8
     }
 $find-typeinfo:end:
     # . restore registers
+    5f/pop-to-edi
+    5a/pop-to-edx
     59/pop-to-ecx
+    58/pop-to-eax
     # . epilogue
     89/<- %esp 5/r32/ebp
     5d/pop-to-ebp