@@ -86,7 +86,7 @@ import org.aspectj.apache.bcel.util.ByteSequence; | |||
/** | |||
* 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 | |||
@@ -1297,6 +1297,24 @@ public abstract class Utility { | |||
} | |||
} | |||
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); |
@@ -59,7 +59,7 @@ import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
/** | |||
* 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 | |||
@@ -88,7 +88,7 @@ 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 |
@@ -62,7 +62,7 @@ import org.aspectj.apache.bcel.classfile.ConstantPool; | |||
/** | |||
* 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 | |||
@@ -98,18 +98,8 @@ 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; | |||
} | |||
@@ -60,7 +60,7 @@ import org.aspectj.apache.bcel.classfile.JavaClass; | |||
/** | |||
* 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 { | |||
@@ -70,9 +70,16 @@ 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 | |||
*/ |
@@ -65,7 +65,7 @@ import org.aspectj.apache.bcel.classfile.Utility; | |||
* 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: | |||
@@ -248,6 +248,74 @@ public abstract class Type implements java.io.Serializable { | |||
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 |
@@ -57,6 +57,7 @@ package org.aspectj.apache.bcel.util; | |||
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; | |||
@@ -78,7 +79,7 @@ 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 | |||
*/ | |||
@@ -88,7 +89,7 @@ public class SyntheticRepository implements Repository { | |||
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; |