| /* |
| * This file is part of ltrace. |
| * Copyright (C) 2011,2012,2013 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); |
| |
| /* Copy expression NODE into the area pointed to by RETP. Return 0 on |
| * success or a negative value on failure. */ |
| int expr_clone(struct expr_node *retp, const 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 */ |