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