00001 package ca.mcgill.sable.soot.coffi; 00002 00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00004 * Jimple, a 3-address code Java(TM) bytecode representation. * 00005 * Copyright (C) 1997, 1998 Raja Vallee-Rai (kor@sable.mcgill.ca) * 00006 * All rights reserved. * 00007 * * 00008 * Modifications by Vijay Sundaresan (vijay@sable.mcgill.ca) are * 00009 * Copyright (C) 1999 Vijay Sundaresan. All rights reserved. * 00010 * * 00011 * This work was done as a project of the Sable Research Group, * 00012 * School of Computer Science, McGill University, Canada * 00013 * (http://www.sable.mcgill.ca/). It is understood that any * 00014 * modification not identified as such is not covered by the * 00015 * preceding statement. * 00016 * * 00017 * This work is free software; you can redistribute it and/or * 00018 * modify it under the terms of the GNU Library General Public * 00019 * License as published by the Free Software Foundation; either * 00020 * version 2 of the License, or (at your option) any later version. * 00021 * * 00022 * This work is distributed in the hope that it will be useful, * 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00025 * Library General Public License for more details. * 00026 * * 00027 * You should have received a copy of the GNU Library General Public * 00028 * License along with this library; if not, write to the * 00029 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * 00030 * Boston, MA 02111-1307, USA. * 00031 * * 00032 * Java is a trademark of Sun Microsystems, Inc. * 00033 * * 00034 * To submit a bug report, send a comment, or get the latest news on * 00035 * this project and other Sable Research Group projects, please * 00036 * visit the web site: http://www.sable.mcgill.ca/ * 00037 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00038 00039 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00040 * Coffi, a bytecode parser for the Java(TM) language. * 00041 * Copyright (C) 1996, 1997 Clark Verbrugge (clump@sable.mcgill.ca). * 00042 * All rights reserved. * 00043 * * 00044 * This work was done as a project of the Sable Research Group, * 00045 * School of Computer Science, McGill University, Canada * 00046 * (http://www.sable.mcgill.ca/). It is understood that any * 00047 * modification not identified as such is not covered by the * 00048 * preceding statement. * 00049 * * 00050 * This work is free software; you can redistribute it and/or * 00051 * modify it under the terms of the GNU Library General Public * 00052 * License as published by the Free Software Foundation; either * 00053 * version 2 of the License, or (at your option) any later version. * 00054 * * 00055 * This work is distributed in the hope that it will be useful, * 00056 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00057 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00058 * Library General Public License for more details. * 00059 * * 00060 * You should have received a copy of the GNU Library General Public * 00061 * License along with this library; if not, write to the * 00062 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * 00063 * Boston, MA 02111-1307, USA. * 00064 * * 00065 * Java is a trademark of Sun Microsystems, Inc. * 00066 * * 00067 * To submit a bug report, send a comment, or get the latest news on * 00068 * this project and other Sable Research Group projects, please * 00069 * visit the web site: http://www.sable.mcgill.ca/ * 00070 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00071 00072 /* 00073 Reference Version 00074 ----------------- 00075 This is the latest official version on which this file is based. 00076 The reference version is: $CoffiVersion: 1.1 $ 00077 $SootVersion: 1.beta.4 $ 00078 00079 Change History 00080 -------------- 00081 A) Notes: 00082 00083 Please use the following template. Most recent changes should 00084 appear at the top of the list. 00085 00086 - Modified on [date (March 1, 1900)] by [name]. [(*) if appropriate] 00087 [description of modification]. 00088 00089 Any Modification flagged with "(*)" was done as a project of the 00090 Sable Research Group, School of Computer Science, 00091 McGill University, Canada (http://www.sable.mcgill.ca/). 00092 00093 You should add your copyright, using the following template, at 00094 the top of this file, along with other copyrights. 00095 00096 * * 00097 * Modifications by [name] are * 00098 * Copyright (C) [year(s)] [your name (or company)]. All rights * 00099 * reserved. * 00100 * * 00101 00102 B) Changes: 00103 00104 - Modified on February 19, 1999 by Vijay Sundaresan (vijay@sable.mcgill.ca) (*) 00105 Made Instruction implement Cloneable. 00106 00107 - Modified on November 2, 1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*) 00108 Repackaged all source files and performed extensive modifications. 00109 First initial release of Soot. 00110 00111 - Modified on September 3, by Raja Vallee-Rai (kor@sable.mcgill.ca). (*) 00112 Installed code to print original index of bytecodes from classfile 00113 for easy debugging. 00114 00115 - Modified on 15-Jun-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*) 00116 First internal release (Version 0.1). 00117 */ 00118 00119 import java.io.*; 00120 /** Instruction subclasses are used to represent parsed bytecode; each 00121 * bytecode operation has a corresponding subclass of Instruction. 00122 * <p> 00123 * Each subclass is derived from one of 00124 * <ul><li>Instruction</li> 00125 * <li>Instruction_noargs (an Instruction with no embedded arguments)</li> 00126 * <li>Instruction_byte (an Instruction with a single byte data argument)</li> 00127 * <li>Instruction_bytevar (a byte argument specifying a local variable)</li> 00128 * <li>Instruction_byteindex (a byte argument specifying a constant pool index)</li> 00129 * <li>Instruction_int (an Instruction with a single short data argument)</li> 00130 * <li>Instruction_intvar (a short argument specifying a local variable)</li> 00131 * <li>Instruction_intindex (a short argument specifying a constant pool index)</li> 00132 * <li>Instruction_intbranch (a short argument specifying a code offset)</li> 00133 * <li>Instruction_longbranch (an int argument specifying a code offset)</li> 00134 * </ul> 00135 * @author Clark Verbrugge 00136 * @see Instruction 00137 * @see Instruction_noargs 00138 * @see Instruction_byte 00139 * @see Instruction_bytevar 00140 * @see Instruction_byteindex 00141 * @see Instruction_int 00142 * @see Instruction_intvar 00143 * @see Instruction_intindex 00144 * @see Instruction_intbranch 00145 * @see Instruction_longbranch 00146 * @see Instruction_Unknown 00147 */ 00148 abstract class Instruction implements Cloneable { 00149 00150 /** String used to separate arguments in printing. */ 00151 public static final String argsep = " "; 00152 /** String used to construct names for local variables. */ 00153 public static final String LOCALPREFIX = "local_"; 00154 // public static int w; // set by the wide instr. and used by other instrs 00155 00156 /** Actual byte code of this instruction. */ 00157 public byte code; 00158 /** Offset of this instruction from the start of code. 00159 * @see ClassFile#relabel 00160 */ 00161 public int label; 00162 /** Name of this instruction. 00163 * @see Instruction#toString 00164 */ 00165 public String name; 00166 00167 /** Reference for chaining. */ 00168 public Instruction next; 00169 /** Whether this instruction is the target of a branch. */ 00170 public boolean labelled; 00171 /** Whether this instruction branches. */ 00172 public boolean branches; 00173 /** Whether this instruction is a method invocation. */ 00174 public boolean calls; 00175 /** Whether this instruction is a return. */ 00176 public boolean returns; 00177 00178 int originalIndex; 00179 00180 /** Constructs a new Instruction for this bytecode. 00181 * @param c bytecode of the instruction. 00182 */ 00183 public Instruction(byte c) { 00184 code = c; 00185 next = null; 00186 branches = false; 00187 calls = false; 00188 returns = false; 00189 } 00190 /** Returns an array of the instructions to which this instruction 00191 * might branch (only valid if branches==<i>true</i>; default action is 00192 * to return <i>null</i>). 00193 * @param next the instruction following this one, in case of default flow through. 00194 * @return array of instructions which may be targets of this instruction. 00195 * @see Instruction#branches 00196 */ 00197 public Instruction[] branchpoints(Instruction next) { return null; } 00198 protected Object clone() throws CloneNotSupportedException { 00199 00200 return super.clone(); 00201 00202 } 00203 /** Writes out the sequence of bytecodes represented by this instruction, including 00204 * any arguments. 00205 * @param bc complete array of bytecode. 00206 * @param index offset of remaining bytecode at which to start writing. 00207 * @return offset of the next available bytecode. 00208 * @see ClassFile#unparseMethod 00209 * @see Instruction#parse 00210 */ 00211 public abstract int compile(byte bc[],int index); 00212 /** For storing in a Hashtable. 00213 * @param i the Instruction to which this is compared. 00214 * @return <i>true</i> if <i>i</i> is the same, <i>false</i> otherwise. 00215 */ 00216 public boolean equals(Instruction i) { 00217 if (label == i.label) return true; 00218 return false; 00219 } 00220 /** Utility routines, used mostly by the parse routines of various 00221 * Instruction subclasses; 00222 * this method converts four bytes into an int. 00223 * @param bc complete array of bytecode. 00224 * @param index offset of data in bc. 00225 * @return the int constructed from the four bytes. 00226 * @see Instruction#parse 00227 * @see Instruction#intToBytes 00228 */ 00229 public static int getInt(byte bc[],int index) { 00230 int i,bhh,bhl,blh,bll; 00231 bhh = (((int)(bc[index]))<<24)&0xff000000; 00232 bhl = (((int)(bc[index+1]))<<16)&0xff0000; 00233 blh = (((int)(bc[index+2]))<<8)&0xff00; 00234 bll = ((int)(bc[index+3]))&0xff; 00235 i = bhh | bhl | blh | bll; 00236 return i; 00237 } 00238 /** Utility routines, used mostly by the parse routines of various 00239 * Instruction subclasses; 00240 * this method converts two bytes into a short. 00241 * @param bc complete array of bytecode. 00242 * @param index offset of data in bc. 00243 * @return the short constructed from the two bytes. 00244 * @see Instruction#parse 00245 * @see Instruction#shortToBytes 00246 */ 00247 public static short getShort(byte bc[],int index) { 00248 short s,bh,bl; 00249 bh = (short)(bc[index]); bl = (short)(bc[index+1]); 00250 s = (short)(((bh<<8)&0xff00) | (bl&0xff)); 00251 //s = (short)((int)(bc[index])<<8 + bc[index+1]); 00252 return s; 00253 } 00254 /** For storing in a Hashtable. 00255 * @return unique hash code for this instruction, assuming labels are unique. 00256 */ 00257 public int hashCode() { 00258 return (new Integer(label)).hashCode(); 00259 } 00260 /** Utility routines, used mostly by the compile routines of various 00261 * Instruction subclasses; 00262 * this method converts an int into four bytes. 00263 * @param bc complete array of bytecode in which to store the int. 00264 * @param index next available offset in bc. 00265 * @return the next available offset in bc 00266 * @see Instruction#compile 00267 * @see Instruction#getInt 00268 */ 00269 public static int intToBytes(int s,byte bc[],int index) { 00270 bc[index++] = (byte)((s>>24)&0xff); 00271 bc[index++] = (byte)((s>>16)&0xff); 00272 bc[index++] = (byte)((s>>8)&0xff); 00273 bc[index++] = (byte)(s&0xff); 00274 return index; 00275 } 00276 /** Marks the appropriate spot if that constant_pool entry is used by this instr. 00277 * For every constant pool entry used (referenced) by this instruction, the 00278 * corresponding boolean in the given array is set to <i>true</i>. 00279 * @param refs array of booleans the same size as the constant pool array. 00280 * @see ClassFile#constant_pool 00281 */ 00282 public void markCPRefs(boolean[] refs) { } 00283 /** Returns the next available offset assuming this instruction begins 00284 * on the indicated offset; default assumes no arguments. 00285 * @param curr offset this instruction would be on. 00286 * @return next available offset. 00287 * @see ClassFile#relabel 00288 */ 00289 public int nextOffset(int curr) { return curr+1; } 00290 /** Changes offset values in this instruction to Instruction references; 00291 * default behaviour is to do nothing. 00292 * @param bc complete array of bytecode. 00293 * @see ByteCode#build 00294 */ 00295 public void offsetToPointer(ByteCode bc) { } 00296 /** Assuming the actual bytecode for this instruction has been extracted already, 00297 * and index is the offset of the next byte, this method parses whatever 00298 * arguments the instruction requires and return the offset of the next 00299 * available byte. 00300 * @param bc complete array of bytecode. 00301 * @param index offset of remaining bytecode after this instruction's 00302 * bytecode was parsed. 00303 * @return offset of the next available bytecode. 00304 * @see ByteCode#disassemble_bytecode 00305 * @see Instruction#compile 00306 */ 00307 public abstract int parse(byte bc[],int index); 00308 /** Updates all constant pool references within this instruction to use 00309 * new indices, based on the given redirection array. 00310 * @param redirect array of new indices of constant pool entries. 00311 * @see ClassFile#constant_pool 00312 */ 00313 public void redirectCPRefs(short redirect[]) { } 00314 /** Utility routines, used mostly by the compile routines of various 00315 * Instruction subclasses; 00316 * this method converts a short into two bytes. 00317 * @param bc complete array of bytecode in which to store the short. 00318 * @param index next available offset in bc. 00319 * @return the next available offset in bc 00320 * @see Instruction#compile 00321 * @see Instruction#getShort 00322 */ 00323 public static int shortToBytes(short s,byte bc[],int index) { 00324 bc[index++] = (byte)((s>>8)&0xff); 00325 bc[index++] = (byte)(s&0xff); 00326 return index; 00327 } 00328 public String toString() 00329 { 00330 return name + "[" + originalIndex + "]"; 00331 } 00332 /** For displaying instructions. 00333 * @param constant_pool constant pool of associated ClassFile 00334 * @return String representation of this instruction. 00335 */ 00336 public String toString(cp_info constant_pool[]) { 00337 int i = ((int)code)&0xff; 00338 if (name==null) name = "null???=" + Integer.toString(i); 00339 return name; 00340 } 00341 }