void Resolver::resolveBody(Compiler& compiler, Module& module, gc<Expr> body, int& maxLocals, int& numClosures) { // Make a fake procedure so we can track closures. ResolvedProcedure procedure; maxLocals = resolve(compiler, module, NULL, &procedure, true, NULL, NULL, NULL, body); numClosures = procedure.closures().count(); }
void ExprCompiler::compileClosures(gc<SourcePos> pos, ResolvedProcedure& procedure) { // When a procedure is created, it needs to capture references to any // variables declared outside of itself that it (or one of its nested // procedures) accesses. We do this by compiling a series of // pseudo-instructions. Each one describes which upvar from the outer // procedure should be captured. for (int i = 0; i < procedure.closures().count(); i++) { int index = procedure.closures()[i]; if (index == -1) { // This closure is a new one in this function so there's nothing to // Capture. So just add a "do nothing" pseudo-op. write(pos, OP_GET_UPVAR, 0, 0, 0); } else { // Capture the upvar from the outer scope. write(pos, OP_GET_UPVAR, index, 0, 1); } } }