diff options
author | jilles <jilles@FreeBSD.org> | 2010-10-31 12:06:02 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2010-10-31 12:06:02 +0000 |
commit | 4de067d3c296d7e292bb6b7415b78bc4a789a6b3 (patch) | |
tree | 8991552f2d74e310f587a48b7e2610fa8999dd8b /bin/sh/eval.c | |
parent | f1bdc586812e81a8dc92b036a28f8a29e0ef1914 (diff) | |
download | FreeBSD-src-4de067d3c296d7e292bb6b7415b78bc4a789a6b3.zip FreeBSD-src-4de067d3c296d7e292bb6b7415b78bc4a789a6b3.tar.gz |
sh: Use iteration instead of recursion to evaluate semicolon lists.
This reduces CPU and memory usage when executing long lists (such
as long functions).
Diffstat (limited to 'bin/sh/eval.c')
-rw-r--r-- | bin/sh/eval.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index ed6d717..cfb9e06 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -196,6 +196,7 @@ void evaltree(union node *n, int flags) { int do_etest; + union node *next; do_etest = 0; if (n == NULL) { @@ -203,6 +204,8 @@ evaltree(union node *n, int flags) exitstatus = 0; goto out; } + do { + next = NULL; #ifndef NO_HISTORY displayhist = 1; /* show history substitutions done with fc */ #endif @@ -212,20 +215,20 @@ evaltree(union node *n, int flags) evaltree(n->nbinary.ch1, flags & ~EV_EXIT); if (evalskip) goto out; - evaltree(n->nbinary.ch2, flags); + next = n->nbinary.ch2; break; case NAND: evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip || exitstatus != 0) { goto out; } - evaltree(n->nbinary.ch2, flags); + next = n->nbinary.ch2; break; case NOR: evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip || exitstatus == 0) goto out; - evaltree(n->nbinary.ch2, flags); + next = n->nbinary.ch2; break; case NREDIR: evalredir(n, flags); @@ -242,9 +245,9 @@ evaltree(union node *n, int flags) if (evalskip) goto out; if (exitstatus == 0) - evaltree(n->nif.ifpart, flags); + next = n->nif.ifpart; else if (n->nif.elsepart) - evaltree(n->nif.elsepart, flags); + next = n->nif.elsepart; else exitstatus = 0; break; @@ -281,6 +284,8 @@ evaltree(union node *n, int flags) flushout(&output); break; } + n = next; + } while (n != NULL); out: if (pendingsigs) dotrap(); |