expr.c revision 1233b37167097dffa9a78bd7bd0a8117c75fe8ff
194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata/*
294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This file is part of ltrace.
394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata *
594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This program is free software; you can redistribute it and/or
694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * modify it under the terms of the GNU General Public License as
794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * published by the Free Software Foundation; either version 2 of the
894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * License, or (at your option) any later version.
994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata *
1094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This program is distributed in the hope that it will be useful, but
1194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
1294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * General Public License for more details.
1494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata *
1594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * You should have received a copy of the GNU General Public License
1694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * along with this program; if not, write to the Free Software
1794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
1894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * 02110-1301 USA
1994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata */
2094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
2194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <string.h>
2294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <assert.h>
2394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <errno.h>
2494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include <stdlib.h>
2594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
2694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata#include "expr.h"
2794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
2894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic void
2994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_common(struct expr_node *node, enum expr_node_kind kind)
3094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
3194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->kind = kind;
3294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->lhs = NULL;
3394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->own_lhs = 0;
3494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	memset(&node->u, 0, sizeof(node->u));
3594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
3694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
3794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
3894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_self(struct expr_node *node)
3994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
4094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_common(node, EXPR_OP_SELF);
4194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
4294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
4394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
4494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_named(struct expr_node *node,
4594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		const char *name, int own_name)
4694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
4794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_common(node, EXPR_OP_NAMED);
4894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.name.s = name;
4994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.name.own = own_name;
5094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
5194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
5294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
5394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_argno(struct expr_node *node, size_t num)
5494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
5594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_common(node, EXPR_OP_ARGNO);
5694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.num = num;
5794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
5894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
5994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
6094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_const(struct expr_node *node, struct value *val)
6194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
6294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_common(node, EXPR_OP_CONST);
6394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.value = *val;
6494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
6594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
6694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
6794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_const_word(struct expr_node *node, long l,
6894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		     struct arg_type_info *type, int own_type)
6994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
7094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value val;
7194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_init_detached(&val, NULL, type, own_type);
72da442f4777454436e02bf0ec170bc9b59fb68546Petr Machata	value_set_word(&val, l);
7394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_const(node, &val);
7494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
7594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
7694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
7794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_index(struct expr_node *node,
7894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		struct expr_node *lhs, int own_lhs,
7994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		struct expr_node *rhs, int own_rhs)
8094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
8194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_common(node, EXPR_OP_INDEX);
8294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->lhs = lhs;
8394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->own_lhs = own_lhs;
8494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.node.n = rhs;
8594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.node.own = own_rhs;
8694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
8794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
8894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
8994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_up(struct expr_node *node, struct expr_node *lhs, int own_lhs)
9094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
9194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	assert(lhs != NULL);
9294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_common(node, EXPR_OP_UP);
9394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->lhs = lhs;
9494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->own_lhs = own_lhs;
9594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
9694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
9794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
9894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_cb1(struct expr_node *node,
9994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	      int (*cb)(struct value *ret_value, struct value *value,
10094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			struct value_dict *arguments, void *data),
10194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	      struct expr_node *lhs, int own_lhs, void *data)
10294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
10394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_common(node, EXPR_OP_CALL1);
10494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->lhs = lhs;
10594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->own_lhs = own_lhs;
10694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.call.u.cb1 = cb;
10794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.call.data = data;
10894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
10994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
11094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
11194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_init_cb2(struct expr_node *node,
11294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	      int (*cb)(struct value *ret_value,
11394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			struct value *lhs, struct value *rhs,
11494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			struct value_dict *arguments, void *data),
11594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	      struct expr_node *lhs, int own_lhs,
11694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	      struct expr_node *rhs, int own_rhs, void *data)
11794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
11894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	expr_init_common(node, EXPR_OP_CALL2);
11994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->lhs = lhs;
12094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->own_lhs = own_lhs;
12194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.call.rhs = rhs;
12294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.call.own_rhs = own_rhs;
12394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.call.u.cb2 = cb;
12494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	node->u.call.data = data;
12594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
12694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
12794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic void
1283299797320059f659f3abb80f3ce02bab3db8bb9Petr Machatarelease_expr(struct expr_node *node, int own)
12994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
1303299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata	if (own) {
1313299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata		expr_destroy(node);
1323299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata		free(node);
1333299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata	}
13494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
13594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
13694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatavoid
13794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_destroy(struct expr_node *node)
13894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
13994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (node == NULL)
14094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return;
14194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
14294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	switch (node->kind) {
14394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_ARGNO:
14494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_SELF:
14594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return;
14694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
14794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CONST:
14894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		value_destroy(&node->u.value);
14994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return;
15094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
15194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_NAMED:
15294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		if (node->u.name.own)
15394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			free((char *)node->u.name.s);
15494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return;
15594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
15694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_INDEX:
1573299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata		release_expr(node->lhs, node->own_lhs);
1583299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata		release_expr(node->u.node.n, node->u.node.own);
15994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return;
16094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
16194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CALL2:
1623299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata		release_expr(node->u.call.rhs, node->u.call.own_rhs);
1633299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata		/* Fall through.  */
16494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_UP:
16594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CALL1:
1663299797320059f659f3abb80f3ce02bab3db8bb9Petr Machata		release_expr(node->lhs, node->own_lhs);
16794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return;
16894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
16994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
17094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	assert(!"Invalid value of node kind");
17194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	abort();
17294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
17394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
17494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
17594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_is_compile_constant(struct expr_node *node)
17694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
17794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return node->kind == EXPR_OP_CONST;
17894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
17994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
18094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int
18194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataeval_up(struct expr_node *node, struct value *context,
18294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value_dict *arguments, struct value *ret_value)
18394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
18494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->lhs, context, arguments, ret_value) < 0)
18594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
18694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value *parent = value_get_parental_struct(ret_value);
18794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (parent == NULL) {
18894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		value_destroy(ret_value);
18994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
19094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
19194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	*ret_value = *parent;
19294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return 0;
19394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
19494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
19594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int
19694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataeval_cb1(struct expr_node *node, struct value *context,
19794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	 struct value_dict *arguments, struct value *ret_value)
19894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
19994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value val;
20094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->lhs, context, arguments, &val) < 0)
20194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
20294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
20394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	int ret = 0;
20494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (node->u.call.u.cb1(ret_value, &val, arguments,
20594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			       node->u.call.data) < 0)
20694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		ret = -1;
20794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
20894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	/* N.B. the callback must return its own value, or somehow
20994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	 * clone the incoming argument.  */
21094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_destroy(&val);
21194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return ret;
21294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
21394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
21494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int
21594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataeval_cb2(struct expr_node *node, struct value *context,
21694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	 struct value_dict *arguments, struct value *ret_value)
21794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
21894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value lhs;
21994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
22094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
22194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
22294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value rhs;
22394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->u.call.rhs, context, arguments, &rhs) < 0) {
22494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		value_destroy(&lhs);
22594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
22694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
22794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
22894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	int ret = 0;
22994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (node->u.call.u.cb2(ret_value, &lhs, &rhs, arguments,
23094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			       node->u.call.data) < 0)
23194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		ret = -1;
23294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
23394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	/* N.B. the callback must return its own value, or somehow
23494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	 * clone the incoming argument.  */
23594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_destroy(&lhs);
23694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_destroy(&rhs);
23794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return ret;
23894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
23994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
24094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
24194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataeval_index(struct expr_node *node, struct value *context,
24294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	   struct value_dict *arguments, struct value *ret_value)
24394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
24494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value lhs;
24594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
24694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
24794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
24894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	long l;
24994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval_word(node->u.node.n, context, arguments, &l) < 0) {
25094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	fail:
25194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		value_destroy(&lhs);
25294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
25394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
25494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
25594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (value_init_element(ret_value, &lhs, (size_t)l) < 0)
25694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		goto fail;
25794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return 0;
25894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
25994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
26094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
26194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_eval(struct expr_node *node, struct value *context,
26294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	  struct value_dict *arguments, struct value *ret_value)
26394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
26494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	switch (node->kind) {
26594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		struct value *valp;
26694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_ARGNO:
26794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		valp = val_dict_get_num(arguments, node->u.num);
26894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		if (valp == NULL)
26994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			return -1;
27094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		*ret_value = *valp;
27194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return 0;
27294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
27394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_NAMED:
27494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		valp = val_dict_get_name(arguments, node->u.name.s);
27594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		if (valp == NULL)
27694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			return -1;
27794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		*ret_value = *valp;
27894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return 0;
27994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
28094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_SELF:
28194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		*ret_value = *context;
28294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return 0;
28394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
28494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CONST:
28594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		*ret_value = node->u.value;
28694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return 0;
28794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
28894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_INDEX:
28994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return eval_index(node, context, arguments, ret_value);
29094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
29194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_UP:
29294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return eval_up(node, context, arguments, ret_value);
29394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
29494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CALL1:
29594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return eval_cb1(node, context, arguments, ret_value);
29694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
29794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CALL2:
29894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return eval_cb2(node, context, arguments, ret_value);
29994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
30094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
30194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	assert(!"Unknown node kind.");
30294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	abort();
30394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
30494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
30594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
30694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_eval_word(struct expr_node *node, struct value *context,
30794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	       struct value_dict *arguments, long *ret_value)
30894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
30994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value val;
31094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node, context, arguments, &val) < 0)
31194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
31294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	int ret = 0;
31394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (value_extract_word(&val, ret_value, arguments) < 0)
31494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		ret = -1;
31594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_destroy(&val);
31694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return ret;
31794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
31894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
31994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
32094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_eval_constant(struct expr_node *node, long *valuep)
32194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
32294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	assert(expr_is_compile_constant(node));
32394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return expr_eval_word(node, NULL, NULL, valuep);
32494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
32594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
32694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastruct expr_node *
32794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_self(void)
32894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
3291233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata	static struct expr_node *nodep = NULL;
3301233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata	if (nodep == NULL) {
3311233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata		static struct expr_node node;
3321233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata		expr_init_self(&node);
3331233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata		nodep = &node;
33494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
3351233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata	return nodep;
33694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
337