KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > bcel > internal > generic > Instruction


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

56
57 import com.sun.org.apache.bcel.internal.Constants;
58 import com.sun.org.apache.bcel.internal.classfile.Utility;
59 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
60 import java.io.*;
61 import com.sun.org.apache.bcel.internal.util.ByteSequence;
62
63 /**
64  * Abstract super class for all Java byte codes.
65  *
66  * @version $Id: Instruction.java,v 1.1.1.1 2001/10/29 20:00:18 jvanzyl Exp $
67  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
68  */

69 public abstract class Instruction implements Cloneable JavaDoc, Serializable {
70   protected short length = 1; // Length of instruction in bytes
71
protected short opcode = -1; // Opcode number
72

73   /**
74    * Empty constructor needed for the Class.newInstance() statement in
75    * Instruction.readInstruction(). Not to be used otherwise.
76    */

77   Instruction() {}
78
79   public Instruction(short opcode, short length) {
80     this.length = length;
81     this.opcode = opcode;
82   }
83
84   /**
85    * Dump instruction as byte code to stream out.
86    * @param out Output stream
87    */

88   public void dump(DataOutputStream out) throws IOException {
89     out.writeByte(opcode); // Common for all instructions
90
}
91
92   /**
93    * Long output format:
94    *
95    * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]"
96    * "("&lt;length of instruction&gt;")"
97    *
98    * @param verbose long/short format switch
99    * @return mnemonic for instruction
100    */

101   public String JavaDoc toString(boolean verbose) {
102     if(verbose)
103       return Constants.OPCODE_NAMES[opcode] + "[" + opcode + "](" + length + ")";
104     else
105       return Constants.OPCODE_NAMES[opcode];
106   }
107
108   /**
109    * @return mnemonic for instruction in verbose format
110    */

111   public String JavaDoc toString() {
112     return toString(true);
113   }
114
115   /**
116    * @return mnemonic for instruction with sumbolic references resolved
117    */

118   public String JavaDoc toString(ConstantPool cp) {
119     return toString(false);
120   }
121
122   /**
123    * Use with caution, since `BranchInstruction's have a `target' reference which
124    * is not copied correctly (only basic types are). This also applies for
125    * `Select' instructions with their multiple branch targets.
126    *
127    * @see BranchInstruction
128    * @return (shallow) copy of an instruction
129    */

130   public Instruction copy() {
131     Instruction i = null;
132
133     // "Constant" instruction, no need to duplicate
134
if(InstructionConstants.INSTRUCTIONS[this.getOpcode()] != null)
135       i = this;
136     else {
137       try {
138     i = (Instruction)clone();
139       } catch(CloneNotSupportedException JavaDoc e) {
140     System.err.println(e);
141       }
142     }
143
144     return i;
145   }
146   
147   /**
148    * Read needed data (e.g. index) from file.
149    *
150    * @param bytes byte sequence to read from
151    * @param wide "wide" instruction flag
152    */

153   protected void initFromFile(ByteSequence bytes, boolean wide)
154     throws IOException
155   {}
156
157   /**
158    * Read an instruction from (byte code) input stream and return the
159    * appropiate object.
160    *
161    * @param file file to read from
162    * @return instruction object being read
163    */

164   public static final Instruction readInstruction(ByteSequence bytes)
165     throws IOException
166   {
167     boolean wide = false;
168     short opcode = (short)bytes.readUnsignedByte();
169     Instruction obj = null;
170
171     if(opcode == Constants.WIDE) { // Read next opcode after wide byte
172
wide = true;
173       opcode = (short)bytes.readUnsignedByte();
174     }
175
176     if(InstructionConstants.INSTRUCTIONS[opcode] != null)
177       return InstructionConstants.INSTRUCTIONS[opcode]; // Used predefined immutable object, if available
178

179     /* Find appropiate class, instantiate an (empty) instruction object
180      * and initialize it by hand.
181      */

182     Class JavaDoc clazz;
183     try {
184       clazz = Class.forName(className(opcode));
185     }
186     catch (ClassNotFoundException JavaDoc cnfe){
187       // If a class by that name does not exist, the opcode is illegal.
188
// Note that IMPDEP1, IMPDEP2, BREAKPOINT are also illegal in a sense.
189
throw new ClassGenException("Illegal opcode detected.");
190     }
191     try {
192       obj = (Instruction)clazz.newInstance();
193
194       if(wide && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) ||
195            (obj instanceof RET)))
196     throw new Exception JavaDoc("Illegal opcode after wide: " + opcode);
197
198       obj.setOpcode(opcode);
199       obj.initFromFile(bytes, wide); // Do further initializations, if any
200
// Byte code offset set in InstructionList
201
} catch(Exception JavaDoc e) { throw new ClassGenException(e.toString()); }
202
203     return obj;
204   }
205
206   private static final String JavaDoc className(short opcode) {
207     String JavaDoc name = Constants.OPCODE_NAMES[opcode].toUpperCase();
208
209     /* ICONST_0, etc. will be shortened to ICONST, etc., since ICONST_0 and the like
210      * are not implemented (directly).
211      */

212     try {
213       int len = name.length();
214       char ch1 = name.charAt(len - 2), ch2 = name.charAt(len - 1);
215
216       if((ch1 == '_') && (ch2 >= '0') && (ch2 <= '5'))
217     name = name.substring(0, len - 2);
218       
219       if(name.equals("ICONST_M1")) // Special case
220
name = "ICONST";
221     } catch(StringIndexOutOfBoundsException JavaDoc e) { System.err.println(e); }
222
223     return "com.sun.org.apache.bcel.internal.generic." + name;
224   }
225
226   /**
227    * This method also gives right results for instructions whose
228    * effect on the stack depends on the constant pool entry they
229    * reference.
230    * @return Number of words consumed from stack by this instruction,
231    * or Constants.UNPREDICTABLE, if this can not be computed statically
232    */

233   public int consumeStack(ConstantPoolGen cpg) {
234     return Constants.CONSUME_STACK[opcode];
235   }
236
237   /**
238    * This method also gives right results for instructions whose
239    * effect on the stack depends on the constant pool entry they
240    * reference.
241    * @return Number of words produced onto stack by this instruction,
242    * or Constants.UNPREDICTABLE, if this can not be computed statically
243    */

244   public int produceStack(ConstantPoolGen cpg) {
245     return Constants.PRODUCE_STACK[opcode];
246   }
247
248   /**
249    * @return this instructions opcode
250    */

251   public short getOpcode() { return opcode; }
252
253   /**
254    * @return length (in bytes) of instruction
255    */

256   public int getLength() { return length; }
257
258   /**
259    * Needed in readInstruction.
260    */

261   private void setOpcode(short opcode) { this.opcode = opcode; }
262
263   /** Some instructions may be reused, so don't do anything by default.
264    */

265   void dispose() { }
266
267   /**
268    * Call corresponding visitor method(s). The order is:
269    * Call visitor methods of implemented interfaces first, then
270    * call methods according to the class hierarchy in descending order,
271    * i.e., the most specific visitXXX() call comes last.
272    *
273    * @param v Visitor object
274    */

275   public abstract void accept(Visitor v);
276 }
277
Popular Tags