2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
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.
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.
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
30 expr_init_common(struct expr_node *node, enum expr_node_kind kind)
35 memset(&node->u, 0, sizeof(node->u));
39 expr_init_self(struct expr_node *node)
41 expr_init_common(node, EXPR_OP_SELF);
45 expr_init_named(struct expr_node *node,
46 const char *name, int own_name)
48 expr_init_common(node, EXPR_OP_NAMED);
49 node->u.name.s = name;
50 node->u.name.own = own_name;
54 expr_init_argno(struct expr_node *node, size_t num)
56 expr_init_common(node, EXPR_OP_ARGNO);
61 expr_init_const(struct expr_node *node, struct value *val)
63 expr_init_common(node, EXPR_OP_CONST);
68 expr_init_const_word(struct expr_node *node, long l,
69 struct arg_type_info *type, int own_type)
72 value_init_detached(&val, NULL, type, own_type);
73 value_set_word(&val, l);
74 expr_init_const(node, &val);
78 expr_init_index(struct expr_node *node,
79 struct expr_node *lhs, int own_lhs,
80 struct expr_node *rhs, int own_rhs)
82 expr_init_common(node, EXPR_OP_INDEX);
84 node->own_lhs = own_lhs;
86 node->u.node.own = own_rhs;
90 expr_init_up(struct expr_node *node, struct expr_node *lhs, int own_lhs)
93 expr_init_common(node, EXPR_OP_UP);
95 node->own_lhs = own_lhs;
99 expr_init_cb1(struct expr_node *node,
100 int (*cb)(struct value *ret_value, struct value *value,
101 struct value_dict *arguments, void *data),
102 struct expr_node *lhs, int own_lhs, void *data)
104 expr_init_common(node, EXPR_OP_CALL1);
106 node->own_lhs = own_lhs;
107 node->u.call.u.cb1 = cb;
108 node->u.call.data = data;
112 expr_init_cb2(struct expr_node *node,
113 int (*cb)(struct value *ret_value,
114 struct value *lhs, struct value *rhs,
115 struct value_dict *arguments, void *data),
116 struct expr_node *lhs, int own_lhs,
117 struct expr_node *rhs, int own_rhs, void *data)
119 expr_init_common(node, EXPR_OP_CALL2);
121 node->own_lhs = own_lhs;
122 node->u.call.rhs = rhs;
123 node->u.call.own_rhs = own_rhs;
124 node->u.call.u.cb2 = cb;
125 node->u.call.data = data;
129 release_expr(struct expr_node *node, int own)
138 expr_destroy(struct expr_node *node)
143 switch (node->kind) {
149 value_destroy(&node->u.value);
153 if (node->u.name.own)
154 free((char *)node->u.name.s);
158 release_expr(node->lhs, node->own_lhs);
159 release_expr(node->u.node.n, node->u.node.own);
163 release_expr(node->u.call.rhs, node->u.call.own_rhs);
167 release_expr(node->lhs, node->own_lhs);
171 assert(!"Invalid value of node kind");
176 expr_is_compile_constant(struct expr_node *node)
178 return node->kind == EXPR_OP_CONST;
182 eval_up(struct expr_node *node, struct value *context,
183 struct value_dict *arguments, struct value *ret_value)
185 if (expr_eval(node->lhs, context, arguments, ret_value) < 0)
187 struct value *parent = value_get_parental_struct(ret_value);
188 if (parent == NULL) {
189 value_destroy(ret_value);
192 *ret_value = *parent;
197 eval_cb1(struct expr_node *node, struct value *context,
198 struct value_dict *arguments, struct value *ret_value)
201 if (expr_eval(node->lhs, context, arguments, &val) < 0)
205 if (node->u.call.u.cb1(ret_value, &val, arguments,
206 node->u.call.data) < 0)
209 /* N.B. the callback must return its own value, or somehow
210 * clone the incoming argument. */
216 eval_cb2(struct expr_node *node, struct value *context,
217 struct value_dict *arguments, struct value *ret_value)
220 if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
224 if (expr_eval(node->u.call.rhs, context, arguments, &rhs) < 0) {
230 if (node->u.call.u.cb2(ret_value, &lhs, &rhs, arguments,
231 node->u.call.data) < 0)
234 /* N.B. the callback must return its own value, or somehow
235 * clone the incoming argument. */
242 eval_index(struct expr_node *node, struct value *context,
243 struct value_dict *arguments, struct value *ret_value)
246 if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
250 if (expr_eval_word(node->u.node.n, context, arguments, &l) < 0) {
256 if (value_init_element(ret_value, &lhs, (size_t)l) < 0)
262 expr_eval(struct expr_node *node, struct value *context,
263 struct value_dict *arguments, struct value *ret_value)
265 switch (node->kind) {
268 valp = val_dict_get_num(arguments, node->u.num);
275 valp = val_dict_get_name(arguments, node->u.name.s);
282 *ret_value = *context;
286 *ret_value = node->u.value;
290 return eval_index(node, context, arguments, ret_value);
293 return eval_up(node, context, arguments, ret_value);
296 return eval_cb1(node, context, arguments, ret_value);
299 return eval_cb2(node, context, arguments, ret_value);
302 assert(!"Unknown node kind.");
307 expr_eval_word(struct expr_node *node, struct value *context,
308 struct value_dict *arguments, long *ret_value)
311 if (expr_eval(node, context, arguments, &val) < 0)
314 if (value_extract_word(&val, ret_value, arguments) < 0)
321 expr_eval_constant(struct expr_node *node, long *valuep)
323 assert(expr_is_compile_constant(node));
324 return expr_eval_word(node, NULL, NULL, valuep);
330 static struct expr_node *node = NULL;
332 node = malloc(sizeof(*node));
334 error(1, errno, "malloc expr_self");
335 expr_init_self(node);