summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2018-09-14 23:00:39 +0000
committerMikael Magnusson <mikma@users.sourceforge.net>2019-02-28 00:38:24 +0100
commitec3a86b8a0ccf8e499c15eed8e873d2a62959a13 (patch)
treead2f17e2a2eec2bc9410e1e967de1ff1fe85aaec /filter
parent7c36eb3e8bd7d06f65dc7319d42b6abe782c5b89 (diff)
WIP native functionnative/native-function
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y26
-rw-r--r--filter/filter.c17
-rw-r--r--filter/filter.h1
3 files changed, 36 insertions, 8 deletions
diff --git a/filter/config.Y b/filter/config.Y
index c1e74531..cc19cac0 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -819,10 +819,17 @@ function_call:
SYM '(' var_list ')' {
struct symbol *sym;
struct f_inst *inst = $3;
- if ($1->class != SYM_FUNCTION)
- cf_error("You can't call something which is not a function. Really.");
+ enum f_instruction_code code;
+ switch ($1->class) {
+ case SYM_FUNCTION:
+ code = FI_CALL; break;
+ case SYM_FUNCTION_NATIVE:
+ code = FI_CALL_NATIVE; break;
+ default:
+ cf_error("You can't call something which is not a function. Really.");
+ }
DBG("You are calling function %s\n", $1->name);
- $$ = f_new_inst(FI_CALL);
+ $$ = f_new_inst(code);
$$->a1.p = inst;
$$->a2.p = $1->def;
sym = $1->aux2;
@@ -939,10 +946,17 @@ term:
| SYM '(' var_list ')' {
struct symbol *sym;
struct f_inst *inst = $3;
- if ($1->class != SYM_FUNCTION)
- cf_error("You can't call something which is not a function. Really.");
+ enum f_instruction_code code;
+ switch ($1->class) {
+ case SYM_FUNCTION:
+ code = FI_CALL; break;
+ case SYM_FUNCTION_NATIVE:
+ code = FI_CALL_NATIVE; break;
+ default:
+ cf_error("You can't call something which is not a function. Really.");
+ }
DBG("You are calling function %s\n", $1->name);
- $$ = f_new_inst(FI_CALL);
+ $$ = f_new_inst(code);
$$->a1.p = inst;
$$->a2.p = $1->def;
sym = $1->aux2;
diff --git a/filter/filter.c b/filter/filter.c
index 37cf16a3..88da05b4 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -610,7 +610,8 @@ static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
#define INTERPRET(val, what_) \
val = interpret(what_); \
- if (val.type & T_RETURN) \
+ debug("INTERPRET %d\n", val.type); \
+ if (val.type & T_RETURN) \
return val;
#define ACCESS_RTE \
@@ -886,8 +887,10 @@ interpret(struct f_inst *what)
res.val.t = what->a2.p;
else if (res.type == T_STRING)
res.val.s = what->a2.p;
- else
+ else {
res.val.i = what->a2.i;
+ debug("FI_CONSTANT %d\n", res.val.i);
+ }
break;
case FI_VARIABLE:
case FI_CONSTANT_INDIRECT:
@@ -1309,6 +1312,15 @@ interpret(struct f_inst *what)
return res;
res.type &= ~T_RETURN;
break;
+ case FI_CALL_NATIVE: /* CALL: this is special: if T_RETURN and returning some value, mask it out */
+ ARG_ANY(1);
+ debug("**********************foobar1**************************%d %x\n", v1.type, v1.val.s);
+ struct f_val (*f)(void) = what->a2.p;
+ res = f();
+ if (res.type == T_RETURN)
+ return res;
+ res.type &= ~T_RETURN;
+ break;
case FI_CLEAR_LOCAL_VARS: /* Clear local variables */
for (sym = what->a1.p; sym != NULL; sym = sym->aux2)
((struct f_val *) sym->def)->type = T_VOID;
@@ -1578,6 +1590,7 @@ interpret(struct f_inst *what)
default:
bug( "Unknown instruction %d (%c)", what->fi_code, what->fi_code & 0xff);
}}
+ debug("return %d\n", res.type);
return res;
}
diff --git a/filter/filter.h b/filter/filter.h
index a8c33287..1dbc16c2 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -63,6 +63,7 @@
F(FI_AS_PATH_LAST_NAG, 'a', 'L') \
F(FI_RETURN, 0, 'r') \
F(FI_CALL, 'c', 'a') \
+ F(FI_CALL_NATIVE, 'c', 'n') \
F(FI_CLEAR_LOCAL_VARS, 'c', 'V') \
F(FI_SWITCH, 'S', 'W') \
F(FI_IP_MASK, 'i', 'M') \