ref: c2103276d324781df709f39564f54da596f302d8
dir: /awk-cinapfixes/
diff f3ac883d0db6842870cdabd44ed938b92de87d71 uncommitted
--- a/sys/src/cmd/awk/run.c
+++ b/sys/src/cmd/awk/run.c
@@ -218,8 +218,6 @@
#define NARGS 50 /* max args in a call */
-struct Frame *frame = nil; /* base of stack frames; dynamically allocated */
-int nframe = 0; /* number of frames allocated */
struct Frame *fp = nil; /* frame pointer. bottom level unused */
Cell *call(Node **a, int) /* function call. very kludgy and fragile */
@@ -227,8 +225,9 @@
static Cell newcopycell = { OCELL, CCOPY, NUM|STR|DONTFREE, 0, EMPTY, 0.0 };
int i, ncall, ndef;
Node *x;
- Cell *args[NARGS], *oargs[NARGS]; /* BUG: fixed size arrays */
+ Cell *args[NARGS], **oargs;
Cell *y, *z, *fcn;
+ struct Frame frame, *up;
char *s;
fcn = execute(a[0]); /* the function itself */
@@ -235,79 +234,66 @@
s = fcn->nval;
if (!isfcn(fcn))
FATAL("calling undefined function %s", s);
- if (frame == nil) {
- fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame));
- if (frame == nil)
- FATAL("out of space for stack frames calling %s", s);
- }
for (ncall = 0, x = a[1]; x != nil; x = x->nnext) /* args in call */
ncall++;
ndef = (int) fcn->fval; /* args in defn */
- dprint( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, (int) (fp-frame)) );
- if (ncall > ndef)
+ dprint( ("calling %s, %d args (%d in defn)\n", s, ncall, ndef) );
+ if (ncall > ndef){
WARNING("function %s called with %d args, uses only %d",
s, ncall, ndef);
- if (ncall + ndef > NARGS)
- FATAL("function %s has %d arguments, limit %d", s, ncall+ndef, NARGS);
- for (i = 0, x = a[1]; x != nil; i++, x = x->nnext) { /* get call args */
- dprint( ("evaluate args[%d], fp=%d:\n", i, (int) (fp-frame)) );
+ ncall = ndef;
+ }
+ if (ndef+ncall > NARGS)
+ FATAL("function %s has %d arguments, limit %d", s, ndef+ncall, NARGS);
+ oargs = args+ndef;
+ for (i = 0, x = a[1]; i < ncall && x != nil; i++, x = x->nnext) { /* get call args */
+ dprint( ("evaluate args[%d]:\n", i) );
y = execute(x);
- oargs[i] = y;
dprint( ("args[%d]: %s %f <%s>, t=%o\n",
i, y->nval, y->fval, isarr(y) ? "(array)" : y->sval, y->tval) );
if (isfcn(y))
FATAL("can't use function %s as argument in %s", y->nval, s);
- if (isarr(y))
+ if (isarr(y)) {
args[i] = y; /* arrays by ref */
- else
+ y = nil;
+ } else if (istemp(y)) {
+ y->csub = CCOPY;
+ args[i] = y;
+ } else
args[i] = copycell(y);
- if (istemp(y))
- tfree(y);
+ oargs[i] = y; /* potential output arg for arrays */
}
for ( ; i < ndef; i++) { /* add null args for ones not provided */
args[i] = gettemp();
*args[i] = newcopycell;
}
- fp++; /* now ok to up frame */
- if (fp >= frame + nframe) {
- int dfp = fp - frame; /* old index */
- frame = (struct Frame *)
- realloc((char *) frame, (nframe += 100) * sizeof(struct Frame));
- if (frame == nil)
- FATAL("out of space for stack frames in %s", s);
- fp = frame + dfp;
- }
+ /* now ok to up frame */
+ up = fp;
+ fp = &frame;
fp->fcncell = fcn;
fp->args = args;
fp->nargs = ndef; /* number defined with (excess are locals) */
fp->retval = gettemp();
- dprint( ("start exec of %s, fp=%d\n", s, (int) (fp-frame)) );
+ dprint( ("start exec of %s\n", s) );
y = execute((Node *)(fcn->sval)); /* execute body */
- dprint( ("finished exec of %s, fp=%d\n", s, (int) (fp-frame)) );
+ dprint( ("finished exec of %s\n", s) );
for (i = 0; i < ndef; i++) {
- Cell *t = fp->args[i];
+ Cell *t = args[i];
if (isarr(t)) {
if (t->csub == CCOPY) {
if (i >= ncall) {
freesymtab(t);
- t->csub = CTEMP;
- if (istemp(t))
tfree(t);
- } else {
+ } else if(oargs[i] != nil) {
oargs[i]->tval = t->tval;
oargs[i]->tval &= ~(STR|NUM|DONTFREE);
oargs[i]->sval = t->sval;
- if (istemp(t))
- tfree(t);
}
}
- } else if (t != y) { /* kludge to prevent freeing twice */
- t->csub = CTEMP;
- if (istemp(t))
- tfree(t);
- }
+ } else if (t != y) /* kludge to prevent freeing twice */
+ tfree(t);
}
if (istemp(fcn))
tfree(fcn);
@@ -317,7 +303,7 @@
tfree(y); /* this can free twice! */
z = fp->retval; /* return value */
dprint( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) );
- fp--;
+ fp = up;
return(z);
}
@@ -328,7 +314,7 @@
y = gettemp();
y->csub = CCOPY; /* prevents freeing until call is over */
y->nval = x->nval; /* BUG? */
- y->sval = x->sval != nil && x->sval != EMPTY ? tostring(x->sval) : EMPTY;
+ y->sval = x->sval != nil && *x->sval ? tostring(x->sval) : EMPTY;
y->fval = x->fval;
y->tval = x->tval & ~(CON|FLD|REC|DONTFREE); /* copy is not constant or field */
if (y->sval == EMPTY)
@@ -341,7 +327,7 @@
n = ptoi(a[0]); /* argument number, counting from 0 */
dprint( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) );
- if (n+1 > fp->nargs)
+ if (n >= fp->nargs)
FATAL("argument #%d of function %s was not supplied",
n+1, fp->fcncell->nval);
return fp->args[n];
--- a/sys/src/cmd/awk/tran.c
+++ b/sys/src/cmd/awk/tran.c
@@ -229,7 +229,7 @@
p->sval = (char *) ENVtab;
p->tval = ARR;
} else {
- p->sval = s != nil && s != EMPTY ? tostring(s) : EMPTY;
+ p->sval = s && *s ? tostring(s) : EMPTY;
p->tval = t;
if (p->sval == EMPTY)
p->tval |= DONTFREE;
@@ -342,7 +342,7 @@
donefld = 0; /* mark $1... invalid */
donerec = 1;
}
- t = s != nil && s != EMPTY ? tostring(s) : EMPTY; /* in case it's self-assign */
+ t = s && *s ? tostring(s) : EMPTY; /* in case it's self-assign */
vp->tval &= ~NUM;
vp->tval |= STR;
if (freeable(vp))