/**
* Utility functions that do not really belong to any class in particular.
*
- * @version $Id: Utility.java,v 1.4 2005/06/01 14:56:57 aclement Exp $
+ * @version $Id: Utility.java,v 1.5 2006/07/19 12:06:15 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*
* modified: Andy Clement 2-mar-05 Removed unnecessary static and optimized
}
}
+ public static final byte typeOfSignature(char c) throws ClassFormatException {
+ switch(c) {
+ case 'B' : return Constants.T_BYTE;
+ case 'C' : return Constants.T_CHAR;
+ case 'D' : return Constants.T_DOUBLE;
+ case 'F' : return Constants.T_FLOAT;
+ case 'I' : return Constants.T_INT;
+ case 'J' : return Constants.T_LONG;
+ case 'L' : return Constants.T_REFERENCE;
+ case '[' : return Constants.T_ARRAY;
+ case 'V' : return Constants.T_VOID;
+ case 'Z' : return Constants.T_BOOLEAN;
+ case 'S' : return Constants.T_SHORT;
+ default:
+ throw new ClassFormatException("Invalid type of signature: " + c);
+ }
+ }
+
public static final String readClassTypeSignatureFrom(String signature) {
StringBuffer sb = new StringBuffer();
readClassTypeSignatureFrom(signature,0,sb,false);
/**
* Super class for the GET/PUTxxx family of instructions.
*
- * @version $Id: FieldInstruction.java,v 1.4 2004/11/22 08:31:27 aclement Exp $
+ * @version $Id: FieldInstruction.java,v 1.5 2006/07/19 12:06:16 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
public abstract class FieldInstruction extends FieldOrMethod
/** @return size of field (1 or 2)
*/
protected int getFieldSize(ConstantPoolGen cpg) {
- return getType(cpg).getSize();
+ return Type.getTypeSize(getSignature(cpg));
}
/** @return return type of referenced field
/**
* Super class for the INVOKExxx family of instructions.
*
- * @version $Id: InvokeInstruction.java,v 1.3 2004/11/22 08:31:27 aclement Exp $
+ * @version $Id: InvokeInstruction.java,v 1.4 2006/07/19 12:06:17 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
public abstract class InvokeInstruction extends FieldOrMethod
*/
public int consumeStack(ConstantPoolGen cpg) {
String signature = getSignature(cpg);
- Type[] args = Type.getArgumentTypes(signature);
- int sum;
-
- if(opcode == Constants.INVOKESTATIC)
- sum = 0;
- else
- sum = 1; // this reference
-
- int n = args.length;
- for (int i = 0; i < n; i++)
- sum += args[i].getSize();
-
+ int sum = Type.getArgumentSizes(signature);
+ if (opcode!=Constants.INVOKESTATIC) sum+=1;
return sum;
}
/**
* Denotes reference such as java.lang.String.
*
- * @version $Id: ObjectType.java,v 1.2 2004/11/19 16:45:18 aclement Exp $
+ * @version $Id: ObjectType.java,v 1.3 2006/07/19 12:06:16 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
public final class ObjectType extends ReferenceType {
* @param class_name fully qualified class name, e.g. java.lang.String
*/
public ObjectType(String class_name) {
- super(Constants.T_REFERENCE, "L" + class_name.replace('.', '/') + ";");
+ super(Constants.T_REFERENCE, toSignature(class_name));//"L" + class_name.replace('.', '/') + ";");
this.class_name = class_name.replace('/', '.');
}
+
+ private static String toSignature(String classname) {
+ StringBuffer sig = new StringBuffer();
+ sig.append("L").append(classname.replace('.','/'));
+ sig.append(";");
+ return sig.toString();
+ }
/** @return name of referenced class
*/
* Abstract super class for all possible java types, namely basic types
* such as int, object types like String and array types, e.g. int[]
*
- * @version $Id: Type.java,v 1.6 2005/09/21 15:02:04 acolyer Exp $
+ * @version $Id: Type.java,v 1.7 2006/07/19 12:06:17 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*
* modified:
vec.toArray(types);
return types;
}
+
+ /**
+ * Work out the type of each argument in the signature and return the cumulative sizes of
+ * all the types (size means number of stack slots it consumes, eg double=2, int=1).
+ * Unlike the call above, this does minimal unpacking
+ */
+ public static int getArgumentSizes(String signature) {
+ int size = 0;
+ if (signature.charAt(0) != '(')
+ throw new ClassFormatException("Invalid method signature: " + signature);
+
+ int index = 1; // current string position
+ try {
+ while (signature.charAt(index) != ')') {
+ byte type = Utility.typeOfSignature(signature.charAt(index));
+ if (type<=Constants.T_VOID) {
+ size+=BasicType.getType(type).getSize();
+ index++;
+ } else if (type==Constants.T_ARRAY) {
+ int dim=0;
+ do { dim++; } while(signature.charAt(dim+index) == '[');
+ TypeHolder th = getTypeInternal(signature.substring(dim+index));
+ size+=1;
+ index+=dim+th.getConsumed();
+ } else { // type == T_REFERENCE
+ // Format is 'Lblahblah;'
+ int index2 = signature.indexOf(';',index); // Look for closing ';'
+
+ // generics awareness
+ int nextAngly = signature.indexOf('<',index);
+ if (nextAngly==-1 || nextAngly>index2) {
+ } else {
+ boolean endOfSigReached = false;
+ int posn = nextAngly;
+ int genericDepth=0;
+ while (!endOfSigReached) {
+ switch (signature.charAt(posn++)) {
+ case '<': genericDepth++;break;
+ case '>': genericDepth--;break;
+ case ';': if (genericDepth==0) endOfSigReached=true;break;
+ default:
+ }
+ }
+ index2=posn-1;
+ }
+ size++;
+ index=index2+1;
+ }
+ }
+ } catch(StringIndexOutOfBoundsException e) { // Should never occur
+ throw new ClassFormatException("Invalid method signature: " + signature);
+ }
+ return size;
+ }
+
+ /**
+ * Return the size of the type expressed in the signature. The signature should contain only one type.
+ */
+ public static int getTypeSize(String signature) {
+ byte type = Utility.typeOfSignature(signature.charAt(0));
+ if (type<=Constants.T_VOID) {
+ return BasicType.getType(type).getSize();
+ } else if (type==Constants.T_ARRAY) {
+ return 1;
+ } else { // type == T_REFERENCE
+ return 1;
+ }
+ }
/** Convert runtime java.lang.Class to BCEL Type object.
* @param cl Java class
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
+import java.util.WeakHashMap;
import org.aspectj.apache.bcel.classfile.ClassParser;
import org.aspectj.apache.bcel.classfile.JavaClass;
*
* @see org.aspectj.apache.bcel.Repository
*
- * @version $Id: SyntheticRepository.java,v 1.5 2004/11/22 08:31:27 aclement Exp $
+ * @version $Id: SyntheticRepository.java,v 1.6 2006/07/19 12:06:16 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @author David Dixon-Peugh
*/
private static HashMap _instances = new HashMap(); // CLASSPATH X REPOSITORY
private ClassPath _path = null;
- private HashMap _loadedClasses = new HashMap(); // CLASSNAME X JAVACLASS
+ private WeakHashMap _loadedClasses = new WeakHashMap(); // CLASSNAME X JAVACLASS
private SyntheticRepository(ClassPath path) {
_path = path;