From e0bceffe08e06a30e771efe986f1f4f7c717dc95 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 26 Sep 2020 13:41:23 -0700 Subject: [PATCH] 6860 Snapshot: tile currently segfaulting. I need to back up and make it easier to debug. --- 310copy-bytes.subx | 58 +++++++++++++++++++++++++++++++ 400.mu | 1 + apps/tile/environment.mu | 8 ++--- apps/tile/gap-buffer.mu | 7 ++++ apps/tile/rpn.mu | 73 ++++++++++++++++++++++++++++++++++++++-- apps/tile/table.mu | 10 +++--- apps/tile/word.mu | 7 ++++ 7 files changed, 152 insertions(+), 12 deletions(-) diff --git a/310copy-bytes.subx b/310copy-bytes.subx index f33388a9..7a90495b 100644 --- a/310copy-bytes.subx +++ b/310copy-bytes.subx @@ -55,3 +55,61 @@ $copy-bytes:end: 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return + +stream-to-string: # in: (addr stream _), out: (addr handle array _) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + 52/push-edx + 56/push-esi + # esi = s + 8b/-> *(ebp+8) 6/r32/esi + # var len/ecx: int = s->write - s->read + 8b/-> *esi 1/r32/ecx + 2b/subtract *(esi+4) 1/r32/ecx + # allocate + (allocate-array Heap %ecx *(ebp+0xc)) + # var in/edx: (addr byte) = s->data + s->read + 8b/-> *(esi+4) 2/r32/edx + 8d/copy-address *(esi+edx+0xc) 2/r32/edx + # var dest/eax: (addr byte) = data for out + 8b/-> *(ebp+0xc) 0/r32/eax + (lookup *eax *(eax+4)) # => eax + 8d/copy-address *(eax+4) 0/r32/eax + # + (copy-bytes %edx %eax %ecx) +$stream-to-string:end: + # . restore registers + 5e/pop-to-esi + 5a/pop-to-edx + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-stream-to-string: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # setup + (clear-stream _test-input-stream) + (write _test-input-stream "abc") + # skip something + (read-byte _test-input-stream) # => eax + # var out/ecx: (handle array byte) + 68/push 0/imm32 + 68/push 0/imm32 + 89/<- %ecx 4/r32/esp + # + (stream-to-string _test-input-stream %ecx) + (lookup *ecx *(ecx+4)) # => eax + (check-strings-equal %eax "bc") + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return diff --git a/400.mu b/400.mu index b51d111f..9676f283 100644 --- a/400.mu +++ b/400.mu @@ -173,5 +173,6 @@ sig new-buffered-file out: (addr handle buffered-file) sig stream-empty? s: (addr stream _) -> result/eax: boolean sig stream-full? s: (addr stream _) -> result/eax: boolean +sig stream-to-string in: (addr stream _), out: (addr handle array _) sig copy-bytes src: (addr byte), dest: (addr byte), n: int diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu index 200aed98..4caa37f1 100644 --- a/apps/tile/environment.mu +++ b/apps/tile/environment.mu @@ -177,9 +177,7 @@ fn render _env: (addr environment) { var _program/eax: (addr program) <- lookup *program-ah var program/esi: (addr program) <- copy _program # defs - var defs-ah/edx: (addr handle function) <- get program, defs - var _defs/eax: (addr function) <- lookup *defs-ah - var defs/edx: (addr function) <- copy _defs + var defs/edx: (addr handle function) <- get program, defs # line var sandbox-ah/esi: (addr handle sandbox) <- get program, sandboxes var sandbox/eax: (addr sandbox) <- lookup *sandbox-ah @@ -194,7 +192,7 @@ fn render _env: (addr environment) { move-cursor screen, 3, cursor-col # input-row } -fn render-line screen: (addr screen), defs: (addr function), bindings: (addr table), _line: (addr line), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) { +fn render-line screen: (addr screen), defs: (addr handle function), bindings: (addr table), _line: (addr line), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) { # curr-word var line/esi: (addr line) <- copy _line var first-word-ah/eax: (addr handle word) <- get line, data @@ -222,7 +220,7 @@ fn render-line screen: (addr screen), defs: (addr function), bindings: (addr tab # - Return the farthest column written. # - If final-word is same as cursor-word, do some additional computation to set # cursor-col-a. -fn render-column screen: (addr screen), defs: (addr function), bindings: (addr table), scratch: (addr line), final-word: (addr word), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) -> right-col/ecx: int { +fn render-column screen: (addr screen), defs: (addr handle function), bindings: (addr table), scratch: (addr line), final-word: (addr word), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) -> right-col/ecx: int { var max-width/ecx: int <- copy 0 { # render stack for all but final column diff --git a/apps/tile/gap-buffer.mu b/apps/tile/gap-buffer.mu index f4f866a4..47417b96 100644 --- a/apps/tile/gap-buffer.mu +++ b/apps/tile/gap-buffer.mu @@ -27,6 +27,13 @@ fn initialize-gap-buffer-with self: (addr gap-buffer), s: (addr array byte) { } } +fn gap-buffer-to-string self: (addr gap-buffer), out: (addr handle array byte) { + var s-storage: (stream byte 0x100) + var s/ecx: (addr stream byte) <- address s-storage + emit-gap-buffer self, s + stream-to-string s, out +} + fn emit-gap-buffer _self: (addr gap-buffer), out: (addr stream byte) { var self/esi: (addr gap-buffer) <- copy _self clear-stream out diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu index 83f6e909..417bc9a0 100644 --- a/apps/tile/rpn.mu +++ b/apps/tile/rpn.mu @@ -1,4 +1,4 @@ -fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr int-stack) { +fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr int-stack) { var line/eax: (addr line) <- copy scratch var word-ah/eax: (addr handle word) <- get line, data var curr/eax: (addr word) <- lookup *word-ah @@ -46,8 +46,16 @@ fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line), push-int-stack out, a break $evaluate:process-word } - # HERE: if curr-text is a known function name, call it appropriately + # if curr-text is a known function name, call it appropriately { + var callee-h: (handle function) + var callee-ah/eax: (addr handle function) <- address callee-h + find-function defs, curr-text, callee-ah + var callee/eax: (addr function) <- lookup *callee-ah + compare callee, 0 + break-if-= + perform-call callee, out, defs + break $evaluate:process-word } # otherwise it's an int { @@ -66,6 +74,67 @@ fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line), } } +fn find-function first: (addr handle function), name: (addr stream byte), out: (addr handle function) { + var curr/esi: (addr handle function) <- copy first + $find-function:loop: { + var _f/eax: (addr function) <- lookup *curr + var f/ecx: (addr function) <- copy _f + compare f, 0 + break-if-= + var curr-name-ah/eax: (addr handle array byte) <- get f, name + var curr-name/eax: (addr array byte) <- lookup *curr-name-ah + var done?/eax: boolean <- stream-data-equal? name, curr-name + compare done?, 0 # false + { + break-if-= + copy-handle *curr, out + break $find-function:loop + } + curr <- get f, next + loop + } +} + +fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs: (addr handle function) { + var callee/ecx: (addr function) <- copy _callee + # create bindings for args + var table-storage: table + var table/esi: (addr table) <- address table-storage + initialize-table table + # + var curr-arg-ah/eax: (addr handle word) <- get callee, args + var curr-arg/eax: (addr word) <- lookup *curr-arg-ah + # + var curr-key-storage: (handle array byte) + var curr-key/edx: (addr handle array byte) <- address curr-key-storage + { + compare curr-arg, 0 + break-if-= + # create binding + word-to-string curr-arg, curr-key + { + var curr-val/eax: int <- pop-int-stack caller-stack + bind-int-in-table table, curr-key, curr-val + } + # + var next-arg-ah/edx: (addr handle word) <- get curr-arg, next + curr-arg <- lookup *next-arg-ah + loop + } + # obtain body + var body-ah/eax: (addr handle line) <- get callee, body + var body/eax: (addr line) <- lookup *body-ah + # perform call + var stack-storage: int-stack + var stack/edi: (addr int-stack) <- address stack-storage + print-string-to-real-screen "about to enter recursive eval\n" + evaluate defs, table, body, 0, stack + print-string-to-real-screen "exited recursive eval\n" + # stitch result from stack into caller + var result/eax: int <- pop-int-stack stack + push-int-stack caller-stack, result +} + # Copy of 'simplify' that just tracks the maximum stack depth needed # Doesn't actually need to simulate the stack, since every word has a predictable effect. fn max-stack-depth first-word: (addr word), final-word: (addr word) -> result/edi: int { diff --git a/apps/tile/table.mu b/apps/tile/table.mu index 94f3299a..851f891c 100644 --- a/apps/tile/table.mu +++ b/apps/tile/table.mu @@ -1,10 +1,10 @@ -fn initialize-table _self: (address table) { +fn initialize-table _self: (addr table) { var self/esi: (addr table) <- copy _self var data-ah/eax: (addr handle array bind) <- get self, data populate data-ah, 0x10 } -fn bind-int-in-table _self: (addr table), key: (addr array byte), val: int { +fn bind-int-in-table _self: (addr table), key: (addr handle array byte), val: int { var self/esi: (addr table) <- copy _self var data-ah/esi: (addr handle array bind) <- get self, data var _data/eax: (addr array bind) <- lookup *data-ah @@ -15,7 +15,7 @@ fn bind-int-in-table _self: (addr table), key: (addr array byte), val: int { } # manual test: full array of binds -fn next-empty-slot _data: (addr array bind), key: (addr array byte) -> result/eax: (offset bind) { +fn next-empty-slot _data: (addr array bind), key: (addr handle array byte) -> result/eax: (offset bind) { var data/esi: (addr array bind) <- copy _data var len/ecx: int <- length data var i/edx: int <- copy 0 @@ -36,10 +36,10 @@ fn next-empty-slot _data: (addr array bind), key: (addr array byte) -> result/ea } } -fn make-binding _self: (addr bind), key: (addr array byte), _val: int { +fn make-binding _self: (addr bind), key: (addr handle array byte), _val: int { var self/esi: (addr bind) <- copy _self var dest/eax: (addr handle array byte) <- get self, key - populate-text-with dest, key + copy-object key, dest var dest2/eax: (addr value) <- get self, value var dest3/eax: (addr int) <- get dest2, scalar-data var val/ecx: int <- copy _val diff --git a/apps/tile/word.mu b/apps/tile/word.mu index 8016a496..b425868e 100644 --- a/apps/tile/word.mu +++ b/apps/tile/word.mu @@ -225,3 +225,10 @@ fn emit-word _self: (addr word), out: (addr stream byte) { var data/eax: (addr gap-buffer) <- lookup *data-ah emit-gap-buffer data, out } + +fn word-to-string _self: (addr word), out: (addr handle array byte) { + var self/esi: (addr word) <- copy _self + var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data + var data/eax: (addr gap-buffer) <- lookup *data-ah + gap-buffer-to-string data, out +}