Commit 0ae4a719 authored by Jan Maria Matejka's avatar Jan Maria Matejka

TMP: let's try to run this

parent 9aec608c
Pipeline #23976 failed with stages
in 11 minutes and 42 seconds
......@@ -331,12 +331,10 @@ f_generate_lc(struct f_inst *t1, struct f_inst *t2, struct f_inst *t3)
else
#endif
{
rv = cfg_allocz(sizeof(struct f_inst3));
rv->lineno = ifs->lino;
rv->fi_code = fi_lc_construct;
rv = f_new_inst(fi_lc_construct);
rv->a1.p = t1;
rv->a2.p = t2;
INST3(rv).p = t3;
rv->a3.p = t3;
}
return rv;
......
......@@ -621,13 +621,7 @@ static struct f_val interpret(struct f_inst *what);
static struct f_val
interpret(struct f_inst *what)
{
struct symbol *sym;
struct f_val v1, v2, res, *vp;
unsigned u1, u2;
int i;
u32 as;
res.type = T_VOID;
struct f_val res = { .type = T_VOID };
if (!what)
return res;
......@@ -638,7 +632,7 @@ interpret(struct f_inst *what)
FI_LIST
#undef F
default:
bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
bug( "Unknown instruction %d (%c%c)", what->fi_code, (what->fi_code & 0xff00) >> 8, what->fi_code & 0xff);
}
if (what->next)
return interpret(what->next);
......@@ -653,7 +647,9 @@ interpret(struct f_inst *what)
#define ONEARG ARG(v1, a1.p)
#define TWOARGS ARG(v1, a1.p) \
ARG(v2, a2.p)
#define THREEARGS ARG(v1, a1.p) \
ARG(v2, a2.p) \
ARG(v3, a3.p)
#define A2_SAME if (f1->a2.i != f2->a2.i) return 0;
/*
......@@ -668,38 +664,36 @@ i_same(struct f_inst *f1, struct f_inst *f2)
return 1;
if (f1->aux != f2->aux)
return 0;
if (f1->code != f2->code)
if (f1->fi_code != f2->fi_code)
return 0;
if (f1 == f2) /* It looks strange, but it is possible with call rewriting trickery */
return 1;
switch(f1->code) {
case ',': /* fall through */
case '+':
case '-':
case '*':
case '/':
case '|':
case '&':
case P('m','p'):
case P('m','c'):
case P('!','='):
case P('=','='):
case '<':
case P('<','='): TWOARGS; break;
case '!': ONEARG; break;
case P('!', '~'):
case '~': TWOARGS; break;
case P('d','e'): ONEARG; break;
case P('m','l'):
TWOARGS;
if (!i_same(INST3(f1).p, INST3(f2).p))
return 0;
switch(f1->fi_code) {
case fi_add:
case fi_subtract:
case fi_multiply:
case fi_divide:
case fi_or:
case fi_and:
case fi_pair_construct:
case fi_ec_construct:
case fi_neq:
case fi_eq:
case fi_lt:
case fi_lte:
TWOARGS; break;
case fi_not:
ONEARG; break;
case fi_not_match:
case fi_match:
TWOARGS; break;
case fi_defined:
ONEARG; break;
case fi_lc_construct:
THREEARGS;
break;
case 's':
case fi_set:
ARG(v2, a2.p);
{
struct symbol *s1, *s2;
......@@ -712,7 +706,7 @@ i_same(struct f_inst *f1, struct f_inst *f2)
}
break;
case 'c':
case fi_constant:
switch (f1->aux) {
case T_PREFIX_SET:
......@@ -735,43 +729,57 @@ i_same(struct f_inst *f1, struct f_inst *f2)
}
break;
case 'C':
case fi_constant_indirect:
if (!val_same(* (struct f_val *) f1->a1.p, * (struct f_val *) f2->a1.p))
return 0;
break;
case 'V':
case fi_variable:
if (strcmp((char *) f1->a2.p, (char *) f2->a2.p))
return 0;
break;
case 'p': case 'L': ONEARG; break;
case '?': TWOARGS; break;
case '0': case 'E': break;
case P('p',','): ONEARG; A2_SAME; break;
case 'P':
case 'a': A2_SAME; break;
case P('e','a'): A2_SAME; break;
case P('P','S'):
case P('a','S'):
case P('e','S'): ONEARG; A2_SAME; break;
case 'r': ONEARG; break;
case P('c','p'): ONEARG; break;
case P('c','a'): /* Call rewriting trickery to avoid exponential behaviour */
case fi_print:
case fi_length:
ONEARG; break;
case fi_condition:
TWOARGS; break;
case fi_nop:
case fi_empty:
break;
case fi_print_and_die:
ONEARG;
A2_SAME;
break;
case fi_pref_get:
case fi_rta_get:
case fi_ea_get:
A2_SAME;
break;
case fi_pref_set:
case fi_rta_set:
case fi_ea_set:
ONEARG;
A2_SAME;
break;
case fi_return: ONEARG; break;
case fi_ip: ONEARG; break;
case fi_call: /* Call rewriting trickery to avoid exponential behaviour */
ONEARG;
if (!i_same(f1->a2.p, f2->a2.p))
return 0;
f2->a2.p = f1->a2.p;
break;
case P('c','v'): break; /* internal instruction */
case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
case P('i','M'): TWOARGS; break;
case P('A','p'): TWOARGS; break;
case P('C','a'): TWOARGS; break;
case P('a','f'):
case P('a','l'):
case P('a','L'): ONEARG; break;
case P('R','C'):
case fi_clear_local_vars: break; /* internal instruction */
case fi_switch: ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
case fi_ip_mask: TWOARGS; break;
case fi_path_prepend: TWOARGS; break;
case fi_clist_add_del: TWOARGS; break;
case fi_as_path_first:
case fi_as_path_last:
case fi_as_path_last_nag:
ONEARG; break;
case fi_roa_check:
TWOARGS;
/* Does not really make sense - ROA check resuls may change anyway */
if (strcmp(((struct f_inst_roa_check *) f1)->rtc->name,
......@@ -779,7 +787,7 @@ i_same(struct f_inst *f1, struct f_inst *f2)
return 0;
break;
default:
bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
bug( "Unknown instruction %d in same (%c%c)", f1->fi_code, (f1->fi_code & 0xff00) >> 8, f1->fi_code & 0xff);
}
return i_same(f1->next, f2->next);
}
......
......@@ -18,49 +18,48 @@
#define FI_TWOCHAR(a,b) ((a<<8) | b)
#define FI_LIST \
F(comma, 0, ',') \
F(add, 0, '+') \
F(subtract, 0, '-') \
F(multiply, 0, '*') \
F(divide, 0, '/') \
F(and, 0, '&') \
F(or, 0, '|') \
F(add, ' ', '+') \
F(subtract, ' ', '-') \
F(multiply, ' ', '*') \
F(divide, ' ', '/') \
F(and, ' ', '&') \
F(or, ' ', '|') \
F(pair_construct, 'm', 'p') \
F(ec_construct, 'm', 'c') \
F(lc_construct, 'm', 'l') \
F(neq, '!', '=') \
F(eq, '=', '=') \
F(lt, 0, '<') \
F(lt, ' ', '<') \
F(lte, '<', '=') \
F(not, 0, '!') \
F(match, 0, '~') \
F(not, ' ', '!') \
F(match, ' ', '~') \
F(not_match, '!', '~') \
F(defined, 'd', 'e') \
F(set, 0, 's') \
F(constant, 0, 'c') \
F(variable, 0, 'V') \
F(constant_indirect, 0, 'C') \
F(print, 0, 'p') \
F(condition, 0, '?') \
F(nop, 0, '0') \
F(set, ' ', 's') \
F(constant, ' ', 'c') \
F(variable, ' ', 'V') \
F(constant_indirect, ' ', 'C') \
F(print, ' ', 'p') \
F(condition, ' ', '?') \
F(nop, ' ', '0') \
F(print_and_die, 'p', ',') \
F(rta_get, 0, 'a') \
F(rta_get, ' ', 'a') \
F(rta_set, 'a', 'S') \
F(ea_get, 'e', 'a') \
F(ea_set, 'e', 'S') \
F(pref_get, 0, 'P') \
F(pref_get, ' ', 'P') \
F(pref_set, 'P', 'S') \
F(length, 0, 'L') \
F(length, ' ', 'L') \
F(ip, 'c', 'p') \
F(as_path_first, 'a', 'f') \
F(as_path_last, 'a', 'l') \
F(as_path_last_nag, 'a', 'L') \
F(return, 0, 'r') \
F(return, ' ', 'r') \
F(call, 'c', 'a') \
F(clear_local_vars, 'c', 'V') \
F(switch, 'S', 'W') \
F(ip_mask, 'i', 'M') \
F(empty, 0, 'E') \
F(empty, ' ', 'E') \
F(path_prepend, 'A', 'p') \
F(clist_add_del, 'C', 'a') \
F(roa_check, 'R', 'C')
......@@ -84,6 +83,10 @@ struct f_inst { /* Instruction */
int i;
void *p;
} a2;
union {
int i;
void *p;
} a3;
int lineno;
};
......@@ -96,17 +99,6 @@ struct f_inst_roa_check {
struct roa_table_config *rtc;
};
struct f_inst3 {
struct f_inst i;
union {
int i;
void *p;
} a3;
};
#define INST3(x) (((struct f_inst3 *) x)->a3)
struct f_prefix {
ip_addr ip;
int len;
......
......@@ -10,7 +10,7 @@
(1u << (what->a2.i >> 24))
#define ARG(n,call) \
struct f_val v##n = call((n == 3) ? (INST3(what).p) : what->a##n.p); \
struct f_val v##n = call(what->a##n.p); \
if (v##n.type & T_RETURN) \
return v##n;
......@@ -23,6 +23,7 @@
#define RET_VOID return F_VAL_VOID
#define RETA(member,value) RET(what->aux, member, value)
/* Interpret */
#define FI_INST_NUMERIC_BINARY(name,op) \
FI_INST_INTERPRET(name) \
{ \
......@@ -61,7 +62,7 @@ static inline struct f_val fi_interpret_boolbinary(const struct f_inst *what)
#define fi_interpret_and fi_interpret_boolbinary
#define fi_interpret_or fi_interpret_boolbinary
F_INST_INTERPRET(pair_construct)
FI_INST_INTERPRET(pair_construct)
{
AI(1); AI(2);
if ((v1.type != T_INT) || (v2.type != T_INT))
......@@ -72,7 +73,7 @@ F_INST_INTERPRET(pair_construct)
RET(T_PAIR, i, (u1 << 16) | u2);
}
F_INST_INTERPRET(ec_construct)
FI_INST_INTERPRET(ec_construct)
{
AI(1); AI(2);
int check, ipv4_used;
......@@ -118,13 +119,13 @@ F_INST_INTERPRET(ec_construct)
return res;
}
F_INST_INTERPRET(lc_construct)
FI_INST_INTERPRET(lc_construct)
{
AI(1); AI(2); AI(3);
if ((v1.type != T_INT) || (v2.type != T_INT) || (v3.type != T_INT))
runtime( "Can't operate with value of non-integer type in LC constructor" );
RET(T_LC, lc, (lcomm) { v1.val.i, v2.val.i, v3.val.i });
RET(T_LC, lc, ((lcomm) { v1.val.i, v2.val.i, v3.val.i }));
}
/* Relational operators */
......@@ -150,7 +151,7 @@ static inline struct f_val fi_interpret_compare(const struct f_inst *what)
#define fi_interpret_lt fi_interpret_compare
#define fi_interpret_lte fi_interpret_compare
F_INST_INTERPRET(not)
FI_INST_INTERPRET(not)
{
AI(1);
if (v1.type != T_BOOL)
......@@ -158,7 +159,7 @@ F_INST_INTERPRET(not)
RET(T_BOOL, i, !v1.val.i);
}
F_INST_INTERPRET(match)
FI_INST_INTERPRET(match)
{
AI(1); AI(2);
int i = val_in_range(v1, v2);
......@@ -167,7 +168,7 @@ F_INST_INTERPRET(match)
RET(T_BOOL, i, !!i);
}
F_INST_INTERPRET(not_match)
FI_INST_INTERPRET(not_match)
{
AI(1); AI(2);
int i = val_in_range(v1, v2);
......@@ -176,13 +177,13 @@ F_INST_INTERPRET(not_match)
RET(T_BOOL, i, !i);
}
F_INST_INTERPRET(defined)
FI_INST_INTERPRET(defined)
{
AI(1);
RET(T_BOOL, i, (v1.type != T_VOID));
}
F_INST_INTERPRET(set)
FI_INST_INTERPRET(set)
{
/* Set to indirect value, a1 = variable, a2 = value */
AI(2);
......@@ -194,7 +195,7 @@ F_INST_INTERPRET(set)
if ((sym->class == (SYM_VARIABLE | T_QUAD)) && (v2.type == T_IP)) {
vp->type = T_QUAD;
vp->val.i = ipa_to_u32(v2.val.px.ip);
break;
RET_VOID;
}
#endif
runtime( "Assigning to variable of incompatible type" );
......@@ -203,7 +204,7 @@ F_INST_INTERPRET(set)
RET_VOID;
}
F_INST_INTERPRET(constant)
FI_INST_INTERPRET(constant)
{
/* some constants have value in a2, some in *a1.p, strange. */
/* integer (or simple type) constant, string, set, or prefix_set */
......@@ -211,25 +212,25 @@ F_INST_INTERPRET(constant)
case T_PREFIX_SET: RET(T_PREFIX_SET, ti, what->a2.p);
case T_SET: RET(T_SET, t, what->a2.p);
case T_STRING: RET(T_STRING, s, what->a2.p);
default: RET(what->aux, i, what->a2.p);
default: RET(what->aux, i, what->a2.i);
}
}
F_INST_INTERPRET(variable)
FI_INST_INTERPRET(variable)
{
return * ((struct f_val *) what->a1.p);
}
#define fi_interpret_constant_indirect fi_interpret_variable
F_INST_INTERPRET(print)
FI_INST_INTERPRET(print)
{
AI(1);
val_format(v1, &f_buf);
RET_VOID;
}
F_INST_INTERPRET(condition)
FI_INST_INTERPRET(condition)
{
/* Structure of conditions:
* if (CONDITION) then TRUE_BLOCK else FALSE_BLOCK
......@@ -287,12 +288,13 @@ F_INST_INTERPRET(condition)
RET(T_BOOL, i, 1);
}
F_INST_INTERPRET(nop)
FI_INST_INTERPRET(nop)
{
debug( "No operation\n" );
RET_VOID;
}
F_INST_INTERPRET(print_and_die)
FI_INST_INTERPRET(print_and_die)
{
AI(1);
if (what->a2.i == F_NOP || (what->a2.i != F_NONL && what->a1.p))
......@@ -306,7 +308,6 @@ F_INST_INTERPRET(print_and_die)
case F_ERROR:
case F_REJECT: /* FIXME (noncritical) Should print complete route along with reason to reject route */
RET(T_RETURN, i, what->a2.i);
return res; /* We have to return now, no more processing. */
case F_NONL:
case F_NOP:
break;
......@@ -316,7 +317,7 @@ F_INST_INTERPRET(print_and_die)
RET_VOID;
}
F_INST_INTERPRET(rta_get)
FI_INST_INTERPRET(rta_get)
{
ACCESS_RTE;
struct rta *rta = (*f_rte)->attrs;
......@@ -325,10 +326,10 @@ F_INST_INTERPRET(rta_get)
{
case SA_FROM: RETA(px.ip, rta->from);
case SA_GW: RETA(px.ip, rta->gw);
case SA_NET: RETA(px, {
case SA_NET: RETA(px, ((struct f_prefix) {
.ip = (*f_rte)->net->n.prefix,
.len = (*f_rte)->net->n.pxlen
});
}));
case SA_PROTO: RETA(s, rta->src->proto->name);
case SA_SOURCE: RETA(i, rta->source);
case SA_SCOPE: RETA(i, rta->scope); break;
......@@ -343,7 +344,7 @@ F_INST_INTERPRET(rta_get)
RET_VOID;
}
F_INST_INTERPRET(rta_set)
FI_INST_INTERPRET(rta_set)
{
AI(1);
ACCESS_RTE;
......@@ -379,15 +380,20 @@ F_INST_INTERPRET(rta_set)
break;
case SA_DEST:
i = v1.val.i;
if ((i != RTD_BLACKHOLE) && (i != RTD_UNREACHABLE) && (i != RTD_PROHIBIT))
runtime( "Destination can be changed only to blackhole, unreachable or prohibit" );
rta->dest = i;
rta->gw = IPA_NONE;
rta->iface = NULL;
rta->nexthops = NULL;
rta->hostentry = NULL;
switch(v1.val.i)
{
case RTD_BLACKHOLE:
case RTD_UNREACHABLE:
case RTD_PROHIBIT:
rta->dest = v1.val.i;
rta->gw = IPA_NONE;
rta->iface = NULL;
rta->nexthops = NULL;
rta->hostentry = NULL;
break;
default:
runtime( "Destination can be changed only to blackhole, unreachable or prohibit" );
}
break;
default:
......@@ -396,7 +402,7 @@ F_INST_INTERPRET(rta_set)
RET_VOID;
}
F_INST_INTERPRET(ea_get)
FI_INST_INTERPRET(ea_get)
{
ACCESS_RTE;
eattr *e = NULL;
......@@ -453,7 +459,7 @@ F_INST_INTERPRET(ea_get)
RET_VOID;
}
F_INST_INTERPRET(ea_set)
FI_INST_INTERPRET(ea_set)
{
ACCESS_RTE;
AI(1);
......@@ -560,12 +566,12 @@ F_INST_INTERPRET(ea_set)
RET_VOID;
}
F_INST_INTERPRET(pref_get) {
FI_INST_INTERPRET(pref_get) {
ACCESS_RTE;
RET(T_INT, i, (*f_rte)->pref);
}
F_INST_INTERPRET(pref_set) {
FI_INST_INTERPRET(pref_set) {
ACCESS_RTE;
AI(1);
if (v1.type != T_INT)
......@@ -577,7 +583,7 @@ F_INST_INTERPRET(pref_set) {
RET_VOID;
}
F_INST_INTERPRET(length) {
FI_INST_INTERPRET(length) {
AI(1);
switch(v1.type) {
case T_PREFIX: RET(T_INT, i, v1.val.px.len);
......@@ -590,7 +596,7 @@ F_INST_INTERPRET(length) {
RET_VOID;
}
F_INST_INTERPRET(ip) {
FI_INST_INTERPRET(ip) {
AI(1);
if (v1.type != T_PREFIX)
runtime( "Prefix expected" );
......@@ -598,7 +604,7 @@ F_INST_INTERPRET(ip) {
RET(T_IP, px.ip, v1.val.px.ip);
}
F_INST_INTERPRET(as_path_first) {
FI_INST_INTERPRET(as_path_first) {
AI(1);
if (v1.type != T_PATH)
runtime( "AS path expected" );
......@@ -608,7 +614,7 @@ F_INST_INTERPRET(as_path_first) {
RET(T_INT, i, as);
}
F_INST_INTERPRET(as_path_last) {
FI_INST_INTERPRET(as_path_last) {
AI(1);
if (v1.type != T_PATH)
runtime( "AS path expected" );
......@@ -618,7 +624,7 @@ F_INST_INTERPRET(as_path_last) {
RET(T_INT, i, as);
}
F_INST_INTERPRET(as_path_last_nag) {
FI_INST_INTERPRET(as_path_last_nag) {
AI(1);
if (v1.type != T_PATH)
runtime( "AS path expected" );
......@@ -626,13 +632,13 @@ F_INST_INTERPRET(as_path_last_nag) {
RET(T_INT, i, as_path_get_last_nonaggregated(v1.val.ad));
}
F_INST_INTERPRET(return) {
FI_INST_INTERPRET(return) {
AI(1);
v1.type |= T_RETURN;
return v1;
}
F_INST_INTERPRET(call) {
FI_INST_INTERPRET(call) {
AI(1);
struct f_val res = interpret(what->a2.p);
if (res.type == T_RETURN) /* Exception */
......@@ -642,20 +648,20 @@ F_INST_INTERPRET(call) {
return res;
}
F_INST_INTERPRET(clear_local_vars) {
for (sym = what->a1.p; sym != NULL; sym = sym->aux2)
FI_INST_INTERPRET(clear_local_vars) {
for (struct symbol *sym = what->a1.p; sym != NULL; sym = sym->aux2)
((struct f_val *) sym->def)->type = T_VOID;
RET_VOID;
}
F_INST_INTERPRET(switch) {
FI_INST_INTERPRET(switch) {
AI(1);
struct f_tree *t = find_tree(what->a2.p, v1);
if (!t) {
t = find_tree(what->a2.p, F_VAL_VOID);
if (!t) {
debug( "No else statement?\n");
break;
RET_VOID;
}
}
......@@ -663,7 +669,7 @@ F_INST_INTERPRET(switch) {
return interpret(t->data);
}
F_INST_INTERPRET(ip_mask) {
FI_INST_INTERPRET(ip_mask) {
AI(1); AI(2);
if (v2.type != T_INT)
......@@ -675,11 +681,11 @@ F_INST_INTERPRET(ip_mask) {
RET(T_IP, px.ip, ipa_and(mask, v1.val.px.ip));
}
F_INST_INTERPRET(empty) {
FI_INST_INTERPRET(empty) {
RETA(ad, adata_empty(f_pool, 0));
}
F_INST_INTERPRET(path_prepend) {
FI_INST_INTERPRET(path_prepend) {
AI(1); AI(2);
if (v1.type != T_PATH)
runtime("Can't prepend to non-path");
......@@ -689,7 +695,7 @@ F_INST_INTERPRET(path_prepend) {
RET(T_PATH, ad, as_path_prepend(f_pool, v1.val.ad, v2.val.i));
}
F_INST_INTERPRET(clist_add_del) {
FI_INST_INTERPRET(clist_add_del) {
AI(1); AI(2);
if (v1.type == T_PATH)
{
......@@ -814,7 +820,6 @@ F_INST_INTERPRET(clist_add_del) {
else if (v2.type != T_LC)
runtime("Can't add/delete non-lc");
res.type = T_LCLIST;
switch (what->aux)
{
case 'a':
......@@ -823,7 +828,7 @@ F_INST_INTERPRET(clist_add_del) {
else if (!arg_set)
RET(T_LCLIST, ad, lc_set_add(f_pool, v1.val.ad, v2.val.lc));
else
RET(T_LCLIST, ad, lc_set_union(f_pool, v1.val.ad, v2.val.ad));
RET(T_LCLIST, ad, lc_set_union(f_pool, v1.val.ad, v2.val.ad));
case 'd':
if (!arg_set)
......@@ -844,7 +849,7 @@ F_INST_INTERPRET(clist_add_del) {
runtime("Can't add/delete to non-[el]?clist");
}
F_INST_INTERPRET(roa_check) {
FI_INST_INTERPRET(roa_check) {
u32 as;
ip_addr ip;
......@@ -893,3 +898,5 @@ F_INST_INTERPRET(roa_check) {
#undef RET_VOID
#undef RETA
#undef FI_INST_NUMERIC_BINARY
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment