Commit 330a43ba authored by ebruneton's avatar ebruneton
Browse files

moved ASM_4_FUTURE_2 branch into trunk

parent 390a3ba5
......@@ -31,7 +31,7 @@
# Some information about the product
product.name asm
product.version 3.3.1
product.version 4.0_RC1
# product.snapshot yes
plugin.version 3.3.0
......
This diff is collapsed.
......@@ -46,7 +46,7 @@ import java.lang.reflect.Method;
*/
public class Adapt extends ClassLoader {
protected synchronized Class loadClass(
protected synchronized Class<?> loadClass(
final String name,
final boolean resolve) throws ClassNotFoundException
{
......@@ -90,10 +90,10 @@ public class Adapt extends ClassLoader {
public static void main(final String args[]) throws Exception {
// loads the application class (in args[0]) with an Adapt class loader
ClassLoader loader = new Adapt();
Class c = loader.loadClass(args[0]);
Class<?> c = loader.loadClass(args[0]);
// calls the 'main' static method of this class with the
// application arguments (in args[1] ... args[n]) as parameter
Method m = c.getMethod("main", new Class[] { String[].class });
Method m = c.getMethod("main", new Class<?>[] { String[].class });
String[] applicationArgs = new String[args.length - 1];
System.arraycopy(args, 1, applicationArgs, 0, applicationArgs.length);
m.invoke(null, new Object[] { applicationArgs });
......
......@@ -40,6 +40,7 @@ import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.objectweb.asm.tree.analysis.Analyzer;
import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.BasicVerifier;
import org.objectweb.asm.tree.analysis.SourceInterpreter;
import org.objectweb.asm.tree.analysis.SourceValue;
......@@ -56,17 +57,17 @@ public class Analysis implements Opcodes {
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_DEBUG);
List methods = cn.methods;
List<MethodNode> methods = cn.methods;
for (int i = 0; i < methods.size(); ++i) {
MethodNode method = (MethodNode) methods.get(i);
MethodNode method = methods.get(i);
if (method.instructions.size() > 0) {
if (!analyze(cn, method)) {
Analyzer a = new Analyzer(new BasicVerifier());
Analyzer<?> a = new Analyzer<BasicValue>(new BasicVerifier());
try {
a.analyze(cn.name, method);
} catch (Exception ignored) {
}
final Frame[] frames = a.getFrames();
final Frame<?>[] frames = a.getFrames();
TraceMethodVisitor mv = new TraceMethodVisitor() {
public void visitMaxs(
......@@ -107,24 +108,24 @@ public class Analysis implements Opcodes {
public static boolean analyze(final ClassNode c, final MethodNode m)
throws Exception
{
Analyzer a = new Analyzer(new SourceInterpreter());
Frame[] frames = a.analyze(c.name, m);
Analyzer<SourceValue> a = new Analyzer<SourceValue>(new SourceInterpreter());
Frame<SourceValue>[] frames = a.analyze(c.name, m);
// for each xLOAD instruction, we find the xSTORE instructions that can
// produce the value loaded by this instruction, and we put them in
// 'stores'
Set stores = new HashSet();
Set<AbstractInsnNode> stores = new HashSet<AbstractInsnNode>();
for (int i = 0; i < m.instructions.size(); ++i) {
Object insn = m.instructions.get(i);
int opcode = ((AbstractInsnNode) insn).getOpcode();
AbstractInsnNode insn = m.instructions.get(i);
int opcode = insn.getOpcode();
if ((opcode >= ILOAD && opcode <= ALOAD) || opcode == IINC) {
int var = opcode == IINC
? ((IincInsnNode) insn).var
: ((VarInsnNode) insn).var;
Frame f = frames[i];
Frame<SourceValue> f = frames[i];
if (f != null) {
Set s = ((SourceValue) f.getLocal(var)).insns;
Iterator j = s.iterator();
Set<AbstractInsnNode> s = f.getLocal(var).insns;
Iterator<AbstractInsnNode> j = s.iterator();
while (j.hasNext()) {
insn = j.next();
if (insn instanceof VarInsnNode) {
......@@ -138,16 +139,14 @@ public class Analysis implements Opcodes {
// we then find all the xSTORE instructions that are not in 'stores'
boolean ok = true;
for (int i = 0; i < m.instructions.size(); ++i) {
Object insn = m.instructions.get(i);
if (insn instanceof AbstractInsnNode) {
int opcode = ((AbstractInsnNode) insn).getOpcode();
if (opcode >= ISTORE && opcode <= ASTORE) {
if (!stores.contains(insn)) {
ok = false;
System.err.println("method " + m.name
+ ", instruction " + i
+ ": useless store instruction");
}
AbstractInsnNode insn = m.instructions.get(i);
int opcode = insn.getOpcode();
if (opcode >= ISTORE && opcode <= ASTORE) {
if (!stores.contains(insn)) {
ok = false;
System.err.println("method " + m.name
+ ", instruction " + i
+ ": useless store instruction");
}
}
}
......
......@@ -78,7 +78,7 @@ public class Annotations {
exceptions);
return new MethodAdapter(v) {
private final List params = new ArrayList();
private final List<Integer> params = new ArrayList<Integer>();
public AnnotationVisitor visitParameterAnnotation(
final int parameter,
......@@ -98,7 +98,7 @@ public class Annotations {
public void visitCode() {
int var = (access & Opcodes.ACC_STATIC) == 0 ? 1 : 0;
for (int p = 0; p < params.size(); ++p) {
int param = ((Integer) params.get(p)).intValue();
int param = params.get(p).intValue();
for (int i = 0; i < param; ++i) {
var += args[i].getSize();
}
......@@ -123,8 +123,8 @@ public class Annotations {
}
}, 0);
Class c = new ClassLoader() {
public Class loadClass(final String name)
Class<?> c = new ClassLoader() {
public Class<?> loadClass(final String name)
throws ClassNotFoundException
{
if (name.equals(n)) {
......@@ -137,7 +137,7 @@ public class Annotations {
System.out.println();
System.out.println("Calling foo(null) on the transformed class results in an IllegalArgumentException:");
Method m = c.getMethod("foo", new Class[] { String.class });
Method m = c.getMethod("foo", new Class<?>[] { String.class });
try {
m.invoke(null, new Object[] { null });
} catch (InvocationTargetException e) {
......
......@@ -50,7 +50,7 @@ public class Compile extends ClassLoader {
FileOutputStream fos = new FileOutputStream("Example.class");
fos.write(b);
fos.close();
Class expClass = main.defineClass("Example", b, 0, b.length);
Class<?> expClass = main.defineClass("Example", b, 0, b.length);
// instantiates this compiled expression class...
Expression iexp = (Expression) expClass.newInstance();
// ... and uses it to evaluate exp(0) to exp(9)
......@@ -74,9 +74,8 @@ abstract class Exp implements Opcodes {
*/
byte[] compile(final String name) {
// class header
String[] itfs = { Expression.class.getName() };
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(V1_1, ACC_PUBLIC, name, null, "java/lang/Object", itfs);
cw.visit(V1_1, ACC_PUBLIC, name, null, "java/lang/Object", new String[] { Expression.class.getName() });
// default public constructor
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC,
......
......@@ -56,7 +56,7 @@ import org.objectweb.asm.ClassReader;
*
* @author Eugene Kuleshov
*
* @see http://www.onjava.com/pub/a/onjava/2005/08/17/asm3.html
* @see "http://www.onjava.com/pub/a/onjava/2005/08/17/asm3.html"
*/
public class DependencyTracker {
......
......@@ -39,6 +39,8 @@ import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodHandle;
import org.objectweb.asm.MethodType;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader;
......@@ -46,7 +48,7 @@ import org.objectweb.asm.signature.SignatureVisitor;
/**
* DependencyVisitor
*
*
* @author Eugene Kuleshov
*/
public class DependencyVisitor implements
......@@ -199,12 +201,23 @@ public class DependencyVisitor implements
addMethodDesc(desc);
}
public void visitLdcInsn(final Object cst) {
if (cst instanceof Type) {
addType((Type) cst);
public void visitInvokeDynamicInsn(
String name,
String desc,
MethodHandle bsm,
Object... bsmArgs)
{
addMethodDesc(desc);
addConstant(bsm);
for(int i=0; i<bsmArgs.length; i++) {
addConstant(bsmArgs[i]);
}
}
public void visitLdcInsn(final Object cst) {
addConstant(cst);
}
public void visitMultiANewArrayInsn(final String desc, final int dims) {
addDesc(desc);
}
......@@ -258,7 +271,7 @@ public class DependencyVisitor implements
final int min,
final int max,
final Label dflt,
final Label[] labels)
final Label... labels)
{
}
......@@ -413,7 +426,7 @@ public class DependencyVisitor implements
addInternalName(names[i]);
}
}
private void addDesc(final String desc) {
addType(Type.getType(desc));
}
......@@ -448,4 +461,16 @@ public class DependencyVisitor implements
new SignatureReader(signature).acceptType(this);
}
}
private void addConstant(final Object cst) {
if (cst instanceof Type) {
addType((Type) cst);
} else if (cst instanceof MethodType) {
addMethodDesc(((MethodType) cst).getDescriptor());
} else if (cst instanceof MethodHandle) {
MethodHandle mHandle = (MethodHandle) cst;
addInternalName(mHandle.getOwner());
addMethodDesc(mHandle.getDesc());
}
}
}
......@@ -104,7 +104,7 @@ public class Helloworld extends ClassLoader implements Opcodes {
fos.close();
Helloworld loader = new Helloworld();
Class exampleClass = loader.defineClass("Example", code, 0, code.length);
Class<?> exampleClass = loader.defineClass("Example", code, 0, code.length);
// uses the dynamically generated class to print 'Helloworld'
exampleClass.getMethods()[0].invoke(null, new Object[] { null });
......
......@@ -110,7 +110,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
/**
* The label names. This map associate String values to Label keys.
*/
protected final Map labelNames;
protected final Map<Label, String> labelNames;
/**
* Prints a disassembled view of the given class in Jasmin assembler format
......@@ -173,7 +173,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
}
});
this.pw = pw;
labelNames = new HashMap();
labelNames = new HashMap<Label, String>();
}
public void visitEnd() {
......@@ -193,7 +193,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
println(".super ", cn.superName);
}
for (int i = 0; i < cn.interfaces.size(); ++i) {
println(".implements ", (String) cn.interfaces.get(i));
println(".implements ", cn.interfaces.get(i));
}
if (cn.signature != null)
println(".signature ", '"' + cn.signature + '"');
......@@ -217,7 +217,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
: '"' + cn.sourceDebug + '"');
for (int i = 0; i < cn.innerClasses.size(); ++i) {
InnerClassNode in = (InnerClassNode) cn.innerClasses.get(i);
InnerClassNode in = cn.innerClasses.get(i);
pw.print(".inner class");
pw.print(access(in.access));
if (in.innerName != null) {
......@@ -236,7 +236,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
}
for (int i = 0; i < cn.fields.size(); ++i) {
FieldNode fn = (FieldNode) cn.fields.get(i);
FieldNode fn = cn.fields.get(i);
boolean annotations = false;
if (fn.visibleAnnotations != null
&& fn.visibleAnnotations.size() > 0)
......@@ -286,7 +286,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
}
for (int i = 0; i < cn.methods.size(); ++i) {
MethodNode mn = (MethodNode) cn.methods.get(i);
MethodNode mn = cn.methods.get(i);
pw.print("\n.method");
pw.print(access(mn.access));
pw.print(' ');
......@@ -306,10 +306,10 @@ public class JasminifierClassAdapter extends ClassAdapter {
if (mn.visibleParameterAnnotations != null) {
for (int j = 0; j < mn.visibleParameterAnnotations.length; ++j)
{
List l = mn.visibleParameterAnnotations[j];
List<AnnotationNode> l = mn.visibleParameterAnnotations[j];
if (l != null) {
for (int k = 0; k < l.size(); ++k) {
printAnnotation((AnnotationNode) l.get(k), 1, j + 1);
printAnnotation(l.get(k), 1, j + 1);
}
}
}
......@@ -317,16 +317,16 @@ public class JasminifierClassAdapter extends ClassAdapter {
if (mn.invisibleParameterAnnotations != null) {
for (int j = 0; j < mn.invisibleParameterAnnotations.length; ++j)
{
List l = mn.invisibleParameterAnnotations[j];
List<AnnotationNode> l = mn.invisibleParameterAnnotations[j];
if (l != null) {
for (int k = 0; k < l.size(); ++k) {
printAnnotation((AnnotationNode) l.get(k), 2, j + 1);
printAnnotation(l.get(k), 2, j + 1);
}
}
}
}
for (int j = 0; j < mn.exceptions.size(); ++j) {
println(".throws ", (String) mn.exceptions.get(j));
println(".throws ", mn.exceptions.get(j));
}
if ((mn.access & Opcodes.ACC_DEPRECATED) != 0) {
pw.println(".deprecated");
......@@ -334,7 +334,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
if (mn.instructions.size() > 0) {
labelNames.clear();
for (int j = 0; j < mn.tryCatchBlocks.size(); ++j) {
TryCatchBlockNode tcb = (TryCatchBlockNode) mn.tryCatchBlocks.get(j);
TryCatchBlockNode tcb = mn.tryCatchBlocks.get(j);
pw.print(".catch ");
pw.print(tcb.type);
pw.print(" from ");
......@@ -494,7 +494,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
int min,
int max,
Label dflt,
Label[] labels)
Label... labels)
{
pw.print("tableswitch ");
pw.println(min);
......@@ -548,7 +548,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
});
}
for (int j = 0; j < mn.localVariables.size(); ++j) {
LocalVariableNode lv = (LocalVariableNode) mn.localVariables.get(j);
LocalVariableNode lv = mn.localVariables.get(j);
pw.print(".var ");
pw.print(lv.index);
pw.print(" is '");
......@@ -660,7 +660,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
}
protected void print(final Label l) {
String name = (String) labelNames.get(l);
String name = labelNames.get(l);
if (name == null) {
name = "L" + labelNames.size();
labelNames.put(l, name);
......@@ -675,14 +675,14 @@ public class JasminifierClassAdapter extends ClassAdapter {
protected void printAnnotations(final MemberNode n) {
if (n.visibleAnnotations != null) {
for (int j = 0; j < n.visibleAnnotations.size(); ++j) {
printAnnotation((AnnotationNode) n.visibleAnnotations.get(j),
printAnnotation(n.visibleAnnotations.get(j),
1,
-1);
}
}
if (n.invisibleAnnotations != null) {
for (int j = 0; j < n.invisibleAnnotations.size(); ++j) {
printAnnotation((AnnotationNode) n.invisibleAnnotations.get(j),
printAnnotation(n.invisibleAnnotations.get(j),
2,
-1);
}
......@@ -793,7 +793,7 @@ public class JasminifierClassAdapter extends ClassAdapter {
}
pw.println();
} else if (value instanceof List) {
List l = (List) value;
List<?> l = (List<?>) value;
if (l.size() > 0) {
Object o = l.get(0);
if (o instanceof String[]) {
......
......@@ -182,9 +182,9 @@ public class JasminifierClassAdapterTest extends TestCase {
scanDirectory("", f, suite, clazz);
} else {
ZipFile zip = new ZipFile(file);
Enumeration entries = zip.entries();
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry e = (ZipEntry) entries.nextElement();
ZipEntry e = entries.nextElement();
String n = e.getName();
String p = n.replace('/', '.');
System.out.println(n+" "+clazz);
......
......@@ -115,7 +115,7 @@ public class BFCompiler implements Opcodes {
mv.visitIntInsn(NEWARRAY, T_INT);
mv.visitVarInsn(ASTORE, V_D);
Stack labels = new Stack();
Stack<Label> labels = new Stack<Label>();
int d = 0;
int p = 0;
......@@ -187,11 +187,11 @@ public class BFCompiler implements Opcodes {
p = storeP(mv, p);
d = storeD(mv, d);
mv.visitLabel((Label) labels.pop());
mv.visitLabel(labels.pop());
mv.visitVarInsn(ALOAD, V_D);
mv.visitVarInsn(ILOAD, V_P);
mv.visitInsn(IALOAD);
mv.visitJumpInsn(IFNE, (Label) labels.pop());
mv.visitJumpInsn(IFNE, labels.pop());
break;
}
}
......
......@@ -129,9 +129,9 @@ public class BFCompilerTest extends TestCase {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader(),
name,
cw.toByteArray());
Class c = cl.loadClass(name);
Class<?> c = cl.loadClass(name);
Method m = c.getDeclaredMethod("main",
new Class[] { String[].class });
new Class<?>[] { String[].class });
m.invoke(null, new Object[] { new String[0] });
} catch (InvocationTargetException ex) {
......@@ -163,7 +163,7 @@ public class BFCompilerTest extends TestCase {
this.bytecode = bytecode;
}
public Class loadClass(final String name) throws ClassNotFoundException
public Class<?> loadClass(final String name) throws ClassNotFoundException
{
if (className.equals(name)) {
return super.defineClass(className,
......
This diff is collapsed.
......@@ -70,7 +70,7 @@ public class ClassWriter implements ClassVisitor {
* the synthetic access flag.
*/
static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
/**
* The type of instructions without any argument.
*/
......@@ -109,52 +109,57 @@ public class ClassWriter implements ClassVisitor {
/**
* The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction.
*/
static final int ITFDYNMETH_INSN = 7;
static final int ITFMETH_INSN = 7;
/**
* The type of the INVOKEDYNAMIC instruction.
*/
static final int INDYMETH_INSN = 8;
/**
* The type of instructions with a 2 bytes bytecode offset label.
*/
static final int LABEL_INSN = 8;
static final int LABEL_INSN = 9;
/**
* The type of instructions with a 4 bytes bytecode offset label.
*/
static final int LABELW_INSN = 9;
static final int LABELW_INSN = 10;
/**
* The type of the LDC instruction.
*/
static final int LDC_INSN = 10;
static final int LDC_INSN = 11;
/**
* The type of the LDC_W and LDC2_W instructions.
*/
static final int LDCW_INSN = 11;
static final int LDCW_INSN = 12;
/**
* The type of the IINC instruction.
*/
static final int IINC_INSN = 12;
static final int IINC_INSN = 13;
/**
* The type of the TABLESWITCH instruction.
*/
static final int TABL_INSN = 13;
static final int TABL_INSN = 14;
/**
* The type of the LOOKUPSWITCH instruction.
*/
static final int LOOK_INSN = 14;
static final int LOOK_INSN = 15;
/**
* The type of the MULTIANEWARRAY instruction.
*/
static final int MANA_INSN = 15;
static final int MANA_INSN = 16;
/**
* The type of the WIDE instruction.
*/
static final int WIDE_INSN = 16;
static final int WIDE_INSN = 17;
/**
* The instruction types of all JVM opcodes.
......@@ -216,12 +221,34 @@ public class ClassWriter implements ClassVisitor {
*/
static final int UTF8 = 1;
/**
* The type of CONSTANT_MethodType constant pool items.
*/
static final int MTYPE = 16;
/**
* The type of CONSTANT_MethodHandle constant pool items.
*/
static final int MHANDLE = 15;
/**
* The type of CONSTANT_InvokeDynamic constant pool items.
*/
static final int INDY = 18;
/**
* The base value for all CONSTANT_MethodHandle constant pool items.
* Internally, ASM store the 9 variations of CONSTANT_MethodHandle into
* 9 different items.
*/
static final int MHANDLE_BASE = 20;
/**
* Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
* instead of the constant pool, in order to avoid clashes with normal
* constant pool items in the ClassWriter constant pool's hash table.