194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata/*
294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata * This file is part of ltrace.
3cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata * Copyright (C) 2011,2012,2013 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
174cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machatastatic int
175cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machataexpr_alloc_and_clone(struct expr_node **retpp, struct expr_node *node, int own)
176cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata{
177cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	*retpp = node;
178cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	if (own) {
179cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		*retpp = malloc(sizeof **retpp);
180cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		if (*retpp == NULL || expr_clone(*retpp, node) < 0) {
181cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			free(*retpp);
182cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			return -1;
183cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		}
184cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	}
185cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	return 0;
186cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata}
187cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
188cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machataint
189cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machataexpr_clone(struct expr_node *retp, const struct expr_node *node)
190cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata{
191cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	*retp = *node;
192cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
193cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	switch (node->kind) {
194cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		struct expr_node *nlhs;
195cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		struct expr_node *nrhs;
196cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
197cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	case EXPR_OP_ARGNO:
198cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	case EXPR_OP_SELF:
199cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		return 0;
200cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
201cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	case EXPR_OP_CONST:
202cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		return value_clone(&retp->u.value, &node->u.value);
203cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
204cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	case EXPR_OP_NAMED:
205cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		if (node->u.name.own
206cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		    && (retp->u.name.s = strdup(node->u.name.s)) == NULL)
207cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			return -1;
208cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		return 0;
209cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
210cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	case EXPR_OP_INDEX:
211cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		if (expr_alloc_and_clone(&nlhs, node->lhs, node->own_lhs) < 0)
212cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			return -1;
213cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
214cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		if (expr_alloc_and_clone(&nrhs, node->u.node.n,
215cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata					 node->u.node.own) < 0) {
216cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			if (nlhs != node->lhs) {
217cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata				expr_destroy(nlhs);
218cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata				free(nlhs);
219cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			}
220cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			return -1;
221cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		}
222cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
223cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		retp->lhs = nlhs;
224cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		retp->u.node.n = nrhs;
225cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		return 0;
226cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
227cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	case EXPR_OP_CALL2:
228cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		if (expr_alloc_and_clone(&nrhs, node->u.call.rhs,
229cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata					 node->u.call.own_rhs) < 0)
230cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			return -1;
231cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		retp->u.call.rhs = nrhs;
232cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		/* Fall through.  */
233cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
234cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	case EXPR_OP_UP:
235cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	case EXPR_OP_CALL1:
236cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		if (expr_alloc_and_clone(&nlhs, node->lhs, node->own_lhs) < 0) {
237cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			if (node->kind == EXPR_OP_CALL2
238cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			    && node->u.call.own_rhs) {
239cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata				expr_destroy(nrhs);
240cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata				free(nrhs);
241cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata				return -1;
242cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata			}
243cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		}
244cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
245cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		retp->lhs = nlhs;
246cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata		return 0;
247cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	}
248cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
249cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	assert(!"Invalid value of node kind");
250cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata	abort();
251cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata}
252cd6ff36657ef51369f72fe109d581bc2530be5f2Petr Machata
25394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
25494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_is_compile_constant(struct expr_node *node)
25594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
25694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return node->kind == EXPR_OP_CONST;
25794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
25894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
25994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int
26094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataeval_up(struct expr_node *node, struct value *context,
26194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value_dict *arguments, struct value *ret_value)
26294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
26394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->lhs, context, arguments, ret_value) < 0)
26494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
26594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value *parent = value_get_parental_struct(ret_value);
26694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (parent == NULL) {
26794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		value_destroy(ret_value);
26894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
26994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
27094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	*ret_value = *parent;
27194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return 0;
27294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
27394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
27494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int
27594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataeval_cb1(struct expr_node *node, struct value *context,
27694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	 struct value_dict *arguments, struct value *ret_value)
27794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
27894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value val;
27994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->lhs, context, arguments, &val) < 0)
28094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
28194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
28294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	int ret = 0;
28394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (node->u.call.u.cb1(ret_value, &val, arguments,
28494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			       node->u.call.data) < 0)
28594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		ret = -1;
28694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
28794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	/* N.B. the callback must return its own value, or somehow
28894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	 * clone the incoming argument.  */
28994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_destroy(&val);
29094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return ret;
29194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
29294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
29394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastatic int
29494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataeval_cb2(struct expr_node *node, struct value *context,
29594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	 struct value_dict *arguments, struct value *ret_value)
29694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
29794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value lhs;
29894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
29994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
30094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
30194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value rhs;
30294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->u.call.rhs, context, arguments, &rhs) < 0) {
30394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		value_destroy(&lhs);
30494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
30594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
30694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
30794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	int ret = 0;
30894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (node->u.call.u.cb2(ret_value, &lhs, &rhs, arguments,
30994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			       node->u.call.data) < 0)
31094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		ret = -1;
31194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
31294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	/* N.B. the callback must return its own value, or somehow
31394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	 * clone the incoming argument.  */
31494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_destroy(&lhs);
31594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_destroy(&rhs);
31694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return ret;
31794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
31894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
31994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
32094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataeval_index(struct expr_node *node, struct value *context,
32194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	   struct value_dict *arguments, struct value *ret_value)
32294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
32394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value lhs;
32494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node->lhs, context, arguments, &lhs) < 0)
32594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
32694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
32794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	long l;
32894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval_word(node->u.node.n, context, arguments, &l) < 0) {
32994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	fail:
33094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		value_destroy(&lhs);
33194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
33294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
33394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
33494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (value_init_element(ret_value, &lhs, (size_t)l) < 0)
33594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		goto fail;
33694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return 0;
33794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
33894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
33994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
34094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_eval(struct expr_node *node, struct value *context,
34194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	  struct value_dict *arguments, struct value *ret_value)
34294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
34394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	switch (node->kind) {
34494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		struct value *valp;
34594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_ARGNO:
34694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		valp = val_dict_get_num(arguments, node->u.num);
34794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		if (valp == NULL)
34894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			return -1;
34994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		*ret_value = *valp;
35094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return 0;
35194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
35294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_NAMED:
35394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		valp = val_dict_get_name(arguments, node->u.name.s);
35494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		if (valp == NULL)
35594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata			return -1;
35694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		*ret_value = *valp;
35794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return 0;
35894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
35994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_SELF:
36094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		*ret_value = *context;
36194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return 0;
36294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
36394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CONST:
36494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		*ret_value = node->u.value;
36594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return 0;
36694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
36794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_INDEX:
36894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return eval_index(node, context, arguments, ret_value);
36994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
37094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_UP:
37194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return eval_up(node, context, arguments, ret_value);
37294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
37394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CALL1:
37494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return eval_cb1(node, context, arguments, ret_value);
37594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
37694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	case EXPR_OP_CALL2:
37794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return eval_cb2(node, context, arguments, ret_value);
37894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
37994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
38094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	assert(!"Unknown node kind.");
38194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	abort();
38294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
38394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
38494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
38594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_eval_word(struct expr_node *node, struct value *context,
38694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	       struct value_dict *arguments, long *ret_value)
38794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
38894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	struct value val;
38994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (expr_eval(node, context, arguments, &val) < 0)
39094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		return -1;
39194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	int ret = 0;
39294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	if (value_extract_word(&val, ret_value, arguments) < 0)
39394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata		ret = -1;
39494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	value_destroy(&val);
39594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return ret;
39694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
39794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
39894078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataint
39994078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_eval_constant(struct expr_node *node, long *valuep)
40094078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
40194078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	assert(expr_is_compile_constant(node));
40294078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	return expr_eval_word(node, NULL, NULL, valuep);
40394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
40494078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata
40594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machatastruct expr_node *
40694078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machataexpr_self(void)
40794078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata{
4081233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata	static struct expr_node *nodep = NULL;
4091233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata	if (nodep == NULL) {
4101233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata		static struct expr_node node;
4111233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata		expr_init_self(&node);
4121233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata		nodep = &node;
41394078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata	}
4141233b37167097dffa9a78bd7bd0a8117c75fe8ffPetr Machata	return nodep;
41594078ecce3a103c28457e6f90f1e5b0dacc61146Petr Machata}
416