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
|
||||
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:
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
|
@ -8769,6 +8815,19 @@ _Primitive-copy-lit-to-mem:
|
|||
2/imm32/imm32-is-first-inout
|
||||
0/imm32/no-disp32
|
||||
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
|
||||
# - compare
|
||||
_Primitive-compare-mem-with-reg:
|
||||
|
@ -9366,6 +9425,10 @@ Single-int-var-in-some-register:
|
|||
Int-var-in-some-register/imm32
|
||||
0/imm32/next
|
||||
|
||||
Single-addr-var-in-some-register:
|
||||
Addr-var-in-some-register/imm32
|
||||
0/imm32/next
|
||||
|
||||
Int-var-in-some-register:
|
||||
"arg1"/imm32/name
|
||||
Type-int/imm32
|
||||
|
@ -9373,6 +9436,13 @@ Int-var-in-some-register:
|
|||
0/imm32/no-stack-offset
|
||||
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:
|
||||
Int-var-in-eax/imm32
|
||||
0/imm32/next
|
||||
|
@ -9458,6 +9528,10 @@ Type-literal:
|
|||
0/imm32/left/literal
|
||||
0/imm32/right/null
|
||||
|
||||
Type-addr:
|
||||
2/imm32/left/addr
|
||||
0/imm32/right/null
|
||||
|
||||
== code
|
||||
emit-subx-primitive: # out: (addr buffered-file), stmt: (handle stmt), primitive: (handle function)
|
||||
# . 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>= 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
|
||||
|
||||
var/reg <- length arr/reg2: (addr array T)
|
||||
|
|
|
@ -195,6 +195,10 @@ Similarly, conditional loops:
|
|||
loop-if-addr>=
|
||||
loop-if-addr>= label
|
||||
|
||||
## Address operations
|
||||
|
||||
var/reg: (addr T) <- address var: T # var must be in mem (on the stack)
|
||||
|
||||
## Array operations
|
||||
|
||||
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: (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: 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: (addr T) <- index arr/reg: (addr array T), idx/reg: (offset T)
|
||||
|
||||
## User-defined types
|
||||
|
|
Loading…
Reference in New Issue