diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-03-15 16:44:55 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-03-15 16:44:55 -0700 |
commit | f559236bdf9103c5f88d8dfc098f3afe3de64e4a (patch) | |
tree | d2a3d5df9ebe9b4ff9143a751a5bbca0b21d296a | |
parent | e2a0b4407305cdcd35ea8ff727c7080872050ff7 (diff) | |
download | mu-f559236bdf9103c5f88d8dfc098f3afe3de64e4a.tar.gz |
6152 - fix regression in factorial.mu
I had to amend commit 6148 three times yesterday as I kept finding bugs by inspection. And yet I stubbornly thought I didn't need a test.
-rwxr-xr-x | apps/mu | bin | 207490 -> 210747 bytes | |||
-rw-r--r-- | apps/mu.subx | 102 |
2 files changed, 100 insertions, 2 deletions
diff --git a/apps/mu b/apps/mu index d76a48d8..17916ee9 100755 --- a/apps/mu +++ b/apps/mu Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx index fa967d63..f78f6bbb 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -2865,6 +2865,68 @@ test-convert-function-call-with-arg-of-user-defined-type: 5d/pop-to-ebp c3/return +test-convert-function-call-with-arg-of-user-defined-type-register-indirect: + # . 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 f {\n") + (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") + (write _test-input-stream " foo *a\n") + (write _test-input-stream "}\n") + (write _test-input-stream "fn foo x: t {\n") + (write _test-input-stream "}\n") + (write _test-input-stream "type t {\n") + (write _test-input-stream " x: int\n") + (write _test-input-stream " y: int\n") + (write _test-input-stream "}\n") + # convert + (convert-mu _test-input-buffered-file _test-output-buffered-file) + (flush _test-output-buffered-file) +#? # dump _test-output-stream {{{ +#? (write 2 "^") +#? (write-stream 2 _test-output-stream) +#? (write 2 "$\n") +#? (rewind-stream _test-output-stream) +#? # }}} + # check output + (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3") + (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + # var a + (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + # foo a + (check-next-stream-line-equal _test-output-stream " (foo *(eax+0x00000000) *(eax+0x00000004))" "F - test-convert-function-call-with-arg-of-user-defined-type/8") + # + (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9") + (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13") + (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19") + (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21") + (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + # we don't have special support for call-by-reference; just explicitly create # a new variable with the address of the arg test-convert-function-call-with-arg-of-user-defined-type-by-reference: @@ -6542,6 +6604,41 @@ $size-of:end: 5d/pop-to-ebp c3/return +size-of-deref: # v: (handle var) -> result/eax: int + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + # var t/ecx: (handle tree type-id) = v->type + 8b/-> *(ebp+8) 1/r32/ecx + 8b/-> *(ecx+4) 1/r32/ecx # Var-type + # TODO: assert(t is an addr) + 8b/-> *(ecx+4) 1/r32/ecx # Tree-right + # if is-mu-array?(t) return size-of-array(t) + { + (is-mu-array? %ecx) # => eax + 3d/compare-eax-and 0/imm32/false + 74/jump-if-= break/disp8 + (size-of-array %ecx) # => eax + eb/jump $size-of:end/disp8 + } + # if (t->left >= *Max-type-id) t = t->left + { + 8b/-> *Max-type-id 0/r32/eax + 39/compare *ecx 0/r32/eax # Tree-left + 72/jump-if-addr< break/disp8 + 8b/-> *ecx 1/r32/ecx # Tree-left + } + (size-of-type-id *ecx) # Atom-left => eax +$size-of-deref:end: + # . restore registers + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + is-mu-array?: # t: (handle tree type-id) -> result/eax: boolean # . prologue 55/push-ebp @@ -10021,8 +10118,9 @@ emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (hand 56/push-esi # esi = v 8b/-> *(ebp+0xc) 6/r32/esi - # var size/ecx: int = size-of(v) - (size-of %esi) # => eax + # var size/ecx: int = size-of-deref(v) + (size-of-deref %esi) # => eax + 89/<- %ecx 0/r32/eax # TODO: assert size is a multiple of 4 # var i/eax: int = 0 b8/copy-to-eax 0/imm32 |