Added BPatch_retExpr
[dyninst.git] / dyninstAPI / src / BPatch_snippet.C
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 #include <string.h>
43 #include "ast.h"
44 #include "symtab.h"
45 #include "perfStream.h"
46
47 #include "BPatch.h"
48 #include "BPatch_snippet.h"
49 #include "BPatch_type.h"
50
51
52 /*
53  * BPatch_snippet::BPatch_snippet
54  *
55  * Copy constructor for BPatch_snippet.
56  */
57 BPatch_snippet::BPatch_snippet(const BPatch_snippet &src)
58 {
59     ast = assignAst(src.ast);
60 }
61
62
63 /*
64  * BPatch_snippet::operator=
65  *
66  * Assignment operator for BPatch_snippet.  Needed to ensure that the
67  * reference counts for the asts contained in the snippets is correct.
68  */
69 BPatch_snippet &BPatch_snippet::operator=(const BPatch_snippet &src)
70 {
71     // Check for x = x
72     if (&src == this)
73         return *this;
74
75     // Since we're copying over this snippet, release the old AST
76     if (ast != NULL)
77         removeAst(ast);
78
79     // We'll now contain another reference to the ast in the other snippet
80     ast = assignAst(src.ast);
81
82     return *this;
83 }
84
85
86 /*
87  * BPatch_snippet:getCost
88  *
89  * Returns the estimated cost of executing the snippet, in seconds.
90  */
91 float BPatch_snippet::getCost()
92 {
93     return (double)ast->cost() / cyclesPerSecond;
94 }
95
96
97 /*
98  * BPatch_snippet::~BPatch_snippet
99  *
100  * Destructor for BPatch_snippet.  Deallocates memory allocated by the
101  * snippet.
102  */
103 BPatch_snippet::~BPatch_snippet()
104 {
105     // if (ast != NULL)
106         // removeAst(ast);
107 }
108
109
110 /*
111  * BPatch_arithExpr::BPatch_arithExpr
112  *
113  * Construct a snippet representing a binary arithmetic operation.
114  *
115  * op           The desired operation.
116  * lOperand     The left operand for the operation.
117  * rOperand     The right operand.
118  */
119 BPatch_arithExpr::BPatch_arithExpr(BPatch_binOp op,
120         const BPatch_snippet &lOperand, const BPatch_snippet &rOperand)
121 {
122     assert(BPatch::bpatch != NULL);
123
124     opCode astOp;
125     switch(op) {
126       case BPatch_assign:
127         astOp = storeOp;
128         break;
129       case BPatch_plus:
130         astOp = plusOp;
131         break;
132       case BPatch_minus:
133         astOp = minusOp;
134         break;
135       case BPatch_divide:
136         astOp = divOp;
137         break;
138       case BPatch_times:
139         astOp = timesOp;
140         break;
141       case BPatch_mod:
142         /* XXX Not yet implemented. */
143         assert(0);
144         break;
145       case BPatch_ref:
146         /* XXX Not yet implemented. */
147         assert(0);
148         break;
149       case BPatch_seq:
150         ast = new AstNode(lOperand.ast, rOperand.ast);
151         ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
152         return;
153       default:
154         /* XXX handle error */
155         assert(0);
156     };
157
158     ast = new AstNode(astOp, lOperand.ast, rOperand.ast);
159     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
160 }
161
162
163 /*
164  * BPatch_boolExpr::BPatch_boolExpr
165  *
166  * Constructs a snippet representing a boolean expression.
167  *
168  * op           The operator for the boolean expression.
169  * lOperand     The left operand.
170  * rOperand     The right operand.
171  */
172 BPatch_boolExpr::BPatch_boolExpr(BPatch_relOp op,
173                                  const BPatch_snippet &lOperand,
174                                  const BPatch_snippet &rOperand)
175 {
176     opCode astOp;
177     switch(op) {
178       case BPatch_lt:
179         astOp = lessOp;
180         break;
181       case BPatch_eq:
182         astOp = eqOp;
183         break;
184       case BPatch_gt:
185         astOp = greaterOp;
186         break;
187       case BPatch_le:
188         astOp = leOp;
189         break;
190       case BPatch_ne:
191         astOp = neOp;
192         break;
193       case BPatch_ge:
194         astOp = geOp;
195         break;
196       case BPatch_and:
197         astOp = andOp;
198         break;
199       case BPatch_or:
200         astOp = orOp;
201         break;
202       default:
203         /* XXX Handle the error case here */
204         assert( 0 );
205     };
206     
207     ast = new AstNode(astOp, lOperand.ast, rOperand.ast);
208     assert(BPatch::bpatch != NULL);
209     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
210 }
211
212
213 /*
214  * BPatch_constExpr::BPatch_constExpr
215  *
216  * Constructs a snippet representing a constant integer value.
217  *
218  * value        The desired value.
219  */
220 BPatch_constExpr::BPatch_constExpr(int value)
221 {
222     ast = new AstNode(AstNode::Constant, (void *)value);
223
224     assert(BPatch::bpatch != NULL);
225     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
226
227     BPatch_type *type = BPatch::bpatch->stdTypes->findType("int");
228     assert(type != NULL);
229
230     ast->setType(type);
231 }
232
233
234 /*
235  * BPatch_constExpr::BPatch_constExpr
236  *
237  * Constructs a snippet representing a constant string value.
238  *
239  * value        The desired constant string.
240  */
241 BPatch_constExpr::BPatch_constExpr(const char *value)
242 {
243     ast = new AstNode(AstNode::ConstantString, (void *)value);
244
245     assert(BPatch::bpatch != NULL);
246     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
247
248     BPatch_type *type = BPatch::bpatch->stdTypes->findType("char *");
249     assert(type != NULL);
250
251     ast->setType(type);
252 }
253
254
255 /*
256  * BPatch_funcCallExpr::BPatch_funcCallExpr
257  *
258  * Constructs a snippet representing a function call.
259  *
260  * func         Identifies the function to call.
261  * args         A vector of the arguments to be passed to the function.
262  */
263 BPatch_funcCallExpr::BPatch_funcCallExpr(
264     const BPatch_function &func,
265     const BPatch_Vector<BPatch_snippet *> &args)
266 {
267     vector<AstNode *> ast_args;
268
269     for (int i = 0; i < args.size(); i++)
270         ast_args += assignAst(args[i]->ast);
271
272     ast = new AstNode(func.func->prettyName(), ast_args);
273
274     for (int i = 0; i < args.size(); i++)
275         removeAst(ast_args[i]);
276
277     assert(BPatch::bpatch != NULL);
278     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
279 }
280
281
282 /*
283  * BPatch_ifExpr::BPatch_ifExpr
284  *
285  * Constructs a snippet representing a conditional expression.
286  *
287  * conditional          The conditional.
288  * tClause              A snippet to execute if the conditional is true.
289  */
290 BPatch_ifExpr::BPatch_ifExpr(const BPatch_boolExpr &conditional,
291                              const BPatch_snippet &tClause)
292 {
293     ast = new AstNode(ifOp, conditional.ast, tClause.ast);
294
295     assert(BPatch::bpatch != NULL);
296     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
297 }
298
299
300 /*
301  * BPatch_ifExpr::BPatch_ifExpr
302  *
303  * Constructs a snippet representing a conditional expression with an else
304  * clause.
305  *
306  * conditional          The conditional.
307  * tClause              A snippet to execute if the conditional is true.
308  */
309 BPatch_ifExpr::BPatch_ifExpr(const BPatch_boolExpr &conditional,
310                              const BPatch_snippet &tClause,
311                              const BPatch_snippet &fClause)
312 {
313     ast = new AstNode(ifOp, conditional.ast, tClause.ast, fClause.ast);
314
315     assert(BPatch::bpatch != NULL);
316     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
317 }
318
319
320 /*
321  * BPatch_nullExpr::BPatch_nullExpr
322  *
323  * Construct a null snippet that can be used as a placeholder.
324  */
325 BPatch_nullExpr::BPatch_nullExpr()
326 {
327     ast = new AstNode;
328
329     assert(BPatch::bpatch != NULL);
330     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
331 }
332
333
334 /*
335  * BPatch_paramExpr::BPatch_paramExpr
336  *
337  * Construct a snippet representing a parameter of the function in which
338  * the snippet is inserted.
339  *
340  * n    The position of the parameter (0 is the first parameter, 1 the second,
341  *      and so on).
342  */
343 BPatch_paramExpr::BPatch_paramExpr(int n)
344 {
345     ast = new AstNode(AstNode::Param, (void *)n);
346
347     assert(BPatch::bpatch != NULL);
348     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
349 }
350
351
352 /*
353  * BPatch_retExpr::BPatch_retExpr
354  *
355  * Construct a snippet representing a return value from the function in which
356  * the snippet is inserted.
357  *
358  */
359 BPatch_retExpr::BPatch_retExpr()
360 {
361     ast = new AstNode(AstNode::ReturnVal, (void *)0);
362
363     assert(BPatch::bpatch != NULL);
364     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
365 }
366
367 /*
368  * BPatch_sequence::BPatch_sequence
369  *
370  * Construct a snippet representing a sequence of snippets.
371  *
372  * items        The snippets that are to make up the sequence.
373  */
374 BPatch_sequence::BPatch_sequence(const BPatch_Vector<BPatch_snippet *> &items)
375 {
376     if (items.size() == 0) {
377         // XXX do something to indicate an error
378         return;
379     }
380
381     assert(BPatch::bpatch != NULL);
382
383     ast = new AstNode(items[0]->ast);
384     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
385
386     for (int i = 1; i < items.size(); i++) {
387         AstNode *tempAst = new AstNode(ast, items[i]->ast);
388         tempAst->setTypeChecking(BPatch::bpatch->isTypeChecked());
389         removeAst(ast);
390         ast = tempAst;
391     }
392 }
393
394
395 /*
396  * BPatch_variableExpr::BPatch_variableExpr
397  *
398  * Construct a snippet representing a variable at the given address.
399  *
400  * in_address   The address of the variable in the inferior's address space.
401  */
402 BPatch_variableExpr::BPatch_variableExpr(void *in_address,
403                                          const BPatch_type *type) :
404     address(in_address)
405 {
406     ast = new AstNode(AstNode::DataAddr, address);
407
408     assert(BPatch::bpatch != NULL);
409     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
410
411     ast->setType(type);
412 }
413
414 /**************************************************************************
415  * BPatch_function
416  *************************************************************************/
417
418 /*
419  * BPatch_function::getName
420  *
421  * Copies the name of the function into a buffer, up to a given maximum
422  * length.  Returns a pointer to the beginning of the buffer that was
423  * passed in.
424  *
425  * s            The buffer into which the name will be copied.
426  * len          The size of the buffer.
427  */
428 char *BPatch_function::getName(char *s, int len)
429 {
430     assert(func);
431     string name = func->prettyName();
432     strncpy(s, name.string_of(), len);
433
434     return s;
435 }