6160 - plan for safe heap access
Based on apps/handle.subx (commit 4894), but we're able to simplify it further now that we know more about the situation we find ourselves in. 6 instructions, zero pushes or pops. Before I can start building this, I need to reorganize my use of handles. They're going to be fat pointers so we can't store them in registers anymore.
This commit is contained in:
parent
fa80585024
commit
0ef7f1d2d6
|
@ -157,7 +157,7 @@ Address operations
|
|||
var/reg: (addr T) <- address var: T
|
||||
=> "8d/copy-address *(ebp+" var.stack-offset ") " reg "/r32"
|
||||
|
||||
Array operations
|
||||
Array operations (TODO: bounds-checking)
|
||||
|
||||
var/reg <- length arr/reg2: (addr array T)
|
||||
=> "8b/-> *" reg2 " " reg "/r32"
|
||||
|
@ -187,4 +187,33 @@ var/reg: (addr T_f) <- get var2/reg2: (addr F), f
|
|||
var/reg: (addr T_f) <- get var2: (addr F), f
|
||||
=> "8d/copy-address *(ebp+" var2.stack-offset "+" offset(f) ") " reg "/r32"
|
||||
|
||||
vim:ft=mu:nowrap:tw&
|
||||
Handles for safe access to the heap
|
||||
|
||||
copy-handle-to dest: (handle T), src: (handle T)
|
||||
=> "50/push-eax"
|
||||
"8b/-> *(ebp+" src.stack-offset ") 0/r32/eax"
|
||||
"89/<- *(ebp+" dest.stack-offset ") 0/r32/eax"
|
||||
"8b/-> *(ebp+" src.stack-offset+4 ") 0/r32/eax"
|
||||
"89/<- *(ebp+" dest.stack-offset+4 ") 0/r32/eax"
|
||||
"58/pop-to-eax"
|
||||
|
||||
copy-handle-to *dest/reg: (addr handle T), src: (handle T)
|
||||
=> "50/push-eax"
|
||||
"8b/-> *(ebp+" src.stack-offset ") 0/r32/eax"
|
||||
"89/<- *" reg " 0/r32/eax"
|
||||
"8b/-> *(ebp+" src.stack-offset+4 ") 0/r32/eax"
|
||||
"89/<- *(" reg "+4) 0/r32/eax"
|
||||
"58/pop-to-eax"
|
||||
|
||||
out/reg: (addr T) <- lookup in: (handle T)
|
||||
=> # payload_allocid = in->address->allocid
|
||||
"8b/-> *(epb+" (in.stack-offset+4) ") " reg "/r32"
|
||||
"8b/-> *" reg " " reg "/r32"
|
||||
# if (payload_allocid != handle->allocid) abort
|
||||
"39/compare *(ebp+" in.stack-offset ") " reg "/r32"
|
||||
"0f 85/jump-if-!= $lookup:abort/disp32"
|
||||
# return payload
|
||||
"8b/-> *(epb+" (in.stack-offset+4) ") " reg "/r32"
|
||||
"81 0/subop/add %" reg " 4/imm32" # skip payload->allocid
|
||||
|
||||
vim:ft=mu:nowrap:textwidth=0
|
||||
|
|
24
mu_summary
24
mu_summary
|
@ -216,3 +216,27 @@ Similarly, conditional loops:
|
|||
var/reg: (addr T_f) <- get var/reg: (addr T), f
|
||||
where record (product) type T has elements a, b, c, ... of types T_a, T_b, T_c, ...
|
||||
var/reg: (addr T_f) <- get var: (addr T), f
|
||||
|
||||
## Handles for safe access to the heap
|
||||
|
||||
Say we created a handle like this on the stack (it can't be in a register)
|
||||
var x: (handle T)
|
||||
allocate Heap, T, x
|
||||
|
||||
You can copy handles to another variable on the stack like this:
|
||||
var y: (handle T)
|
||||
copy-handle-to y, x
|
||||
|
||||
You can also save handles inside other user-defined types like this:
|
||||
var y/reg: (addr handle T_f) <- get var: (addr T), f
|
||||
copy-handle-to *y, x
|
||||
|
||||
Or this:
|
||||
var y/reg: (addr handle T) <- index arr: (addr array handle T), n
|
||||
copy-handle-to *y, x
|
||||
|
||||
Handles can be converted into addresses like this:
|
||||
var y/reg: (addr T) <- lookup x
|
||||
|
||||
It's illegal to continue to use this addr after a function that reclaims heap
|
||||
memory. You have to repeat the lookup.
|
||||
|
|
Loading…
Reference in New Issue