6145 - 'address' operator
This could be a can of worms, but I think I have a set of checks that will keep use of addresses type-safe.
This commit is contained in:
parent
6db056110b
commit
114641e2c8
74
apps/mu.subx
74
apps/mu.subx
|
@ -2258,6 +2258,52 @@ test-convert-function-with-local-array-var-in-mem:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
c3/return
|
||||||
|
|
||||||
|
test-convert-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 a: int\n")
|
||||||
|
(write _test-input-stream " var b/eax: (addr int) <- address a\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 "foo:" "F - test-convert-address/0")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4")
|
||||||
|
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11")
|
||||||
|
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15")
|
||||||
|
(check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16")
|
||||||
|
# . epilogue
|
||||||
|
89/<- %esp 5/r32/ebp
|
||||||
|
5d/pop-to-ebp
|
||||||
|
c3/return
|
||||||
|
|
||||||
test-convert-length-of-array:
|
test-convert-length-of-array:
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
|
@ -8769,6 +8815,19 @@ _Primitive-copy-lit-to-mem:
|
||||||
2/imm32/imm32-is-first-inout
|
2/imm32/imm32-is-first-inout
|
||||||
0/imm32/no-disp32
|
0/imm32/no-disp32
|
||||||
1/imm32/output-is-write-only
|
1/imm32/output-is-write-only
|
||||||
|
_Primitive-address/imm32/next
|
||||||
|
# - address
|
||||||
|
_Primitive-address:
|
||||||
|
# var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32
|
||||||
|
"address"/imm32/name
|
||||||
|
Single-int-var-in-mem/imm32/inouts
|
||||||
|
Single-addr-var-in-some-register/imm32/outputs
|
||||||
|
"8d/copy-address"/imm32/subx-name
|
||||||
|
1/imm32/rm32-is-first-inout
|
||||||
|
3/imm32/r32-is-first-output
|
||||||
|
0/imm32/no-imm32
|
||||||
|
0/imm32/no-disp32
|
||||||
|
1/imm32/output-is-write-only
|
||||||
_Primitive-compare-mem-with-reg/imm32/next
|
_Primitive-compare-mem-with-reg/imm32/next
|
||||||
# - compare
|
# - compare
|
||||||
_Primitive-compare-mem-with-reg:
|
_Primitive-compare-mem-with-reg:
|
||||||
|
@ -9366,6 +9425,10 @@ Single-int-var-in-some-register:
|
||||||
Int-var-in-some-register/imm32
|
Int-var-in-some-register/imm32
|
||||||
0/imm32/next
|
0/imm32/next
|
||||||
|
|
||||||
|
Single-addr-var-in-some-register:
|
||||||
|
Addr-var-in-some-register/imm32
|
||||||
|
0/imm32/next
|
||||||
|
|
||||||
Int-var-in-some-register:
|
Int-var-in-some-register:
|
||||||
"arg1"/imm32/name
|
"arg1"/imm32/name
|
||||||
Type-int/imm32
|
Type-int/imm32
|
||||||
|
@ -9373,6 +9436,13 @@ Int-var-in-some-register:
|
||||||
0/imm32/no-stack-offset
|
0/imm32/no-stack-offset
|
||||||
Any-register/imm32
|
Any-register/imm32
|
||||||
|
|
||||||
|
Addr-var-in-some-register:
|
||||||
|
"arg1"/imm32/name
|
||||||
|
Type-addr/imm32
|
||||||
|
1/imm32/some-block-depth
|
||||||
|
0/imm32/no-stack-offset
|
||||||
|
Any-register/imm32
|
||||||
|
|
||||||
Single-int-var-in-eax:
|
Single-int-var-in-eax:
|
||||||
Int-var-in-eax/imm32
|
Int-var-in-eax/imm32
|
||||||
0/imm32/next
|
0/imm32/next
|
||||||
|
@ -9458,6 +9528,10 @@ Type-literal:
|
||||||
0/imm32/left/literal
|
0/imm32/left/literal
|
||||||
0/imm32/right/null
|
0/imm32/right/null
|
||||||
|
|
||||||
|
Type-addr:
|
||||||
|
2/imm32/left/addr
|
||||||
|
0/imm32/right/null
|
||||||
|
|
||||||
== code
|
== code
|
||||||
emit-subx-primitive: # out: (addr buffered-file), stmt: (handle stmt), primitive: (handle function)
|
emit-subx-primitive: # out: (addr buffered-file), stmt: (handle stmt), primitive: (handle function)
|
||||||
# . prologue
|
# . prologue
|
||||||
|
|
|
@ -205,6 +205,11 @@ loop-if-addr<= label {.name="loop-if-addr<=", .inouts=[label],
|
||||||
loop-if-addr>= {.name="loop-if-addr>=", .subx-name="0f 83/jump-if-addr>= loop/disp32"}
|
loop-if-addr>= {.name="loop-if-addr>=", .subx-name="0f 83/jump-if-addr>= loop/disp32"}
|
||||||
loop-if-addr>= label {.name="loop-if-addr>=", .inouts=[label], .subx-name="0f 83/jump-if-addr>=", .disp32=inouts[0] ":loop"}
|
loop-if-addr>= label {.name="loop-if-addr>=", .inouts=[label], .subx-name="0f 83/jump-if-addr>=", .disp32=inouts[0] ":loop"}
|
||||||
|
|
||||||
|
Address operations
|
||||||
|
|
||||||
|
var/reg: (addr T) <- address var: T
|
||||||
|
{.name="address", .inouts=[var], .outputs=[reg], .subx-name="8d/copy-address", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
|
||||||
|
|
||||||
Array operations
|
Array operations
|
||||||
|
|
||||||
var/reg <- length arr/reg2: (addr array T)
|
var/reg <- length arr/reg2: (addr array T)
|
||||||
|
|
|
@ -195,6 +195,10 @@ Similarly, conditional loops:
|
||||||
loop-if-addr>=
|
loop-if-addr>=
|
||||||
loop-if-addr>= label
|
loop-if-addr>= label
|
||||||
|
|
||||||
|
## Address operations
|
||||||
|
|
||||||
|
var/reg: (addr T) <- address var: T # var must be in mem (on the stack)
|
||||||
|
|
||||||
## Array operations
|
## Array operations
|
||||||
|
|
||||||
var/reg: int <- length arr/reg: (addr array T)
|
var/reg: int <- length arr/reg: (addr array T)
|
||||||
|
@ -203,8 +207,8 @@ Similarly, conditional loops:
|
||||||
var/reg: (addr T) <- index arr/reg: (addr array T), n
|
var/reg: (addr T) <- index arr/reg: (addr array T), n
|
||||||
var/reg: (addr T) <- index arr: (array T sz), n
|
var/reg: (addr T) <- index arr: (array T sz), n
|
||||||
|
|
||||||
var/reg: (offset T) <- compute-offset arr: (addr array T), idx/reg: int # arr can be in reg or mem
|
var/reg: (offset T) <- compute-offset arr: (addr array T), idx/reg: int # arr can be in reg or mem
|
||||||
var/reg: (offset T) <- compute-offset arr: (addr array T), idx: int # arr can be in reg or mem
|
var/reg: (offset T) <- compute-offset arr: (addr array T), idx: int # arr can be in reg or mem
|
||||||
var/reg: (addr T) <- index arr/reg: (addr array T), idx/reg: (offset T)
|
var/reg: (addr T) <- index arr/reg: (addr array T), idx/reg: (offset T)
|
||||||
|
|
||||||
## User-defined types
|
## User-defined types
|
||||||
|
|
Loading…
Reference in New Issue