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