Added features to dyninstAPI library, including the ability to delete
[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 "ast.h"
43 #include "symtab.h"
44 #include "perfStream.h"
45
46 #include "BPatch.h"
47 #include "BPatch_snippet.h"
48 #include "BPatch_type.h"
49
50
51 /*
52  * BPatch_snippet::BPatch_snippet
53  *
54  * Copy constructor for BPatch_snippet.
55  */
56 BPatch_snippet::BPatch_snippet(const BPatch_snippet &src)
57 {
58     ast = assignAst(src.ast);
59 }
60
61
62 /*
63  * BPatch_snippet::operator=
64  *
65  * Assignment operator for BPatch_snippet.  Needed to ensure that the
66  * reference counts for the asts contained in the snippets is correct.
67  */
68 BPatch_snippet &BPatch_snippet::operator=(const BPatch_snippet &src)
69 {
70     // Check for x = x
71     if (&src == this)
72         return *this;
73
74     // Since we're copying over this snippet, release the old AST
75     if (ast != NULL)
76         removeAst(ast);
77
78     // We'll now contain another reference to the ast in the other snippet
79     ast = assignAst(src.ast);
80
81     return *this;
82 }
83
84
85 /*
86  * BPatch_snippet:getCost
87  *
88  * Returns the estimated cost of executing the snippet, in seconds.
89  */
90 float BPatch_snippet::getCost()
91 {
92     return (double)ast->cost() / cyclesPerSecond;
93 }
94
95
96 /*
97  * BPatch_snippet::~BPatch_snippet
98  *
99  * Destructor for BPatch_snippet.  Deallocates memory allocated by the
100  * snippet.
101  */
102 BPatch_snippet::~BPatch_snippet()
103 {
104     // if (ast != NULL)
105         // removeAst(ast);
106 }
107
108
109 /*
110  * BPatch_arithExpr::BPatch_arithExpr
111  *
112  * Construct a snippet representing a binary arithmetic operation.
113  *
114  * op           The desired operation.
115  * lOperand     The left operand for the operation.
116  * rOperand     The right operand.
117  */
118 BPatch_arithExpr::BPatch_arithExpr(BPatch_binOp op,
119         const BPatch_snippet &lOperand, const BPatch_snippet &rOperand)
120 {
121     assert(BPatch::bpatch != NULL);
122
123     opCode astOp;
124     switch(op) {
125       case BPatch_assign:
126         astOp = storeOp;
127         break;
128       case BPatch_plus:
129         astOp = plusOp;
130         break;
131       case BPatch_minus:
132         astOp = minusOp;
133         break;
134       case BPatch_divide:
135         astOp = divOp;
136         break;
137       case BPatch_times:
138         astOp = timesOp;
139         break;
140       case BPatch_mod:
141         /* XXX Not yet implemented. */
142         assert(0);
143         break;
144       case BPatch_ref:
145         /* XXX Not yet implemented. */
146         assert(0);
147         break;
148       case BPatch_seq:
149         ast = new AstNode(lOperand.ast, rOperand.ast);
150         ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
151         return;
152       default:
153         /* XXX handle error */
154         assert(0);
155     };
156
157     ast = new AstNode(astOp, lOperand.ast, rOperand.ast);
158     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
159 }
160
161
162 /*
163  * BPatch_boolExpr::BPatch_boolExpr
164  *
165  * Constructs a snippet representing a boolean expression.
166  *
167  * op           The operator for the boolean expression.
168  * lOperand     The left operand.
169  * rOperand     The right operand.
170  */
171 BPatch_boolExpr::BPatch_boolExpr(BPatch_relOp op,
172                                  const BPatch_snippet &lOperand,
173                                  const BPatch_snippet &rOperand)
174 {
175     opCode astOp;
176     switch(op) {
177       case BPatch_lt:
178         astOp = lessOp;
179         break;
180       case BPatch_eq:
181         astOp = eqOp;
182         break;
183       case BPatch_gt:
184         astOp = greaterOp;
185         break;
186       case BPatch_le:
187         astOp = leOp;
188         break;
189       case BPatch_ne:
190         astOp = neOp;
191         break;
192       case BPatch_ge:
193         astOp = geOp;
194         break;
195       case BPatch_and:
196         astOp = andOp;
197         break;
198       case BPatch_or:
199         astOp = orOp;
200         break;
201       default:
202         /* XXX Handle the error case here */
203         assert( 0 );
204     };
205     
206     ast = new AstNode(astOp, lOperand.ast, rOperand.ast);
207     assert(BPatch::bpatch != NULL);
208     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
209 }
210
211
212 /*
213  * BPatch_constExpr::BPatch_constExpr
214  *
215  * Constructs a snippet representing a constant integer value.
216  *
217  * value        The desired value.
218  */
219 BPatch_constExpr::BPatch_constExpr(int value)
220 {
221     ast = new AstNode(AstNode::Constant, (void *)value);
222
223     assert(BPatch::bpatch != NULL);
224     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
225
226     BPatch_type *type = BPatch::bpatch->stdTypes->findType("int");
227     assert(type != NULL);
228
229     ast->setType(type);
230 }
231
232
233 /*
234  * BPatch_constExpr::BPatch_constExpr
235  *
236  * Constructs a snippet representing a constant string value.
237  *
238  * value        The desired constant string.
239  */
240 BPatch_constExpr::BPatch_constExpr(const char *value)
241 {
242     ast = new AstNode(AstNode::ConstantString, (void *)value);
243
244     assert(BPatch::bpatch != NULL);
245     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
246
247     BPatch_type *type = BPatch::bpatch->stdTypes->findType("char *");
248     assert(type != NULL);
249
250     ast->setType(type);
251 }
252
253
254 /*
255  * BPatch_funcCallExpr::BPatch_funcCallExpr
256  *
257  * Constructs a snippet representing a function call.
258  *
259  * func         Identifies the function to call.
260  * args         A vector of the arguments to be passed to the function.
261  */
262 BPatch_funcCallExpr::BPatch_funcCallExpr(
263     const BPatch_function &func,
264     const BPatch_Vector<BPatch_snippet *> &args)
265 {
266     vector<AstNode *> ast_args;
267
268     for (int i = 0; i < args.size(); i++)
269         ast_args += assignAst(args[i]->ast);
270
271     ast = new AstNode(func.func->prettyName(), ast_args);
272
273     for (int i = 0; i < args.size(); i++)
274         removeAst(ast_args[i]);
275
276     assert(BPatch::bpatch != NULL);
277     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
278 }
279
280
281 /*
282  * BPatch_ifExpr::BPatch_ifExpr
283  *
284  * Constructs a snippet representing a conditional expression.
285  *
286  * conditional          The conditional.
287  * tClause              A snippet to execute if the conditional is true.
288  */
289 BPatch_ifExpr::BPatch_ifExpr(const BPatch_boolExpr &conditional,
290                              const BPatch_snippet &tClause)
291 {
292     ast = new AstNode(ifOp, conditional.ast, tClause.ast);
293
294     assert(BPatch::bpatch != NULL);
295     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
296 }
297
298
299 /*
300  * BPatch_nullExpr::BPatch_nullExpr
301  *
302  * Construct a null snippet that can be used as a placeholder.
303  */
304 BPatch_nullExpr::BPatch_nullExpr()
305 {
306     ast = new AstNode;
307
308     assert(BPatch::bpatch != NULL);
309     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
310 }
311
312
313 /*
314  * BPatch_paramExpr::BPatch_paramExpr
315  *
316  * Construct a snippet representing a parameter of the function in which
317  * the snippet is inserted.
318  *
319  * n    The position of the parameter (0 is the first parameter, 1 the second,
320  *      and so on).
321  */
322 BPatch_paramExpr::BPatch_paramExpr(int n)
323 {
324     ast = new AstNode(AstNode::Param, (void *)n);
325
326     assert(BPatch::bpatch != NULL);
327     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
328 }
329
330
331 /*
332  * BPatch_sequence::BPatch_sequence
333  *
334  * Construct a snippet representing a sequence of snippets.
335  *
336  * items        The snippets that are to make up the sequence.
337  */
338 BPatch_sequence::BPatch_sequence(const BPatch_Vector<BPatch_snippet *> &items)
339 {
340     if (items.size() == 0) {
341         // XXX do something to indicate an error
342         return;
343     }
344
345     assert(BPatch::bpatch != NULL);
346
347     ast = new AstNode(items[0]->ast);
348     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
349
350     for (int i = 1; i < items.size(); i++) {
351         AstNode *tempAst = new AstNode(ast, items[i]->ast);
352         tempAst->setTypeChecking(BPatch::bpatch->isTypeChecked());
353         removeAst(ast);
354         ast = tempAst;
355     }
356 }
357
358
359 /*
360  * BPatch_variableExpr::BPatch_variableExpr
361  *
362  * Construct a snippet representing a variable at the given address.
363  *
364  * in_address   The address of the variable in the inferior's address space.
365  */
366 BPatch_variableExpr::BPatch_variableExpr(void *in_address,
367                                          const BPatch_type *type) :
368     address(in_address)
369 {
370     ast = new AstNode(AstNode::DataAddr, address);
371
372     assert(BPatch::bpatch != NULL);
373     ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
374
375     ast->setType(type);
376 }