defer fn myFn do (
defer (thingA;)
blahBlah()
defer (thingB;);
ret blahBlah() // executes thingB -> thingA -> returns
)
the function must be marked as defer, which just reserves the :dret slot as the first local variable added, before any inputs (offset=0)
After the first defer statement, all ret that would be compiled (outside of the first defer block) compile a DRET instead of a RET. This jumps to the :dret local instead of returning.
There is a DEF <U2 literal> instr which:
stores the address after the instr+lit at the :dret slot (it's location is offset=0).
jumps to after the defer section (value in literal).
The first defer block ends in a regular RET. Later defer blocks end by jumping to the previous defer block. Therefore defers are executed in FILO order at runtime.
defers are illegal inside of a blk (no looping allowed with defer).
For the TyDb, defer blocks are not allowed to either accept or return any types on the stack (that is the job of the function).
Defer is fairly trivial to implement actually.
defer
, which just reserves the:dret
slot as the first local variable added, before any inputs (offset=0)defer
statement, allret
that would be compiled (outside of the firstdefer
block) compile aDRET
instead of aRET
. This jumps to the:dret
local instead of returning.DEF <U2 literal>
instr which::dret
slot (it's location is offset=0).RET
. Later defer blocks end by jumping to the previous defer block. Therefore defers are executed in FILO order at runtime.blk
(no looping allowed with defer).For the TyDb, defer blocks are not allowed to either accept or return any types on the stack (that is the job of the function).