diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 31393cf8a1..da09cedd01 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -553,77 +553,73 @@ funclit1(Node *ntype, NodeList *body) // as we referred to variables from the outer function, // we accumulated a list of PHEAP names in func->cvars. narg = 0; - if(func->cvars == nil) - ft = type; - else { - // add PHEAP versions as function arguments. - in = nil; - for(l=func->cvars; l; l=l->next) { - a = l->n; - d = nod(ODCLFIELD, a, N); - d->type = ptrto(a->type); - in = list(in, d); - - // while we're here, set up a->heapaddr for back end - n = nod(ONAME, N, N); - snprint(namebuf, sizeof namebuf, "&%s", a->sym->name); - n->sym = lookup(namebuf); - n->type = ptrto(a->type); - n->class = PPARAM; - n->xoffset = narg*types[tptr]->width; - n->addable = 1; - n->ullman = 1; - narg++; - a->heapaddr = n; - - a->xoffset = 0; - - // unlink from actual ONAME in symbol table - a->closure->closure = a->outer; - } - - // add a dummy arg for the closure's caller pc + // add PHEAP versions as function arguments. + in = nil; + for(l=func->cvars; l; l=l->next) { + a = l->n; d = nod(ODCLFIELD, a, N); - d->type = types[TUINTPTR]; + d->type = ptrto(a->type); in = list(in, d); - // slide param offset to make room for ptrs above. - // narg+1 to skip over caller pc. - shift = (narg+1)*types[tptr]->width; + // while we're here, set up a->heapaddr for back end + n = nod(ONAME, N, N); + snprint(namebuf, sizeof namebuf, "&%s", a->sym->name); + n->sym = lookup(namebuf); + n->type = ptrto(a->type); + n->class = PPARAM; + n->xoffset = narg*types[tptr]->width; + n->addable = 1; + n->ullman = 1; + narg++; + a->heapaddr = n; - // now the original arguments. - for(t=structfirst(&save, getinarg(type)); t; t=structnext(&save)) { - d = nod(ODCLFIELD, t->nname, N); - d->type = t->type; - in = list(in, d); + a->xoffset = 0; - a = t->nname; - if(a != N) { - if(a->stackparam != N) - a = a->stackparam; - a->xoffset += shift; - } - } - - // out arguments - out = nil; - for(t=structfirst(&save, getoutarg(type)); t; t=structnext(&save)) { - d = nod(ODCLFIELD, t->nname, N); - d->type = t->type; - out = list(out, d); - - a = t->nname; - if(a != N) { - if(a->stackparam != N) - a = a->stackparam; - a->xoffset += shift; - } - } - - ft = functype(N, in, out); - ft->outnamed = type->outnamed; + // unlink from actual ONAME in symbol table + a->closure->closure = a->outer; } + // add a dummy arg for the closure's caller pc + d = nod(ODCLFIELD, N, N); + d->type = types[TUINTPTR]; + in = list(in, d); + + // slide param offset to make room for ptrs above. + // narg+1 to skip over caller pc. + shift = (narg+1)*types[tptr]->width; + + // now the original arguments. + for(t=structfirst(&save, getinarg(type)); t; t=structnext(&save)) { + d = nod(ODCLFIELD, t->nname, N); + d->type = t->type; + in = list(in, d); + + a = t->nname; + if(a != N) { + if(a->stackparam != N) + a = a->stackparam; + a->xoffset += shift; + } + } + + // out arguments + out = nil; + for(t=structfirst(&save, getoutarg(type)); t; t=structnext(&save)) { + d = nod(ODCLFIELD, t->nname, N); + d->type = t->type; + out = list(out, d); + + a = t->nname; + if(a != N) { + if(a->stackparam != N) + a = a->stackparam; + a->xoffset += shift; + } + } + + ft = functype(N, in, out); + ft->outnamed = type->outnamed; + // declare function. vargen++; snprint(namebuf, sizeof(namebuf), "_f%.3ld·%s", vargen, filename); @@ -642,10 +638,6 @@ funclit1(Node *ntype, NodeList *body) funcdepth--; autodcl = func->dcl; - // if there's no closure, we can use f directly - if(func->cvars == nil) - return f; - // build up type for this instance of the closure func. in = nil; d = nod(ODCLFIELD, N, N); // siz @@ -1655,7 +1647,7 @@ variter(NodeList *vl, Node *nt, NodeList *el) Type *tv; NodeList *r; Type *t; - + t = T; if(nt) { walkexpr(nt, Etype, &nt->ninit); diff --git a/src/pkg/runtime/386/closure.c b/src/pkg/runtime/386/closure.c index 6ccbe3b8b6..1a211bd1f3 100644 --- a/src/pkg/runtime/386/closure.c +++ b/src/pkg/runtime/386/closure.c @@ -43,41 +43,44 @@ sys·closure(int32 siz, byte *fn, byte *arg0) p = mal(n); *ret = p; q = p + n - siz; - mcpy(q, (byte*)&arg0, siz); - // SUBL $siz, SP - *p++ = 0x81; - *p++ = 0xec; - *(uint32*)p = siz; - p += 4; + if(siz > 0) { + mcpy(q, (byte*)&arg0, siz); - // MOVL $q, SI - *p++ = 0xbe; - *(byte**)p = q; - p += 4; - - // MOVL SP, DI - *p++ = 0x89; - *p++ = 0xe7; - - // CLD - *p++ = 0xfc; - - if(siz <= 4*4) { - for(i=0; i 0) { + mcpy(q, (byte*)&arg0, siz); - // MOVQ $q, SI - *p++ = 0x48; - *p++ = 0xbe; - *(byte**)p = q; - p += 8; + // SUBQ $siz, SP + *p++ = 0x48; + *p++ = 0x81; + *p++ = 0xec; + *(uint32*)p = siz; + p += 4; - // MOVQ SP, DI - *p++ = 0x48; - *p++ = 0x89; - *p++ = 0xe7; + // MOVQ $q, SI + *p++ = 0x48; + *p++ = 0xbe; + *(byte**)p = q; + p += 8; - if(siz <= 4*8) { - for(i=0; i