mirror of
https://github.com/apache/httpd.git
synced 2025-08-10 02:56:11 +00:00
Expression parser: Optimize another concatenation
case by using iteration instead of recursion. We have a relatively small recursion limit of about 10 operations. This is a compilation limit (a define). It can be hit if many expr vars or function calls are concatenated. The new optimization is very similar to the existing one, which optimizes consecutive concatenations in node2 of the tree. The new one optimizes consecutive concatenations in node 1. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1657685 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@ -103,7 +103,8 @@ static const char *ap_expr_eval_word(ap_expr_eval_ctx_t *ctx,
|
||||
node->node_arg2);
|
||||
break;
|
||||
case op_Concat:
|
||||
if (((ap_expr_t *)node->node_arg2)->node_op != op_Concat) {
|
||||
if (((ap_expr_t *)node->node_arg2)->node_op != op_Concat &&
|
||||
((ap_expr_t *)node->node_arg1)->node_op != op_Concat) {
|
||||
const char *s1 = ap_expr_eval_word(ctx, node->node_arg1);
|
||||
const char *s2 = ap_expr_eval_word(ctx, node->node_arg2);
|
||||
if (!*s1)
|
||||
@ -113,6 +114,30 @@ static const char *ap_expr_eval_word(ap_expr_eval_ctx_t *ctx,
|
||||
else
|
||||
result = apr_pstrcat(ctx->p, s1, s2, NULL);
|
||||
}
|
||||
else if (((ap_expr_t *)node->node_arg1)->node_op == op_Concat) {
|
||||
const ap_expr_t *nodep = node;
|
||||
int n;
|
||||
int i = 1;
|
||||
struct iovec *vec;
|
||||
do {
|
||||
nodep = nodep->node_arg1;
|
||||
i++;
|
||||
} while (nodep->node_op == op_Concat);
|
||||
vec = apr_palloc(ctx->p, i * sizeof(struct iovec));
|
||||
n = i;
|
||||
nodep = node;
|
||||
i--;
|
||||
do {
|
||||
vec[i].iov_base = (void *)ap_expr_eval_word(ctx,
|
||||
nodep->node_arg2);
|
||||
vec[i].iov_len = strlen(vec[i].iov_base);
|
||||
i--;
|
||||
nodep = nodep->node_arg1;
|
||||
} while (nodep->node_op == op_Concat);
|
||||
vec[i].iov_base = (void *)ap_expr_eval_word(ctx, nodep);
|
||||
vec[i].iov_len = strlen(vec[i].iov_base);
|
||||
result = apr_pstrcatv(ctx->p, vec, n, NULL);
|
||||
}
|
||||
else {
|
||||
const ap_expr_t *nodep = node;
|
||||
int i = 1;
|
||||
|
Reference in New Issue
Block a user