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.util.*;
024:
025: import EDU.purdue.cs.bloat.util.*;
026:
027: /**
028: * A PhiCatchStmt is used to handle variables that are used inside an exception
029: * handler. Inside a try block a variable may be used several times. It may be
030: * updated, may be invovled in a phi-function, etc. A PhiCatchStmt is placed at
031: * the beginning of each expection handling (catch) block to factor together the
032: * variables that are live within the protected region.
033: */
034: public class PhiCatchStmt extends PhiStmt {
035: ArrayList operands;
036:
037: /**
038: * Constructor.
039: *
040: * @param target
041: * Local variable to which the result of this phi-function is to
042: * be assigned.
043: */
044: public PhiCatchStmt(final LocalExpr target) {
045: super (target);
046: this .operands = new ArrayList();
047: }
048:
049: public void visitForceChildren(final TreeVisitor visitor) {
050: if (visitor.reverse()) {
051: target.visit(visitor);
052: }
053:
054: for (int i = 0; i < operands.size(); i++) {
055: final LocalExpr expr = (LocalExpr) operands.get(i);
056: expr.visit(visitor);
057: }
058:
059: if (!visitor.reverse()) {
060: target.visit(visitor);
061: }
062: }
063:
064: public void visit(final TreeVisitor visitor) {
065: visitor.visitPhiCatchStmt(this );
066: }
067:
068: /**
069: * Searches the list of operands for a local variable.
070: *
071: * @param def
072: * The local variable definition to search for.
073: * @return True, if def is found, otherwise, false.
074: */
075: public boolean hasOperandDef(final LocalExpr def) {
076: for (int i = 0; i < operands.size(); i++) {
077: final LocalExpr expr = (LocalExpr) operands.get(i);
078: if (expr.def() == def) {
079: return true;
080: }
081: }
082:
083: return false;
084: }
085:
086: /**
087: * Add a local variable to the operand list for this phi-function.
088: *
089: * @param operand
090: * An operand of this phi-function.
091: */
092: public void addOperand(final LocalExpr operand) {
093: for (int i = 0; i < operands.size(); i++) {
094: final LocalExpr expr = (LocalExpr) operands.get(i);
095: Assert.isTrue(expr.def() != operand.def());
096: }
097:
098: operands.add(operand);
099: operand.setParent(this );
100: }
101:
102: /**
103: * Returns the operands to this phi-function.
104: */
105: public Collection operands() {
106: if (operands == null) {
107: return new ArrayList();
108: }
109:
110: for (int i = 0; i < operands.size(); i++) {
111: final LocalExpr ei = (LocalExpr) operands.get(i);
112:
113: for (int j = operands.size() - 1; j > i; j--) {
114: final LocalExpr ej = (LocalExpr) operands.get(j);
115:
116: if (ei.def() == ej.def()) {
117: ej.cleanup();
118: operands.remove(j);
119: }
120: }
121: }
122:
123: return operands;
124: }
125:
126: /**
127: * Returns the number of operands to this phi-function.
128: */
129: public int numOperands() {
130: return operands.size();
131: }
132:
133: /**
134: * Sets the value of one of this phi-function's operands.
135: *
136: * @param i
137: * The number parameter to set.
138: * @param expr
139: * The new value of the parameter.
140: */
141: public void setOperandAt(final int i, final Expr expr) {
142: final Expr old = (Expr) operands.get(i);
143: old.cleanup();
144: operands.set(i, expr);
145: expr.setParent(this );
146: }
147:
148: /**
149: * Returns the operand at a given index.
150: */
151: public Expr operandAt(final int i) {
152: return (Expr) operands.get(i);
153: }
154: }
|