void runtime·deferreturn(uintptr arg0) { Defer *d; byte *argp; FuncVal *fn; d = g->defer; if(d == nil) return; argp = (byte*)&arg0; if(d->argp != argp) return; // Moving arguments around. // Do not allow preemption here, because the garbage collector // won't know the form of the arguments until the jmpdefer can // flip the PC over to fn. m->locks++; runtime·memmove(argp, d->args, d->siz); fn = d->fn; g->defer = d->link; freedefer(d); m->locks--; if(m->locks == 0 && g->preempt) g->stackguard0 = StackPreempt; runtime·jmpdefer(fn, argp); }
// Run all deferred functions for the current goroutine. static void rundefer(void) { Defer *d; while((d = g->defer) != nil) { g->defer = d->link; reflect·call(d->fn, (byte*)d->args, d->siz); freedefer(d); } }
void runtime·deferreturn(uintptr arg0) { Defer *d; byte *argp; FuncVal *fn; d = g->defer; if(d == nil) return; argp = (byte*)&arg0; if(d->argp != argp) return; runtime·memmove(argp, d->args, d->siz); fn = d->fn; popdefer(); freedefer(d); runtime·jmpdefer(fn, argp); }
// The implementation of the predeclared function panic. void runtime·panic(Eface e) { Defer *d; Panic *p; void *pc, *argp; p = runtime·mal(sizeof *p); p->arg = e; p->link = g->panic; p->stackbase = g->stackbase; g->panic = p; for(;;) { d = g->defer; if(d == nil) break; // take defer off list in case of recursive panic g->defer = d->link; g->ispanic = true; // rock for newstack, where reflect.newstackcall ends up argp = d->argp; pc = d->pc; runtime·newstackcall(d->fn, (byte*)d->args, d->siz); freedefer(d); if(p->recovered) { g->panic = p->link; if(g->panic == nil) // must be done with signal g->sig = 0; runtime·free(p); // Pass information about recovering frame to recovery. g->sigcode0 = (uintptr)argp; g->sigcode1 = (uintptr)pc; runtime·mcall(recovery); runtime·throw("recovery failed"); // mcall should not return } } // ran out of deferred calls - old-school panic now runtime·startpanic(); printpanics(g->panic); runtime·dopanic(0); }