KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > bcel > internal > util > BCELFactory


1 package com.sun.org.apache.bcel.internal.util;
2
3 import com.sun.org.apache.bcel.internal.generic.*;
4 import com.sun.org.apache.bcel.internal.classfile.Utility;
5 import com.sun.org.apache.bcel.internal.Constants;
6 import java.io.PrintWriter JavaDoc;
7 import java.util.*;
8
9 /* ====================================================================
10  * The Apache Software License, Version 1.1
11  *
12  * Copyright (c) 2002 The Apache Software Foundation. All rights
13  * reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  *
19  * 1. Redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer.
21  *
22  * 2. Redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in
24  * the documentation and/or other materials provided with the
25  * distribution.
26  *
27  * 3. The end-user documentation included with the redistribution,
28  * if any, must include the following acknowledgment:
29  * "This product includes software developed by the
30  * Apache Software Foundation (http://www.apache.org/)."
31  * Alternately, this acknowledgment may appear in the software itself,
32  * if and wherever such third-party acknowledgments normally appear.
33  *
34  * 4. The names "Apache" and "Apache Software Foundation" and
35  * "Apache BCEL" must not be used to endorse or promote products
36  * derived from this software without prior written permission. For
37  * written permission, please contact apache@apache.org.
38  *
39  * 5. Products derived from this software may not be called "Apache",
40  * "Apache BCEL", nor may "Apache" appear in their name, without
41  * prior written permission of the Apache Software Foundation.
42  *
43  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
44  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
45  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
47  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
50  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
53  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54  * SUCH DAMAGE.
55  * ====================================================================
56  *
57  * This software consists of voluntary contributions made by many
58  * individuals on behalf of the Apache Software Foundation. For more
59  * information on the Apache Software Foundation, please see
60  * <http://www.apache.org/>.
61  */

62
63 /**
64  * Factory creates il.append() statements, and sets instruction targets.
65  * A helper class for BCELifier.
66  *
67  * @see BCELifier
68  * @version $Id: BCELFactory.java,v 1.1.2.1 2005/07/31 23:46:58 jeffsuttor Exp $
69  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
70  */

71 class BCELFactory extends EmptyVisitor {
72   private MethodGen _mg;
73   private PrintWriter JavaDoc _out;
74   private ConstantPoolGen _cp;
75
76   BCELFactory(MethodGen mg, PrintWriter JavaDoc out) {
77     _mg = mg;
78     _cp = mg.getConstantPool();
79     _out = out;
80   }
81
82   private HashMap branch_map = new HashMap(); // Map<Instruction, InstructionHandle>
83

84   public void start() {
85     if(!_mg.isAbstract() && !_mg.isNative()) {
86       for(InstructionHandle ih = _mg.getInstructionList().getStart();
87       ih != null; ih = ih.getNext()) {
88     Instruction i = ih.getInstruction();
89
90     if(i instanceof BranchInstruction) {
91       branch_map.put(i, ih); // memorize container
92
}
93
94     if(ih.hasTargeters()) {
95       if(i instanceof BranchInstruction) {
96         _out.println(" InstructionHandle ih_" + ih.getPosition() + ";");
97       } else {
98         _out.print(" InstructionHandle ih_" + ih.getPosition() + " = ");
99       }
100     } else {
101       _out.print(" ");
102     }
103
104     if(!visitInstruction(i))
105       i.accept(this);
106       }
107
108       updateBranchTargets();
109       updateExceptionHandlers();
110     }
111   }
112
113   private boolean visitInstruction(Instruction i) {
114     short opcode = i.getOpcode();
115     
116     if((InstructionConstants.INSTRUCTIONS[opcode] != null) &&
117        !(i instanceof ConstantPushInstruction) &&
118        !(i instanceof ReturnInstruction)) { // Handled below
119
_out.println("il.append(InstructionConstants." +
120            i.getName().toUpperCase() + ");");
121       return true;
122     }
123
124     return false;
125   }
126
127   public void visitLocalVariableInstruction(LocalVariableInstruction i) {
128     short opcode = i.getOpcode();
129     Type type = i.getType(_cp);
130
131     if(opcode == Constants.IINC) {
132       _out.println("il.append(new IINC(" + i.getIndex() + ", " +
133            ((IINC)i).getIncrement() + "));");
134     } else {
135       String JavaDoc kind = (opcode < Constants.ISTORE)? "Load" : "Store";
136       _out.println("il.append(_factory.create" + kind + "(" +
137            BCELifier.printType(type) + ", " +
138            i.getIndex() + "));");
139     }
140   }
141
142   public void visitArrayInstruction(ArrayInstruction i) {
143     short opcode = i.getOpcode();
144     Type type = i.getType(_cp);
145     String JavaDoc kind = (opcode < Constants.IASTORE)? "Load" : "Store";
146
147     _out.println("il.append(_factory.createArray" + kind + "(" +
148          BCELifier.printType(type) + "));");
149   }
150
151   public void visitFieldInstruction(FieldInstruction i) {
152     short opcode = i.getOpcode();
153
154     String JavaDoc class_name = i.getClassName(_cp);
155     String JavaDoc field_name = i.getFieldName(_cp);
156     Type type = i.getFieldType(_cp);
157
158     _out.println("il.append(_factory.createFieldAccess(\"" +
159          class_name + "\", \"" + field_name + "\", " +
160          BCELifier.printType(type) + ", " +
161          "Constants." + Constants.OPCODE_NAMES[opcode].toUpperCase() +
162          "));");
163   }
164
165   public void visitInvokeInstruction(InvokeInstruction i) {
166     short opcode = i.getOpcode();
167     String JavaDoc class_name = i.getClassName(_cp);
168     String JavaDoc method_name = i.getMethodName(_cp);
169     Type type = i.getReturnType(_cp);
170     Type[] arg_types = i.getArgumentTypes(_cp);
171
172     _out.println("il.append(_factory.createInvoke(\"" +
173          class_name + "\", \"" + method_name + "\", " +
174          BCELifier.printType(type) + ", " +
175          BCELifier.printArgumentTypes(arg_types) + ", " +
176          "Constants." + Constants.OPCODE_NAMES[opcode].toUpperCase() +
177          "));");
178   }
179
180   public void visitAllocationInstruction(AllocationInstruction i) {
181     Type type;
182
183     if(i instanceof CPInstruction) {
184       type = ((CPInstruction)i).getType(_cp);
185     } else {
186       type = ((NEWARRAY)i).getType();
187     }
188
189     short opcode = ((Instruction)i).getOpcode();
190     int dim = 1;
191
192     switch(opcode) {
193     case Constants.NEW:
194       _out.println("il.append(_factory.createNew(\"" +
195            ((ObjectType)type).getClassName() + "\"));");
196       break;
197
198     case Constants.MULTIANEWARRAY:
199       dim = ((MULTIANEWARRAY)i).getDimensions();
200
201     case Constants.ANEWARRAY:
202     case Constants.NEWARRAY:
203       _out.println("il.append(_factory.createNewArray(" +
204            BCELifier.printType(type) + ", (short) " + dim + "));");
205       break;
206
207     default:
208       throw new RuntimeException JavaDoc("Oops: " + opcode);
209     }
210   }
211
212   private void createConstant(Object JavaDoc value) {
213     String JavaDoc embed = value.toString();
214
215     if(value instanceof String JavaDoc)
216       embed = '"' + Utility.convertString(value.toString()) + '"';
217     else if(value instanceof Character JavaDoc)
218       embed = "(char)0x" + Integer.toHexString(((Character JavaDoc)value).charValue());
219
220     _out.println("il.append(new PUSH(_cp, " + embed + "));");
221   }
222
223   public void visitLDC(LDC i) {
224     createConstant(i.getValue(_cp));
225   }
226
227   public void visitLDC2_W(LDC2_W i) {
228     createConstant(i.getValue(_cp));
229   }
230
231   public void visitConstantPushInstruction(ConstantPushInstruction i) {
232     createConstant(i.getValue());
233   }
234
235   public void visitINSTANCEOF(INSTANCEOF i) {
236     Type type = i.getType(_cp);
237
238     _out.println("il.append(new INSTANCEOF(_cp.addClass(" +
239          BCELifier.printType(type) + ")));");
240   }
241
242   public void visitCHECKCAST(CHECKCAST i) {
243     Type type = i.getType(_cp);
244
245     _out.println("il.append(_factory.createCheckCast(" +
246          BCELifier.printType(type) + "));");
247   }
248
249   public void visitReturnInstruction(ReturnInstruction i) {
250     Type type = i.getType(_cp);
251
252     _out.println("il.append(_factory.createReturn(" +
253          BCELifier.printType(type) + "));");
254   }
255
256   // Memorize BranchInstructions that need an update
257
private ArrayList branches = new ArrayList();
258
259   public void visitBranchInstruction(BranchInstruction bi) {
260     BranchHandle bh = (BranchHandle)branch_map.get(bi);
261     int pos = bh.getPosition();
262     String JavaDoc name = bi.getName() + "_" + pos;
263
264     if(bi instanceof Select) {
265       Select s = (Select)bi;
266       branches.add(bi);
267
268       StringBuffer JavaDoc args = new StringBuffer JavaDoc("new int[] { ");
269       int[] matchs = s.getMatchs();
270
271       for(int i=0; i < matchs.length; i++) {
272     args.append(matchs[i]);
273
274     if(i < matchs.length - 1)
275       args.append(", ");
276       }
277
278       args.append(" }");
279       
280       _out.print(" Select " + name + " = new " +
281          bi.getName().toUpperCase() + "(" + args +
282          ", new InstructionHandle[] { ");
283     
284       for(int i=0; i < matchs.length; i++) {
285     _out.print("null");
286     
287     if(i < matchs.length - 1)
288       _out.print(", ");
289       }
290
291       _out.println(");");
292     } else {
293       int t_pos = bh.getTarget().getPosition();
294       String JavaDoc target;
295
296       if(pos > t_pos) {
297     target = "ih_" + t_pos;
298       } else {
299     branches.add(bi);
300     target = "null";
301       }
302
303       _out.println(" BranchInstruction " + name +
304            " = _factory.createBranchInstruction(" +
305            "Constants." + bi.getName().toUpperCase() + ", " +
306            target + ");");
307     }
308
309     if(bh.hasTargeters())
310       _out.println(" ih_" + pos + " = il.append(" + name + ");");
311     else
312       _out.println(" il.append(" + name + ");");
313   }
314
315   public void visitRET(RET i) {
316     _out.println("il.append(new RET(" + i.getIndex() + ")));");
317   }
318
319   private void updateBranchTargets() {
320     for(Iterator i = branches.iterator(); i.hasNext(); ) {
321       BranchInstruction bi = (BranchInstruction)i.next();
322       BranchHandle bh = (BranchHandle)branch_map.get(bi);
323       int pos = bh.getPosition();
324       String JavaDoc name = bi.getName() + "_" + pos;
325       int t_pos = bh.getTarget().getPosition();
326
327       _out.println(" " + name + ".setTarget(ih_" + t_pos + ");");
328
329       if(bi instanceof Select) {
330     InstructionHandle[] ihs = ((Select)bi).getTargets();
331
332     for(int j = 0; j < ihs.length; j++) {
333       t_pos = ihs[j].getPosition();
334
335       _out.println(" " + name + ".setTarget(" + j +
336                ", ih_" + t_pos + ");");
337     }
338       }
339     }
340   }
341
342   private void updateExceptionHandlers() {
343     CodeExceptionGen[] handlers = _mg.getExceptionHandlers();
344
345     for(int i=0; i < handlers.length; i++) {
346       CodeExceptionGen h = handlers[i];
347       String JavaDoc type = (h.getCatchType() == null)?
348     "null" : BCELifier.printType(h.getCatchType());
349
350       _out.println(" method.addExceptionHandler(" +
351            "ih_" + h.getStartPC().getPosition() + ", " +
352            "ih_" + h.getEndPC().getPosition() + ", " +
353            "ih_" + h.getHandlerPC().getPosition() + ", " +
354            type + ");");
355     }
356   }
357 }
358
Popular Tags