diff --git a/Src/builtin.c b/Src/builtin.c index 063644e..680b19a 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3483,15 +3483,15 @@ mkautofn(Shfunc shf) { Eprog p; - p = (Eprog) zalloc(sizeof(*p)); + p = (Eprog) zalloc(sizeof(*p) + 5 * sizeof(wordcode)); p->len = 5 * sizeof(wordcode); - p->prog = (Wordcode) zalloc(p->len); + p->prog = (Wordcode) (((char*)p)+sizeof(*p)); p->strs = NULL; p->shf = shf; p->npats = 0; p->nref = 1; /* allocated from permanent storage */ p->pats = (Patprog *) p->prog; - p->flags = EF_REAL; + p->flags = EF_REAL_SINGLE; /* no allocation for p->prog */ p->dump = NULL; p->prog[0] = WCB_LIST((Z_SYNC | Z_END), 0); diff --git a/Src/exec.c b/Src/exec.c index debb0ae..088080b 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4973,7 +4973,13 @@ execfuncdef(Estate state, Eprog redir_prog) prog = (Eprog) zhalloc(sizeof(*prog)); prog->nref = -1; /* on the heap */ } else { - prog = (Eprog) zalloc(sizeof(*prog)); + if (state->prog->dump || !names) { + prog = (Eprog) zalloc(sizeof(*prog)); + } else { + /* The EF_REAL path below */ + prog = (Eprog) zalloc(sizeof(*prog) + len); + prog->pats = pp = (Patprog *) (((char*)prog)+sizeof(*prog)); + } prog->nref = 1; /* allocated from permanent storage */ } prog->npats = npats; @@ -4992,8 +4998,11 @@ execfuncdef(Estate state, Eprog redir_prog) prog->prog = state->pc; prog->strs = state->strs + sbeg; } else { - prog->flags = EF_REAL; - prog->pats = pp = (Patprog *) zalloc(len); + /* The EF_REAL path */ + prog->flags = EF_REAL_SINGLE; + // prog->pats = pp = (Patprog *) zalloc(len); + // --> + // prog->pats = pp = (((char*)prog)+sizeof(*prog)); prog->prog = (Wordcode) (prog->pats + npats); prog->strs = (char *) (prog->prog + nprg); prog->dump = NULL; diff --git a/Src/parse.c b/Src/parse.c index 8769baa..1e1c528 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -504,18 +504,28 @@ bld_eprog(int heap) ecadd(WCB_END()); - ret = heap ? (Eprog) zhalloc(sizeof(*ret)) : (Eprog) zalloc(sizeof(*ret)); - ret->len = ((ecnpats * sizeof(Patprog)) + - (ecused * sizeof(wordcode)) + - ecsoffs); - ret->npats = ecnpats; - ret->nref = heap ? -1 : 1; - ret->pats = heap ? (Patprog *) zhalloc(ret->len) : - (Patprog *) zshcalloc(ret->len); + if ( heap ) { + ret = (Eprog) zhalloc(sizeof(*ret)); + ret->len = ((ecnpats * sizeof(Patprog)) + + (ecused * sizeof(wordcode)) + + ecsoffs); + ret->npats = ecnpats; + ret->nref = -1; + ret->pats = (Patprog *) zhalloc(ret->len); + } else { + int len = ((ecnpats * sizeof(Patprog)) + + (ecused * sizeof(wordcode)) + + ecsoffs); + ret = (Eprog) zalloc(sizeof(*ret) + len); + ret->len = len; + ret->npats = ecnpats; + ret->nref = 1; + ret->pats = (Patprog *) (((char*)ret)+sizeof(*ret)); + } ret->prog = (Wordcode) (ret->pats + ecnpats); ret->strs = (char *) (ret->prog + ecused); ret->shf = NULL; - ret->flags = heap ? EF_HEAP : EF_REAL; + ret->flags = heap ? EF_HEAP : EF_REAL_SINGLE; ret->dump = NULL; for (l = 0; l < ecnpats; l++) ret->pats[l] = dummy_patprog1; @@ -2709,9 +2719,14 @@ freeeprog(Eprog p) if (p->dump) { decrdumpcount(p->dump); zfree(p->pats, p->npats * sizeof(Patprog)); - } else - zfree(p->pats, p->len); - zfree(p, sizeof(*p)); + } else { + if ( (p->flags & EF_REAL_SINGLE) == 0 ) + zfree(p->pats, p->len); + } + if ( (p->flags & EF_REAL_SINGLE) ) + zfree(p, sizeof(*p) + p->len); + else + zfree(p, sizeof(*p)); } } } diff --git a/Src/zsh.h b/Src/zsh.h index 22f73f8..ab70cb7 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -797,6 +797,7 @@ struct eprog { #define EF_HEAP 2 #define EF_MAP 4 #define EF_RUN 8 +#define EF_REAL_SINGLE 16 typedef struct estate *Estate;