summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y8
-rw-r--r--filter/decl.m43
-rw-r--r--filter/f-inst.c1
-rw-r--r--filter/filter.c63
4 files changed, 29 insertions, 46 deletions
diff --git a/filter/config.Y b/filter/config.Y
index f256aace..f9d9b0b3 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -317,7 +317,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
MIN, MAX,
EMPTY,
FILTER, WHERE, EVAL, ATTRIBUTE,
- BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT, STACKS)
+ BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT)
%nonassoc THEN
%nonassoc ELSE
@@ -343,12 +343,6 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
CF_GRAMMAR
-conf: FILTER STACKS expr expr ';' {
- new_config->filter_vstk = $3;
- new_config->filter_estk = $4;
- }
- ;
-
conf: filter_def ;
filter_def:
FILTER symbol { $2 = cf_define_symbol($2, SYM_FILTER, filter, NULL); cf_push_scope( $2 ); }
diff --git a/filter/decl.m4 b/filter/decl.m4
index fc3808df..d0c86912 100644
--- a/filter/decl.m4
+++ b/filter/decl.m4
@@ -201,7 +201,6 @@ FID_INTERPRET_BODY()')
# that was needed in the former implementation.
m4_define(LINEX, `FID_INTERPRET_EXEC()LINEX_($1)FID_INTERPRET_NEW()return $1 FID_INTERPRET_BODY()')
m4_define(LINEX_, `do {
- if (fstk->ecnt + 1 >= fstk->elen) runtime("Filter execution stack overflow");
fstk->estk[fstk->ecnt].pos = 0;
fstk->estk[fstk->ecnt].line = $1;
fstk->estk[fstk->ecnt].ventry = fstk->vcnt;
@@ -239,7 +238,7 @@ FID_INTERPRET_BODY()')
# state the result and put it to the right place.
m4_define(RESULT, `RESULT_TYPE([[$1]]) RESULT_([[$1]],[[$2]],[[$3]])')
m4_define(RESULT_, `RESULT_VAL([[ (struct f_val) { .type = $1, .val.$2 = $3 } ]])')
-m4_define(RESULT_VAL, `FID_HIC(, [[do { res = $1; f_vcnt_check_overflow(1); fstk->vcnt++; } while (0)]],
+m4_define(RESULT_VAL, `FID_HIC(, [[do { res = $1; fstk->vcnt++; } while (0)]],
[[return fi_constant(what, $1)]])')
m4_define(RESULT_VOID, `RESULT_VAL([[ (struct f_val) { .type = T_VOID } ]])')
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 0fb04ba7..9a3a22ab 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -1271,7 +1271,6 @@
fstk->vcnt += sym->function->args;
/* Storage for local variables */
- f_vcnt_check_overflow(sym->function->vars);
memset(&(fstk->vstk[fstk->vcnt]), 0, sizeof(struct f_val) * sym->function->vars);
fstk->vcnt += sym->function->vars;
}
diff --git a/filter/filter.c b/filter/filter.c
index d8a58d0a..20a380dc 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -50,28 +50,30 @@ enum f_exception {
FE_RETURN = 0x1,
};
-struct filter_exec_stack {
- const struct f_line *line; /* The line that is being executed */
- uint pos; /* Instruction index in the line */
- uint ventry; /* Value stack depth on entry */
- uint vbase; /* Where to index variable positions from */
- enum f_exception emask; /* Exception mask */
+
+struct filter_stack {
+ /* Value stack for execution */
+#define F_VAL_STACK_MAX 4096
+ uint vcnt; /* Current value stack size; 0 for empty */
+ uint ecnt; /* Current execute stack size; 0 for empty */
+
+ struct f_val vstk[F_VAL_STACK_MAX]; /* The stack itself */
+
+ /* Instruction stack for execution */
+#define F_EXEC_STACK_MAX 4096
+ struct {
+ const struct f_line *line; /* The line that is being executed */
+ uint pos; /* Instruction index in the line */
+ uint ventry; /* Value stack depth on entry */
+ uint vbase; /* Where to index variable positions from */
+ enum f_exception emask; /* Exception mask */
+ } estk[F_EXEC_STACK_MAX];
};
/* Internal filter state, to be allocated on stack when executing filters */
struct filter_state {
/* Stacks needed for execution */
- struct filter_stack {
- /* Current filter stack depth */
-
- /* Value stack */
- uint vcnt, vlen;
- struct f_val *vstk;
-
- /* Instruction stack for execution */
- uint ecnt, elen;
- struct filter_exec_stack *estk;
- } stack;
+ struct filter_stack *stack;
/* The route we are processing. This may be NULL to indicate no route available. */
struct rte **rte;
@@ -93,13 +95,10 @@ struct filter_state {
};
_Thread_local static struct filter_state filter_state;
+_Thread_local static struct filter_stack filter_stack;
void (*bt_assert_hook)(int result, const struct f_line_item *assert);
-#define _f_stack_init(fs, px, def) ((fs).stack.px##stk = alloca(sizeof(*(fs).stack.px##stk) * ((fs).stack.px##len = (config && config->filter_##px##stk) ? config->filter_##px##stk : (def))))
-
-#define f_stack_init(fs) ( _f_stack_init(fs, v, 128), _f_stack_init(fs, e, 128) )
-
static inline void f_cache_eattrs(struct filter_state *fs)
{
fs->eattrs = &((*fs->rte)->attrs->eattrs);
@@ -164,17 +163,15 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val)
ASSERT(line->args == 0);
/* Initialize the filter stack */
- struct filter_stack *fstk = &fs->stack;
+ struct filter_stack *fstk = fs->stack;
fstk->vcnt = line->vars;
memset(fstk->vstk, 0, sizeof(struct f_val) * line->vars);
/* The same as with the value stack. Not resetting the stack for performance reasons. */
fstk->ecnt = 1;
- fstk->estk[0] = (struct filter_exec_stack) {
- .line = line,
- .pos = 0,
- };
+ fstk->estk[0].line = line;
+ fstk->estk[0].pos = 0;
#define curline fstk->estk[fstk->ecnt-1]
@@ -194,8 +191,6 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val)
#define v2 vv(1)
#define v3 vv(2)
-#define f_vcnt_check_overflow(n) do { if (fstk->vcnt + n >= fstk->vlen) runtime("Filter execution stack overflow"); } while (0)
-
#define runtime(fmt, ...) do { \
if (!(fs->flags & FF_SILENT)) \
log_rl(&rl_runtime_err, L_ERR "filters, line %d: " fmt, what->lineno, ##__VA_ARGS__); \
@@ -280,13 +275,12 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i
/* Initialize the filter state */
filter_state = (struct filter_state) {
+ .stack = &filter_stack,
.rte = rte,
.pool = tmp_pool,
.flags = flags,
};
- f_stack_init(filter_state);
-
LOG_BUFFER_INIT(filter_state.buf);
/* Run the interpreter itself */
@@ -345,12 +339,11 @@ enum filter_return
f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool)
{
filter_state = (struct filter_state) {
+ .stack = &filter_stack,
.rte = rte,
.pool = tmp_pool,
};
- f_stack_init(filter_state);
-
LOG_BUFFER_INIT(filter_state.buf);
ASSERT(!((*rte)->flags & REF_COW));
@@ -369,11 +362,10 @@ enum filter_return
f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
{
filter_state = (struct filter_state) {
+ .stack = &filter_stack,
.pool = tmp_pool,
};
- f_stack_init(filter_state);
-
LOG_BUFFER_INIT(filter_state.buf);
enum filter_return fret = interpret(&filter_state, expr, pres);
@@ -390,11 +382,10 @@ f_eval_int(const struct f_line *expr)
{
/* Called independently in parse-time to eval expressions */
filter_state = (struct filter_state) {
+ .stack = &filter_stack,
.pool = cfg_mem,
};
- f_stack_init(filter_state);
-
struct f_val val;
LOG_BUFFER_INIT(filter_state.buf);