diff options
Diffstat (limited to 'expr.h')
-rw-r--r-- | expr.h | 156 |
1 files changed, 156 insertions, 0 deletions
@@ -0,0 +1,156 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef EXPR_H +#define EXPR_H + +#include "value.h" +#include "value_dict.h" + +/* Expressions serve as a way of encoding array lengths. */ + +enum expr_node_kind { + EXPR_OP_SELF, /* reference to the variable in question */ + EXPR_OP_NAMED, /* value of named argument */ + EXPR_OP_ARGNO, /* value of numbered argument */ + EXPR_OP_CONST, /* constant value */ + EXPR_OP_INDEX, /* A[B] */ + EXPR_OP_UP, /* reference to containing structure */ + EXPR_OP_CALL1, /* internal callback with one operand */ + EXPR_OP_CALL2, /* internal callback with two operands */ +}; + +struct expr_node { + enum expr_node_kind kind; + + struct expr_node *lhs; + int own_lhs; + + union { + struct { + const char *s; + int own; + } name; + struct { + struct expr_node *n; + int own; + } node; + struct value value; + size_t num; + struct { + union { + int (*cb1)(struct value *ret_value, + struct value *lhs, + struct value_dict *arguments, + void *data); + int (*cb2)(struct value *ret_value, + struct value *lhs, + struct value *rhs, + struct value_dict *arguments, + void *data); + } u; + void *data; + struct expr_node *rhs; + int own_rhs; + } call; + } u; +}; + +/* Expression of type self just returns the value in consideration. + * For example, if what we seek is length of an array, then the value + * representing that array is returned by the expression. */ +void expr_init_self(struct expr_node *node); + +/* Expression that yields the value of an argument named NAME. NAME + * is owned if OWN_NAME. */ +void expr_init_named(struct expr_node *node, + const char *name, int own_name); + +/* Expression that yields the value of an argument number NUM. */ +void expr_init_argno(struct expr_node *node, size_t num); + +/* Constant expression always returns the same value VAL. VAL is + * copied into NODE and owned by it. */ +void expr_init_const(struct expr_node *node, struct value *val); +void expr_init_const_word(struct expr_node *node, long l, + struct arg_type_info *type, int own_type); + +/* Expression LHS[RHS]. LHS and RHS are owned if, respectively, + * OWN_LHS and OWN_RHS. */ +void expr_init_index(struct expr_node *node, + struct expr_node *lhs, int own_lhs, + struct expr_node *rhs, int own_rhs); + +/* This expression returns the containing value of LHS (^LHS). LHS is + * owned if OWN_LHS. */ +void expr_init_up(struct expr_node *node, struct expr_node *lhs, int own_lhs); + +/* Callback expression calls CB(eval(LHS), DATA). LHS is owned if + * OWN_LHS. DATA is passed to callback verbatim. */ +void expr_init_cb1(struct expr_node *node, + int (*cb)(struct value *ret_value, + struct value *value, + struct value_dict *arguments, + void *data), + struct expr_node *lhs, int own_lhs, void *data); + +/* Callback expression calls CB(eval(LHS), eval(RHS), DATA). LHS and + * RHS are owned if, respectively, OWN_LHS and OWN_RHS. DATA is + * passed to callback verbatim. */ +void expr_init_cb2(struct expr_node *node, + int (*cb)(struct value *ret_value, + struct value *lhs, struct value *rhs, + struct value_dict *arguments, + void *data), + struct expr_node *lhs, int own_lhs, + struct expr_node *rhs, int own_rhs, void *data); + +/* Release the data inside NODE. Doesn't free NODE itself. */ +void expr_destroy(struct expr_node *node); + +/* Evaluate the expression NODE in context of VALUE. ARGUMENTS is a + * dictionary of named and numbered values that NODE may use. Returns + * 0 in case of success or a negative value on error. CONTEXT and + * ARGUMENTS may be NULL, but then the expression mustn't need them + * for evaluation. */ +int expr_eval(struct expr_node *node, struct value *context, + struct value_dict *arguments, struct value *ret_value); + +/* Evaluate compile-time expression. Returns 0 on success or negative + * value on failure. Computed value is passed back in *VALUEP. */ +int expr_eval_constant(struct expr_node *node, long *valuep); + +/* Evaluate expression, whose result should fit into a word. In order + * to easily support all the structure and array accesses, we simply + * operate on values represented by struct value. But eventually we need + * to be able to get out a word-size datum to use it as an index, a + * length, etc. */ +int expr_eval_word(struct expr_node *node, struct value *context, + struct value_dict *arguments, long *ret_value); + +/* Returns non-zero value if the expression is a compile-time + * constant. Currently this is only EXPR_OP_CONST, but eventually + * things like sizeof or simple expressions might be allowed. */ +int expr_is_compile_constant(struct expr_node *node); + +/* Returns a pre-computed expression "self". */ +struct expr_node *expr_self(void); + +#endif /* EXPR_H */ |