001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package EDU.purdue.cs.bloat.tree;
022:
023: import java.io.*;
024: import java.util.*;
025:
026: import EDU.purdue.cs.bloat.cfg.*;
027:
028: /**
029: * PrintVistor traverses a Tree and prints some information about each visited
030: * Node to a stream.
031: */
032: public class PrintVisitor extends TreeVisitor {
033:
034: protected PrintWriter out; // The stream to which we are printing
035:
036: /**
037: * Constructor. Prints to System.out.
038: */
039: public PrintVisitor() {
040: this (System.out);
041: }
042:
043: public PrintVisitor(final Writer out) {
044: this .out = new PrintWriter(out);
045: }
046:
047: public PrintVisitor(final PrintStream out) {
048: this .out = new PrintWriter(out);
049: }
050:
051: protected void println() {
052: out.println();
053: }
054:
055: protected void println(final Object s) {
056: out.println(s);
057: }
058:
059: protected void print(final Object s) {
060: out.print(s);
061: }
062:
063: public void visitFlowGraph(final FlowGraph cfg) {
064: cfg.source().visit(this );
065:
066: final Iterator e = cfg.trace().iterator();
067:
068: while (e.hasNext()) {
069: final Block block = (Block) e.next();
070: block.visit(this );
071: }
072:
073: cfg.sink().visit(this );
074:
075: this .out.flush();
076: }
077:
078: public void visitBlock(final Block block) {
079: println();
080: println(block);
081:
082: final Handler handler = (Handler) block.graph().handlersMap()
083: .get(block);
084:
085: if (handler != null) {
086: println("catches " + handler.catchType());
087: println("protects " + handler.protectedBlocks());
088: }
089:
090: block.visitChildren(this );
091: }
092:
093: public void visitExprStmt(final ExprStmt stmt) {
094: print("eval ");
095: stmt.expr().visit(this );
096: println();
097: }
098:
099: public void visitIfZeroStmt(final IfZeroStmt stmt) {
100: print("if0 (");
101: stmt.expr().visit(this );
102: print(" ");
103:
104: switch (stmt.comparison()) {
105: case IfStmt.EQ:
106: print("==");
107: break;
108: case IfStmt.NE:
109: print("!=");
110: break;
111: case IfStmt.GT:
112: print(">");
113: break;
114: case IfStmt.GE:
115: print(">=");
116: break;
117: case IfStmt.LT:
118: print("<");
119: break;
120: case IfStmt.LE:
121: print("<=");
122: break;
123: }
124:
125: if (stmt.expr().type().isReference()) {
126: print(" null");
127: } else {
128: print(" 0");
129: }
130:
131: print(") then " + stmt.trueTarget() + " else "
132: + stmt.falseTarget());
133: println(" caught by " + stmt.catchTargets());
134: }
135:
136: public void visitIfCmpStmt(final IfCmpStmt stmt) {
137: print("if (");
138: stmt.left().visit(this );
139: print(" ");
140:
141: switch (stmt.comparison()) {
142: case IfStmt.EQ:
143: print("==");
144: break;
145: case IfStmt.NE:
146: print("!=");
147: break;
148: case IfStmt.GT:
149: print(">");
150: break;
151: case IfStmt.GE:
152: print(">=");
153: break;
154: case IfStmt.LT:
155: print("<");
156: break;
157: case IfStmt.LE:
158: print("<=");
159: break;
160: }
161:
162: print(" ");
163:
164: if (stmt.right() != null) {
165: stmt.right().visit(this );
166: }
167:
168: print(") then " + stmt.trueTarget() + " else "
169: + stmt.falseTarget());
170: println(" caught by " + stmt.catchTargets());
171: }
172:
173: public void visitInitStmt(final InitStmt stmt) {
174: print("INIT");
175:
176: final LocalExpr[] t = stmt.targets();
177:
178: if (t != null) {
179: for (int i = 0; i < t.length; i++) {
180: if (t[i] != null) {
181: print(" ");
182: t[i].visit(this );
183: }
184: }
185: }
186:
187: println();
188: }
189:
190: public void visitGotoStmt(final GotoStmt stmt) {
191: print("goto " + stmt.target().label());
192: println(" caught by " + stmt.catchTargets());
193: }
194:
195: public void visitLabelStmt(final LabelStmt stmt) {
196: if (stmt.label() != null) {
197: println(stmt.label());
198: }
199: }
200:
201: public void visitMonitorStmt(final MonitorStmt stmt) {
202: if (stmt.kind() == MonitorStmt.ENTER) {
203: print("enter ");
204: } else {
205: print("exit ");
206: }
207:
208: print("monitor (");
209:
210: if (stmt.object() != null) {
211: stmt.object().visit(this );
212: }
213:
214: println(")");
215: }
216:
217: public void visitCatchExpr(final CatchExpr expr) {
218: print("Catch(" + expr.catchType() + ")");
219: }
220:
221: public void visitStackManipStmt(final StackManipStmt stmt) {
222: print("(");
223:
224: final StackExpr[] target = stmt.target();
225:
226: if (target != null) {
227: for (int i = 0; i < target.length; i++) {
228: target[i].visit(this );
229: if (i != target.length - 1) {
230: print(", ");
231: }
232: }
233: }
234:
235: final String[] str = new String[] { "swap", "dup", "dup_x1",
236: "dup_x2", "dup2", "dup2_x1", "dup2_x2" };
237:
238: print(") := " + str[stmt.kind()] + "(");
239:
240: final StackExpr[] source = stmt.source();
241:
242: if (source != null) {
243: for (int i = 0; i < source.length; i++) {
244: source[i].visit(this );
245: if (i != source.length - 1) {
246: print(", ");
247: }
248: }
249: }
250:
251: println(")");
252: }
253:
254: public void visitPhiJoinStmt(final PhiJoinStmt stmt) {
255: if (stmt.target() != null) {
256: stmt.target().visit(this );
257: }
258:
259: print(" := Phi(");
260:
261: if (stmt.hasParent()) {
262: final Tree tree = (Tree) stmt.parent();
263: final Block block = tree.block();
264:
265: final Iterator e = block.graph().preds(block).iterator();
266:
267: while (e.hasNext()) {
268: final Block pred = (Block) e.next();
269:
270: final Expr operand = stmt.operandAt(pred);
271: print(pred.label() + "=");
272: operand.visit(this );
273:
274: if (e.hasNext()) {
275: print(", ");
276: }
277: }
278: } else {
279: final Iterator e = stmt.operands().iterator();
280:
281: while (e.hasNext()) {
282: final Expr operand = (Expr) e.next();
283: operand.visit(this );
284:
285: if (e.hasNext()) {
286: print(", ");
287: }
288: }
289: }
290:
291: println(")");
292: }
293:
294: public void visitPhiCatchStmt(final PhiCatchStmt stmt) {
295: if (stmt.target() != null) {
296: stmt.target().visit(this );
297: }
298:
299: print(" := Phi-Catch(");
300:
301: final Iterator e = stmt.operands().iterator();
302:
303: while (e.hasNext()) {
304: final Expr operand = (Expr) e.next();
305: operand.visit(this );
306:
307: if (e.hasNext()) {
308: print(", ");
309: }
310: }
311:
312: println(")");
313: }
314:
315: public void visitRetStmt(final RetStmt stmt) {
316: print("ret from " + stmt.sub());
317: println(" caught by " + stmt.catchTargets());
318: }
319:
320: public void visitReturnExprStmt(final ReturnExprStmt stmt) {
321: print("return ");
322:
323: if (stmt.expr() != null) {
324: stmt.expr().visit(this );
325: }
326:
327: println(" caught by " + stmt.catchTargets());
328: }
329:
330: public void visitReturnStmt(final ReturnStmt stmt) {
331: print("return");
332: println(" caught by " + stmt.catchTargets());
333: }
334:
335: public void visitStoreExpr(final StoreExpr expr) {
336: print("(");
337:
338: if (expr.target() != null) {
339: expr.target().visit(this );
340: }
341:
342: print(" := ");
343:
344: if (expr.expr() != null) {
345: expr.expr().visit(this );
346: }
347:
348: print(")");
349: }
350:
351: public void visitAddressStoreStmt(final AddressStoreStmt stmt) {
352: print("La");
353:
354: if (stmt.sub() != null) {
355: print(new Integer(stmt.sub().returnAddress().index()));
356: } else {
357: print("???");
358: }
359:
360: println(" := returnAddress");
361: }
362:
363: public void visitJsrStmt(final JsrStmt stmt) {
364: print("jsr ");
365:
366: if (stmt.sub() != null) {
367: print(stmt.sub().entry());
368: }
369:
370: if (stmt.follow() != null) {
371: print(" ret to " + stmt.follow());
372: }
373:
374: println(" caught by " + stmt.catchTargets());
375: }
376:
377: public void visitSwitchStmt(final SwitchStmt stmt) {
378: print("switch (");
379:
380: if (stmt.index() != null) {
381: stmt.index().visit(this );
382: }
383:
384: print(")");
385: println(" caught by " + stmt.catchTargets());
386:
387: if ((stmt.values() != null) && (stmt.targets() != null)) {
388: for (int i = 0; i < stmt.values().length; i++) {
389: println(" case " + stmt.values()[i] + ": "
390: + stmt.targets()[i]);
391: }
392: }
393:
394: println(" default: " + stmt.defaultTarget());
395: }
396:
397: public void visitThrowStmt(final ThrowStmt stmt) {
398: print("throw ");
399:
400: if (stmt.expr() != null) {
401: stmt.expr().visit(this );
402: }
403:
404: println(" caught by " + stmt.catchTargets());
405: }
406:
407: public void visitSCStmt(final SCStmt stmt) {
408: print("aswizzle ");
409: if (stmt.array() != null) {
410: stmt.array().visit(this );
411: }
412: if (stmt.index() != null) {
413: stmt.index().visit(this );
414: }
415: }
416:
417: public void visitSRStmt(final SRStmt stmt) {
418: print("aswrange array: ");
419: if (stmt.array() != null) {
420: stmt.array().visit(this );
421: }
422: print(" start: ");
423: if (stmt.start() != null) {
424: stmt.start().visit(this );
425: }
426: print(" end: ");
427: if (stmt.end() != null) {
428: stmt.end().visit(this );
429: }
430: println("");
431: }
432:
433: public void visitArithExpr(final ArithExpr expr) {
434: print("(");
435:
436: if (expr.left() != null) {
437: expr.left().visit(this );
438: }
439:
440: print(" ");
441:
442: switch (expr.operation()) {
443: case ArithExpr.ADD:
444: print("+");
445: break;
446: case ArithExpr.SUB:
447: print("-");
448: break;
449: case ArithExpr.DIV:
450: print("/");
451: break;
452: case ArithExpr.MUL:
453: print("*");
454: break;
455: case ArithExpr.REM:
456: print("%");
457: break;
458: case ArithExpr.AND:
459: print("&");
460: break;
461: case ArithExpr.IOR:
462: print("|");
463: break;
464: case ArithExpr.XOR:
465: print("^");
466: break;
467: case ArithExpr.CMP:
468: print("<=>");
469: break;
470: case ArithExpr.CMPL:
471: print("<l=>");
472: break;
473: case ArithExpr.CMPG:
474: print("<g=>");
475: break;
476: }
477:
478: print(" ");
479: if (expr.right() != null) {
480: expr.right().visit(this );
481: }
482: print(")");
483: }
484:
485: public void visitArrayLengthExpr(final ArrayLengthExpr expr) {
486: if (expr.array() != null) {
487: expr.array().visit(this );
488: }
489: print(".length");
490: }
491:
492: public void visitArrayRefExpr(final ArrayRefExpr expr) {
493: if (expr.array() != null) {
494: expr.array().visit(this );
495: }
496: print("[");
497: if (expr.index() != null) {
498: expr.index().visit(this );
499: }
500: print("]");
501: }
502:
503: public void visitCallMethodExpr(final CallMethodExpr expr) {
504: if (expr.receiver() != null) {
505: expr.receiver().visit(this );
506: }
507:
508: print(".");
509: if (expr.method() != null) {
510: print(expr.method().nameAndType().name());
511: }
512: print("(");
513:
514: if (expr.params() != null) {
515: for (int i = 0; i < expr.params().length; i++) {
516: expr.params()[i].visit(this );
517: if (i != expr.params().length - 1) {
518: print(", ");
519: }
520: }
521: }
522:
523: print(")");
524: }
525:
526: public void visitCallStaticExpr(final CallStaticExpr expr) {
527: if (expr.method() != null) {
528: print(expr.method().declaringClass());
529: }
530:
531: print(".");
532: if (expr.method() != null) {
533: print(expr.method().nameAndType().name());
534: }
535: print("(");
536:
537: if (expr.params() != null) {
538: for (int i = 0; i < expr.params().length; i++) {
539: expr.params()[i].visit(this );
540: if (i != expr.params().length - 1) {
541: print(", ");
542: }
543: }
544: }
545:
546: print(")");
547: }
548:
549: public void visitCastExpr(final CastExpr expr) {
550: print("((" + expr.castType() + ") ");
551: if (expr.expr() != null) {
552: expr.expr().visit(this );
553: }
554: print(")");
555: }
556:
557: public void visitConstantExpr(final ConstantExpr expr) {
558: if (expr.value() instanceof String) {
559: final StringBuffer sb = new StringBuffer();
560:
561: final String s = (String) expr.value();
562:
563: for (int i = 0; i < s.length(); i++) {
564: final char c = s.charAt(i);
565: if (Character.isWhitespace(c)
566: || ((0x20 <= c) && (c <= 0x7e))) {
567: sb.append(c);
568: } else {
569: sb.append("\\u");
570: sb.append(Integer.toHexString(c));
571: }
572:
573: if (sb.length() > 50) {
574: sb.append("...");
575: break;
576: }
577: }
578:
579: print("'" + sb.toString() + "'");
580: } else if (expr.value() instanceof Float) {
581: print(expr.value() + "F");
582: } else if (expr.value() instanceof Long) {
583: print(expr.value() + "L");
584: } else {
585: print(expr.value());
586: }
587: }
588:
589: public void visitFieldExpr(final FieldExpr expr) {
590: if (expr.object() != null) {
591: expr.object().visit(this );
592: }
593: print(".");
594: if (expr.field() != null) {
595: print(expr.field().nameAndType().name());
596: }
597: }
598:
599: public void visitInstanceOfExpr(final InstanceOfExpr expr) {
600: if (expr.expr() != null) {
601: expr.expr().visit(this );
602: }
603: print(" instanceof " + expr.checkType());
604: }
605:
606: public void visitLocalExpr(final LocalExpr expr) {
607: if (expr.fromStack()) {
608: print("T");
609: } else {
610: print("L");
611: }
612:
613: print(expr.type().shortName().toLowerCase());
614: print(Integer.toString(expr.index()));
615:
616: final DefExpr def = expr.def();
617:
618: if ((def == null) || (def.version() == -1)) {
619: print("_undef");
620:
621: } else {
622: print("_" + def.version());
623: }
624: }
625:
626: public void visitNegExpr(final NegExpr expr) {
627: print("-");
628: if (expr.expr() != null) {
629: expr.expr().visit(this );
630: }
631: }
632:
633: public void visitNewArrayExpr(final NewArrayExpr expr) {
634: print("new " + expr.elementType() + "[");
635: if (expr.size() != null) {
636: expr.size().visit(this );
637: }
638: print("]");
639: }
640:
641: public void visitNewExpr(final NewExpr expr) {
642: print("new " + expr.objectType());
643: }
644:
645: public void visitNewMultiArrayExpr(final NewMultiArrayExpr expr) {
646: print("new " + expr.elementType());
647:
648: if (expr.dimensions() != null) {
649: for (int i = 0; i < expr.dimensions().length; i++) {
650: print("[" + expr.dimensions()[i] + "]");
651: }
652: }
653: }
654:
655: public void visitZeroCheckExpr(final ZeroCheckExpr expr) {
656: if (expr.expr().type().isReference()) {
657: print("notNull(");
658: } else {
659: print("notZero(");
660: }
661:
662: if (expr.expr() != null) {
663: expr.expr().visit(this );
664: }
665:
666: print(")");
667: }
668:
669: public void visitRCExpr(final RCExpr expr) {
670: print("rc(");
671: if (expr.expr() != null) {
672: expr.expr().visit(this );
673: }
674: print(")");
675: }
676:
677: public void visitUCExpr(final UCExpr expr) {
678: if (expr.kind() == UCExpr.POINTER) {
679: print("aupdate(");
680: } else {
681: print("supdate(");
682: }
683:
684: if (expr.expr() != null) {
685: expr.expr().visit(this );
686: }
687: print(")");
688: }
689:
690: public void visitReturnAddressExpr(final ReturnAddressExpr expr) {
691: print("returnAddress");
692: }
693:
694: public void visitShiftExpr(final ShiftExpr expr) {
695: print("(");
696: if (expr.expr() != null) {
697: expr.expr().visit(this );
698: }
699:
700: if (expr.dir() == ShiftExpr.LEFT) {
701: print("<<");
702: } else if (expr.dir() == ShiftExpr.RIGHT) {
703: print(">>");
704: } else if (expr.dir() == ShiftExpr.UNSIGNED_RIGHT) {
705: print(">>>");
706: }
707:
708: if (expr.bits() != null) {
709: expr.bits().visit(this );
710: }
711: print(")");
712: }
713:
714: public void visitStackExpr(final StackExpr expr) {
715: print("S" + expr.type().shortName().toLowerCase()
716: + expr.index());
717:
718: final DefExpr def = expr.def();
719:
720: if ((def == null) || (def.version() == -1)) {
721: print("_undef");
722: } else {
723: print("_" + def.version());
724: }
725: }
726:
727: public void visitStaticFieldExpr(final StaticFieldExpr expr) {
728: if (expr.field() != null) {
729: print(expr.field().declaringClass() + "."
730: + expr.field().nameAndType().name());
731: }
732: }
733:
734: public void visitExpr(final Expr expr) {
735: print("EXPR");
736: }
737:
738: public void visitStmt(final Stmt stmt) {
739: print("STMT");
740: }
741: }
|