This plugin performs typed closure conversion: it turns functions that capture free variables into self-contained closures - a pair of a code pointer and an environment holding the captured values - so that every function becomes closed and can be lifted to the top level. Later it lowers these typed closures to untyped (code-ptr, env-ptr) pairs and turns exception-like basic blocks into setjmp/longjmp. The transformation is a pipeline of Phases (see below); the C++ implementation lives in mim::plug::clos.
mim::plug::clos::phase::Clos2SJLJ lowers exception-like basic-block closures to these operations.
An opaque pointer to a C jmp_buf; its size in bytes is provided by the runtime.
Allocates a fresh jmp_buf and yields a pointer to it.
Saves the current execution context into the jmp_buf (like C setjmp). Yields 0 on the initial call and the non-zero tag passed to clos.longjmp when jumped to.
Restores the context saved in the jmp_buf, resuming right after the corresponding clos.setjmp and making it yield the given tag (like C longjmp).
A family of mim::Annotations wrapped around a Lam (or a use of it) that classifies how it is used. mim::plug::clos::phase::ClosConvPrep introduces these so that mim::plug::clos::phase::ClosConv sees a canonical program and can treat each kind of continuation appropriately:
The clos phases are the only consumers; until the last of them has run, dropping one of these annotations loses the classification and closure conversion picks the wrong treatment.
The opt pipeline runs these in the order below, reusing clos.branch_clos as a repeated cleanup after the passes that introduce branch closures.
Prepares for closure conversion by wrapping operands with the clos.anno annotations above and eta-expanding branches and continuations (mim::plug::clos::phase::ClosConvPrep).
The actual typed closure conversion (mim::plug::clos::phase::ClosConv).
Flattens a branch over closure literals back into a direct branch over the underlying Lams, inlining their environments (mim::plug::clos::phase::BranchClosElim).
Escape analysis; marks closures whose environment escapes with clos.anno.esc (mim::plug::clos::phase::LowerTypedClosPrep).
Lowers exception-like basic-block closures to setjmp/longjmp (mim::plug::clos::phase::Clos2SJLJ).
Lowers typed closures to untyped (code-ptr, env-ptr) pairs, boxing or unboxing the environment (mim::plug::clos::phase::LowerTypedClos).