Petr Machata | 94078ec | 2012-01-05 18:07:02 +0100 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of ltrace. |
Petr Machata | cd6ff36 | 2013-10-10 14:50:28 +0200 | [diff] [blame] | 3 | * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. |
Petr Machata | 94078ec | 2012-01-05 18:07:02 +0100 | [diff] [blame] | 4 | * |
| 5 | * This program is free software; you can redistribute it and/or |
| 6 | * modify it under the terms of the GNU General Public License as |
| 7 | * published by the Free Software Foundation; either version 2 of the |
| 8 | * License, or (at your option) any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, but |
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | * General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
| 18 | * 02110-1301 USA |
| 19 | */ |
| 20 | |
| 21 | #ifndef EXPR_H |
| 22 | #define EXPR_H |
| 23 | |
| 24 | #include "value.h" |
| 25 | #include "value_dict.h" |
| 26 | |
| 27 | /* Expressions serve as a way of encoding array lengths. */ |
| 28 | |
| 29 | enum expr_node_kind { |
| 30 | EXPR_OP_SELF, /* reference to the variable in question */ |
| 31 | EXPR_OP_NAMED, /* value of named argument */ |
| 32 | EXPR_OP_ARGNO, /* value of numbered argument */ |
| 33 | EXPR_OP_CONST, /* constant value */ |
| 34 | EXPR_OP_INDEX, /* A[B] */ |
| 35 | EXPR_OP_UP, /* reference to containing structure */ |
| 36 | EXPR_OP_CALL1, /* internal callback with one operand */ |
| 37 | EXPR_OP_CALL2, /* internal callback with two operands */ |
| 38 | }; |
| 39 | |
| 40 | struct expr_node { |
| 41 | enum expr_node_kind kind; |
| 42 | |
| 43 | struct expr_node *lhs; |
| 44 | int own_lhs; |
| 45 | |
| 46 | union { |
| 47 | struct { |
| 48 | const char *s; |
| 49 | int own; |
| 50 | } name; |
| 51 | struct { |
| 52 | struct expr_node *n; |
| 53 | int own; |
| 54 | } node; |
| 55 | struct value value; |
| 56 | size_t num; |
| 57 | struct { |
| 58 | union { |
| 59 | int (*cb1)(struct value *ret_value, |
| 60 | struct value *lhs, |
| 61 | struct value_dict *arguments, |
| 62 | void *data); |
| 63 | int (*cb2)(struct value *ret_value, |
| 64 | struct value *lhs, |
| 65 | struct value *rhs, |
| 66 | struct value_dict *arguments, |
| 67 | void *data); |
| 68 | } u; |
| 69 | void *data; |
| 70 | struct expr_node *rhs; |
| 71 | int own_rhs; |
| 72 | } call; |
| 73 | } u; |
| 74 | }; |
| 75 | |
| 76 | /* Expression of type self just returns the value in consideration. |
| 77 | * For example, if what we seek is length of an array, then the value |
| 78 | * representing that array is returned by the expression. */ |
| 79 | void expr_init_self(struct expr_node *node); |
| 80 | |
| 81 | /* Expression that yields the value of an argument named NAME. NAME |
| 82 | * is owned if OWN_NAME. */ |
| 83 | void expr_init_named(struct expr_node *node, |
| 84 | const char *name, int own_name); |
| 85 | |
| 86 | /* Expression that yields the value of an argument number NUM. */ |
| 87 | void expr_init_argno(struct expr_node *node, size_t num); |
| 88 | |
| 89 | /* Constant expression always returns the same value VAL. VAL is |
| 90 | * copied into NODE and owned by it. */ |
| 91 | void expr_init_const(struct expr_node *node, struct value *val); |
| 92 | void expr_init_const_word(struct expr_node *node, long l, |
| 93 | struct arg_type_info *type, int own_type); |
| 94 | |
| 95 | /* Expression LHS[RHS]. LHS and RHS are owned if, respectively, |
| 96 | * OWN_LHS and OWN_RHS. */ |
| 97 | void expr_init_index(struct expr_node *node, |
| 98 | struct expr_node *lhs, int own_lhs, |
| 99 | struct expr_node *rhs, int own_rhs); |
| 100 | |
| 101 | /* This expression returns the containing value of LHS (^LHS). LHS is |
| 102 | * owned if OWN_LHS. */ |
| 103 | void expr_init_up(struct expr_node *node, struct expr_node *lhs, int own_lhs); |
| 104 | |
| 105 | /* Callback expression calls CB(eval(LHS), DATA). LHS is owned if |
| 106 | * OWN_LHS. DATA is passed to callback verbatim. */ |
| 107 | void expr_init_cb1(struct expr_node *node, |
| 108 | int (*cb)(struct value *ret_value, |
| 109 | struct value *value, |
| 110 | struct value_dict *arguments, |
| 111 | void *data), |
| 112 | struct expr_node *lhs, int own_lhs, void *data); |
| 113 | |
| 114 | /* Callback expression calls CB(eval(LHS), eval(RHS), DATA). LHS and |
| 115 | * RHS are owned if, respectively, OWN_LHS and OWN_RHS. DATA is |
| 116 | * passed to callback verbatim. */ |
| 117 | void expr_init_cb2(struct expr_node *node, |
| 118 | int (*cb)(struct value *ret_value, |
| 119 | struct value *lhs, struct value *rhs, |
| 120 | struct value_dict *arguments, |
| 121 | void *data), |
| 122 | struct expr_node *lhs, int own_lhs, |
| 123 | struct expr_node *rhs, int own_rhs, void *data); |
| 124 | |
| 125 | /* Release the data inside NODE. Doesn't free NODE itself. */ |
| 126 | void expr_destroy(struct expr_node *node); |
| 127 | |
Petr Machata | cd6ff36 | 2013-10-10 14:50:28 +0200 | [diff] [blame] | 128 | /* Copy expression NODE into the area pointed to by RETP. Return 0 on |
| 129 | * success or a negative value on failure. */ |
| 130 | int expr_clone(struct expr_node *retp, const struct expr_node *node); |
| 131 | |
Petr Machata | 94078ec | 2012-01-05 18:07:02 +0100 | [diff] [blame] | 132 | /* Evaluate the expression NODE in context of VALUE. ARGUMENTS is a |
| 133 | * dictionary of named and numbered values that NODE may use. Returns |
| 134 | * 0 in case of success or a negative value on error. CONTEXT and |
| 135 | * ARGUMENTS may be NULL, but then the expression mustn't need them |
| 136 | * for evaluation. */ |
| 137 | int expr_eval(struct expr_node *node, struct value *context, |
| 138 | struct value_dict *arguments, struct value *ret_value); |
| 139 | |
| 140 | /* Evaluate compile-time expression. Returns 0 on success or negative |
| 141 | * value on failure. Computed value is passed back in *VALUEP. */ |
| 142 | int expr_eval_constant(struct expr_node *node, long *valuep); |
| 143 | |
| 144 | /* Evaluate expression, whose result should fit into a word. In order |
| 145 | * to easily support all the structure and array accesses, we simply |
| 146 | * operate on values represented by struct value. But eventually we need |
| 147 | * to be able to get out a word-size datum to use it as an index, a |
| 148 | * length, etc. */ |
| 149 | int expr_eval_word(struct expr_node *node, struct value *context, |
| 150 | struct value_dict *arguments, long *ret_value); |
| 151 | |
| 152 | /* Returns non-zero value if the expression is a compile-time |
| 153 | * constant. Currently this is only EXPR_OP_CONST, but eventually |
| 154 | * things like sizeof or simple expressions might be allowed. */ |
| 155 | int expr_is_compile_constant(struct expr_node *node); |
| 156 | |
| 157 | /* Returns a pre-computed expression "self". */ |
| 158 | struct expr_node *expr_self(void); |
| 159 | |
| 160 | #endif /* EXPR_H */ |