frame allocs (25.2): @frame on a step list's field, @alloc_ok on a statement, and on an exported function
A field declared '@frame run: fn(...)' makes every function stored in it a frame root, as a System's
tick is. @alloc_ok("why") before a statement takes that statement out of frame_allocs and makes what
it allocates declared at run time; a function holding one keeps the fence's scope depth and puts it
back at its return, so a return inside the statement cannot leave the scope open. @alloc_ok above
'export function' was lost - export parses the declaration one call down - and is now carried to it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b35409254e
commit
1e2a6bab5b
7 changed files with 75754 additions and 74774 deletions
|
|
@ -34,10 +34,13 @@ function emit_fn(d: Node) -> void {
|
|||
}
|
||||
let declared = fr_alloc_ok(d.s) # 25.1: what an @alloc_ok function makes, callees too, is declared
|
||||
if declared { emit(" %decl.in = atomicrmw add ptr @lp_fdecl, i32 1 monotonic\n") }
|
||||
let keeps = fr_has_aok(d.a) # a statement under @alloc_ok: a return inside it restores the depth
|
||||
if keeps { emit(" %decl.keep = load i32, ptr @lp_fdecl\n") }
|
||||
emit_block(d.a)
|
||||
if not (rl == "void") and not block_ends(d.a) { perr(`function '{d.s}' can reach its end without returning a {ret_ty}`) }
|
||||
if not g_term { emit(" br label %ret\n") }
|
||||
emit("ret:\n")
|
||||
if keeps { emit(" store i32 %decl.keep, ptr @lp_fdecl\n") }
|
||||
if declared { emit(" %decl.out = atomicrmw sub ptr @lp_fdecl, i32 1 monotonic\n") }
|
||||
if (rl == "void") { emit(" ret void\n") }
|
||||
else { let r = emit_bind(`load {rl}, ptr %retval`); emit(" ret "); emit(rl); emit(" "); emit(r); emit("\n") }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue