#include <erec.h>
#include <json.h>
-static const struct expr_ops *expr_ops(const struct expr *e)
-{
- return e->ops;
-}
-
-struct expr *expr_alloc(const struct location *loc, const struct expr_ops *ops,
+extern const struct expr_ops ct_expr_ops;
+extern const struct expr_ops fib_expr_ops;
+extern const struct expr_ops hash_expr_ops;
+extern const struct expr_ops meta_expr_ops;
+extern const struct expr_ops numgen_expr_ops;
+extern const struct expr_ops osf_expr_ops;
+extern const struct expr_ops payload_expr_ops;
+extern const struct expr_ops rt_expr_ops;
+extern const struct expr_ops socket_expr_ops;
+extern const struct expr_ops xfrm_expr_ops;
+
+static const struct expr_ops *expr_ops(const struct expr *e);
+
+struct expr *expr_alloc(const struct location *loc, enum expr_types etype,
const struct datatype *dtype, enum byteorder byteorder,
unsigned int len)
{
expr = xzalloc(sizeof(*expr));
expr->location = *loc;
- expr->ops = ops;
expr->dtype = dtype;
- expr->etype = ops->type;
+ expr->etype = etype;
expr->byteorder = byteorder;
expr->len = len;
expr->refcnt = 1;
{
struct expr *new;
- new = expr_alloc(&expr->location, expr->ops, expr->dtype,
+ new = expr_alloc(&expr->location, expr->etype, expr->dtype,
expr->byteorder, expr->len);
new->flags = expr->flags;
new->op = expr->op;
- expr->ops->clone(new, expr);
+ expr_ops(expr)->clone(new, expr);
return new;
}
{
const struct expr_ops *ops = expr_ops(e);
- if (ops && ops->destroy)
+ if (ops->destroy)
ops->destroy(e);
}
if (--expr->refcnt > 0)
return;
- expr_destroy(expr);
+ /* EXPR_INVALID expressions lack ->ops structure.
+ * This happens for compound types.
+ */
+ if (expr->etype != EXPR_INVALID)
+ expr_destroy(expr);
xfree(expr);
}
const char *expr_name(const struct expr *e)
{
- return e->ops->name;
+ return expr_ops(e)->name;
}
void expr_describe(const struct expr *expr, struct output_ctx *octx)
{
struct expr *expr;
- expr = expr_alloc(loc, &verdict_expr_ops, &verdict_type,
+ expr = expr_alloc(loc, EXPR_VERDICT, &verdict_type,
BYTEORDER_INVALID, 0);
expr->verdict = verdict;
if (chain != NULL)
{
struct expr *expr;
- expr = expr_alloc(loc, &symbol_expr_ops, &invalid_type,
+ expr = expr_alloc(loc, EXPR_SYMBOL, &invalid_type,
BYTEORDER_INVALID, 0);
expr->symtype = type;
expr->scope = scope;
{
struct expr *expr;
- expr = expr_alloc(loc, &variable_expr_ops, &invalid_type,
+ expr = expr_alloc(loc, EXPR_VARIABLE, &invalid_type,
BYTEORDER_INVALID, 0);
expr->scope = scope;
expr->sym = sym;
{
struct expr *expr;
- expr = expr_alloc(loc, &constant_expr_ops, dtype, byteorder, len);
+ expr = expr_alloc(loc, EXPR_VALUE, dtype, byteorder, len);
expr->flags = EXPR_F_CONSTANT | EXPR_F_SINGLETON;
mpz_init2(expr->value, len);
{
struct expr *prefix;
- prefix = expr_alloc(loc, &prefix_expr_ops, &invalid_type,
+ prefix = expr_alloc(loc, EXPR_PREFIX, &invalid_type,
BYTEORDER_INVALID, 0);
prefix->prefix = expr;
prefix->prefix_len = prefix_len;
{
struct expr *expr;
- expr = expr_alloc(loc, &unary_expr_ops, &invalid_type,
+ expr = expr_alloc(loc, EXPR_UNARY, &invalid_type,
BYTEORDER_INVALID, 0);
expr->op = op;
expr->arg = arg;
{
struct expr *expr;
- expr = expr_alloc(loc, &binop_expr_ops, left->dtype,
+ expr = expr_alloc(loc, EXPR_BINOP, left->dtype,
left->byteorder, 0);
expr->left = left;
expr->op = op;
{
struct expr *expr;
- expr = expr_alloc(loc, &relational_expr_ops, &verdict_type,
+ expr = expr_alloc(loc, EXPR_RELATIONAL, &verdict_type,
BYTEORDER_INVALID, 0);
expr->left = left;
expr->op = op;
{
struct expr *expr;
- expr = expr_alloc(loc, &range_expr_ops, &invalid_type,
+ expr = expr_alloc(loc, EXPR_RANGE, &invalid_type,
BYTEORDER_INVALID, 0);
expr->left = left;
expr->right = right;
}
struct expr *compound_expr_alloc(const struct location *loc,
- const struct expr_ops *ops)
+ enum expr_types etype)
{
struct expr *expr;
- expr = expr_alloc(loc, ops, &invalid_type, BYTEORDER_INVALID, 0);
+ expr = expr_alloc(loc, etype, &invalid_type, BYTEORDER_INVALID, 0);
init_list_head(&expr->expressions);
return expr;
}
struct expr *concat_expr_alloc(const struct location *loc)
{
- return compound_expr_alloc(loc, &concat_expr_ops);
+ return compound_expr_alloc(loc, EXPR_CONCAT);
}
static void list_expr_print(const struct expr *expr, struct output_ctx *octx)
struct expr *list_expr_alloc(const struct location *loc)
{
- return compound_expr_alloc(loc, &list_expr_ops);
+ return compound_expr_alloc(loc, EXPR_LIST);
}
static const char *calculate_delim(const struct expr *expr, int *count)
struct expr *set_expr_alloc(const struct location *loc, const struct set *set)
{
- struct expr *set_expr = compound_expr_alloc(loc, &set_expr_ops);
+ struct expr *set_expr = compound_expr_alloc(loc, EXPR_SET);
if (!set)
return set_expr;
{
struct expr *expr;
- expr = expr_alloc(loc, &mapping_expr_ops, from->dtype,
+ expr = expr_alloc(loc, EXPR_MAPPING, from->dtype,
from->byteorder, 0);
expr->left = from;
expr->right = to;
{
struct expr *expr;
- expr = expr_alloc(loc, &map_expr_ops, &invalid_type, BYTEORDER_INVALID, 0);
+ expr = expr_alloc(loc, EXPR_MAP, &invalid_type, BYTEORDER_INVALID, 0);
expr->map = arg;
expr->mappings = mappings;
return expr;
{
struct expr *expr;
- expr = expr_alloc(loc, &set_ref_expr_ops, set->key->dtype, 0, 0);
+ expr = expr_alloc(loc, EXPR_SET_REF, set->key->dtype, 0, 0);
expr->set = set_get(set);
expr->flags |= EXPR_F_CONSTANT;
return expr;
{
struct expr *expr;
- expr = expr_alloc(loc, &set_elem_expr_ops, key->dtype,
+ expr = expr_alloc(loc, EXPR_SET_ELEM, key->dtype,
key->byteorder, key->len);
expr->key = key;
return expr;
BUG("invalid range expression type %s\n", expr_name(expr));
}
}
+
+static const struct expr_ops *expr_ops(const struct expr *e)
+{
+ switch (e->etype) {
+ case EXPR_INVALID:
+ BUG("Invalid expression ops requested");
+ break;
+ case EXPR_VERDICT: return &verdict_expr_ops;
+ case EXPR_SYMBOL: return &symbol_expr_ops;
+ case EXPR_VARIABLE: return &variable_expr_ops;
+ case EXPR_VALUE: return &constant_expr_ops;
+ case EXPR_PREFIX: return &prefix_expr_ops;
+ case EXPR_RANGE: return &range_expr_ops;
+ case EXPR_PAYLOAD: return &payload_expr_ops;
+ case EXPR_EXTHDR: return &exthdr_expr_ops;
+ case EXPR_META: return &meta_expr_ops;
+ case EXPR_SOCKET: return &socket_expr_ops;
+ case EXPR_OSF: return &osf_expr_ops;
+ case EXPR_CT: return &ct_expr_ops;
+ case EXPR_CONCAT: return &concat_expr_ops;
+ case EXPR_LIST: return &list_expr_ops;
+ case EXPR_SET: return &set_expr_ops;
+ case EXPR_SET_REF: return &set_ref_expr_ops;
+ case EXPR_SET_ELEM: return &set_elem_expr_ops;
+ case EXPR_MAPPING: return &mapping_expr_ops;
+ case EXPR_MAP: return &map_expr_ops;
+ case EXPR_UNARY: return &unary_expr_ops;
+ case EXPR_BINOP: return &binop_expr_ops;
+ case EXPR_RELATIONAL: return &relational_expr_ops;
+ case EXPR_NUMGEN: return &numgen_expr_ops;
+ case EXPR_HASH: return &hash_expr_ops;
+ case EXPR_RT: return &rt_expr_ops;
+ case EXPR_FIB: return &fib_expr_ops;
+ case EXPR_XFRM: return &xfrm_expr_ops;
+ }
+
+ BUG("Unknown expression type %d\n", e->etype);
+}