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 marker 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 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.attr markers 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.attr.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).