summaryrefslogtreecommitdiffstats
path: root/bin/sh/eval.c
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2010-10-31 12:06:02 +0000
committerjilles <jilles@FreeBSD.org>2010-10-31 12:06:02 +0000
commit4de067d3c296d7e292bb6b7415b78bc4a789a6b3 (patch)
tree8991552f2d74e310f587a48b7e2610fa8999dd8b /bin/sh/eval.c
parentf1bdc586812e81a8dc92b036a28f8a29e0ef1914 (diff)
downloadFreeBSD-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.c15
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();
OpenPOWER on IntegriCloud