1 Commits
master ... raft

Author SHA1 Message Date
dong9297
821add2a62 add write boolean to util 2022-05-26 20:29:33 +08:00
253 changed files with 30215 additions and 32264 deletions

View File

@@ -6,8 +6,6 @@ plugins {
id 'com.github.johnrengelman.shadow' version '4.0.2' id 'com.github.johnrengelman.shadow' version '4.0.2'
} }
apply from: '../spotless.gradle'
shadowJar { shadowJar {
classifier = "jar" classifier = "jar"
dependencies { dependencies {
@@ -16,7 +14,6 @@ shadowJar {
// relocate 'com.google.code.gson', 'irs.com.google.code.gson' // relocate 'com.google.code.gson', 'irs.com.google.code.gson'
} }
} }
sourceSets { sourceSets {
main { main {
java { java {
@@ -40,22 +37,22 @@ sourceCompatibility = 1.8
dependencies { dependencies {
api 'org.bdware.bdcontract:gmhelper:0.2.0' api 'org.bdware.bdcontract:gmhelper:0.2.0'
api 'berkeleydb:je:3.2.76' api 'berkeleydb:je:3.2.76'
// api 'com.fifesoft:rsyntaxtextarea:3.1.3'
api 'commons-io:commons-io:2.11.0' api 'commons-io:commons-io:2.11.0'
api 'io.netty:netty-all:4.1.86.Final' api 'io.netty:netty-all:4.1.72.Final'
api 'org.antlr:antlr4:4.9.2' api 'org.antlr:antlr4:4.9.2'
api 'commons-codec:commons-codec:1.13' api 'commons-codec:commons-codec:1.5'
api 'org.apache.logging.log4j:log4j-core:2.17.2' api 'org.apache.logging.log4j:log4j-core:2.17.2'
api 'org.apache.logging.log4j:log4j-api:2.17.2' api 'org.apache.logging.log4j:log4j-api:2.17.2'
// api 'com.fifesoft:rsyntaxtextarea:3.1.3'
// api fileTree(dir: 'lib', include: '*.jar')
//api 'org.apache.velocity:velocity-engine-core:2.3' //api 'org.apache.velocity:velocity-engine-core:2.3'
api 'org.rocksdb:rocksdbjni:7.3.1' api 'org.rocksdb:rocksdbjni:6.22.1'
// api fileTree(dir: 'lib', include: '*.jar')
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
implementation 'org.bdware.doip:doip-sdk:1.5.9'
} }
group = "org.bdware.sc" group = "org.bdware.sc"
version = "1.5.6"
version = "1.8.2"
tasks.processResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE) tasks.processResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
task copyLibs(type: Copy) { task copyLibs(type: Copy) {
@@ -71,12 +68,6 @@ task copyJar(type: Copy) {
//task classJar(type: Jar, dependsOn: classes) { //task classJar(type: Jar, dependsOn: classes) {
// classifier = "jar" // classifier = "jar"
//} //}
tasks.withType(Copy).all {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.withType(Jar).all {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
task sourceJar(type: Jar, dependsOn: classes) { task sourceJar(type: Jar, dependsOn: classes) {
archiveClassifier = "sources" archiveClassifier = "sources"
classifier = "sources" classifier = "sources"
@@ -89,7 +80,8 @@ tasks.withType(Javadoc) {
task javadocJar(type: Jar, dependsOn: javadoc) { task javadocJar(type: Jar, dependsOn: javadoc) {
archiveClassifier = 'javadoc' archiveClassifier = 'javadoc'
classifier = "javadoc" classifier = "javadoc"
exclude { details -> details.file.getAbsolutePath().contains("/gm/") exclude {
details -> details.file.getAbsolutePath().contains("/gm/")
} }
from javadoc.destinationDir from javadoc.destinationDir
} }

View File

@@ -3,7 +3,8 @@ package org.bdware.analysis;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
public abstract class AnalysisResult { public abstract class AnalysisResult {
public AnalysisResult() {} public AnalysisResult() {
}
public abstract AnalysisResult merge(AbstractInsnNode insn); public abstract AnalysisResult merge(AbstractInsnNode insn);

View File

@@ -35,8 +35,8 @@ public abstract class BreadthFirstSearch<R extends AnalysisResult, T extends Ana
for (T next : sucs) { for (T next : sucs) {
if (toAnalysis.contains(next)) { if (toAnalysis.contains(next)) {
// results.remove(next); //results.remove(next);
// toAnalysis.remove(next); //toAnalysis.remove(next);
} }
if (!next.inList()) { if (!next.inList()) {
toAnalysis.add(next); toAnalysis.add(next);

View File

@@ -19,7 +19,7 @@ public abstract class CFGraph {
// type2(canThrow) and catchLabels // type2(canThrow) and catchLabels
// type3 and target labels // type3 and target labels
// type4 and catchLabels // type4 and catchLabels
// private List<TryCatchBlockNode> tryCacheList; // private List<TryCatchBlockNode> tryCacheList;
// Pass1: build basic blocks // Pass1: build basic blocks
// create a new block when: // create a new block when:
// 1.starts with Label(can jump) // 1.starts with Label(can jump)
@@ -110,8 +110,8 @@ public abstract class CFGraph {
public void printSelf() { public void printSelf() {
InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out); InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out);
printer.setLabelOrder(getLabelOrder()); printer.setLabelOrder(getLabelOrder());
LOGGER.info("isStatic: " + ((methodNode.access & Opcodes.ACC_STATIC) > 0) + "\tMethod:" LOGGER.info("isStatic: " + ((methodNode.access & Opcodes.ACC_STATIC) > 0)
+ methodNode.name + " " + methodNode.desc); + "\tMethod:" + methodNode.name + " " + methodNode.desc);
LOGGER.info(methodNode.maxLocals + " " + methodNode.maxStack); LOGGER.info(methodNode.maxLocals + " " + methodNode.maxStack);
StringBuilder log = new StringBuilder(); StringBuilder log = new StringBuilder();
for (BasicBlock bb : basicBlocks) { for (BasicBlock bb : basicBlocks) {
@@ -171,17 +171,21 @@ public abstract class CFGraph {
/** /**
* Visits a zero operand instruction. * Visits a zero operand instruction.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is either NOP, * @param opcode the opcode of the instruction to be visited. This opcode is
* ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
* ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
* IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
* FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
* DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
* DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
* LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
* I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, DRETURN, * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
* ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT. * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or
* MONITOREXIT.
*/ */
public void visitInsn(int opcode) { public void visitInsn(int opcode) {
currBlock.add(currInsn); currBlock.add(currInsn);
@@ -195,56 +199,57 @@ public abstract class CFGraph {
/** /**
* Visits an instruction with a single int operand. * Visits an instruction with a single int operand.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, * @param opcode the opcode of the instruction to be visited. This opcode is
* SIPUSH or NEWARRAY. * either BIPUSH, SIPUSH or NEWARRAY.
* @param operand the operand of the instruction to be visited.<br> * @param operand the operand of the instruction to be visited.<br>
* When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and * When opcode is BIPUSH, operand value should be between
* Byte.MAX_VALUE.<br> * Byte.MIN_VALUE and Byte.MAX_VALUE.<br>
* When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and * When opcode is SIPUSH, operand value should be between
* Short.MAX_VALUE.<br> * Short.MIN_VALUE and Short.MAX_VALUE.<br>
* When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, * When opcode is NEWARRAY, operand value should be one of
* {@link Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
* {@link Opcodes#T_LONG}. * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/ */
public void visitIntInsn(int opcode, int operand) { public void visitIntInsn(int opcode, int operand) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a local variable instruction. A local variable instruction is an instruction that * Visits a local variable instruction. A local variable instruction is an
* loads or stores the value of a local variable. * instruction that loads or stores the value of a local variable.
* *
* @param opcode the opcode of the local variable instruction to be visited. This opcode is * @param opcode the opcode of the local variable instruction to be visited.
* either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
* or RET. * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* @param var the operand of the instruction to be visited. This operand is the index of a * @param var the operand of the instruction to be visited. This operand is
* local variable. * the index of a local variable.
*/ */
public void visitVarInsn(int opcode, int var) { public void visitVarInsn(int opcode, int var) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a type instruction. A type instruction is an instruction that takes the internal * Visits a type instruction. A type instruction is an instruction that takes
* name of a class as parameter. * the internal name of a class as parameter.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either * @param opcode the opcode of the type instruction to be visited. This opcode
* NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
* @param type the operand of the instruction to be visited. This operand must be the * @param type the operand of the instruction to be visited. This operand must
* internal name of an object or array class (see {@link Type#getInternalName() * be the internal name of an object or array class (see
* getInternalName}). * {@link Type#getInternalName() getInternalName}).
*/ */
public void visitTypeInsn(int opcode, String type) { public void visitTypeInsn(int opcode, String type) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a field instruction. A field instruction is an instruction that loads or stores * Visits a field instruction. A field instruction is an instruction that loads
* the value of a field of an object. * or stores the value of a field of an object.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either * @param opcode the opcode of the type instruction to be visited. This opcode
* GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* @param owner the internal name of the field's owner class (see * @param owner the internal name of the field's owner class (see
* {@link Type#getInternalName() getInternalName}). * {@link Type#getInternalName() getInternalName}).
* @param name the field's name. * @param name the field's name.
@@ -255,11 +260,12 @@ public abstract class CFGraph {
} }
/** /**
* Visits a method instruction. A method instruction is an instruction that invokes a * Visits a method instruction. A method instruction is an instruction that
* method. * invokes a method.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either * @param opcode the opcode of the type instruction to be visited. This opcode
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
* INVOKEINTERFACE.
* @param owner the internal name of the method's owner class (see * @param owner the internal name of the method's owner class (see
* {@link Type#getInternalName() getInternalName}). * {@link Type#getInternalName() getInternalName}).
* @param name the method's name. * @param name the method's name.
@@ -285,13 +291,13 @@ public abstract class CFGraph {
* @param name the method's name. * @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}). * @param desc the method's descriptor (see {@link Type Type}).
* @param bsm the bootstrap method. * @param bsm the bootstrap method.
* @param bsmArgs the bootstrap method constant arguments. Each argument must be an * @param bsmArgs the bootstrap method constant arguments. Each argument must be
* {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, * an {@link Integer}, {@link Float}, {@link Long},
* {@link Type} or {@link Handle} value. This method is allowed to modify the content * {@link Double}, {@link String}, {@link Type} or {@link Handle}
* of the array so a caller should expect that this array may change. * value. This method is allowed to modify the content of the
* array so a caller should expect that this array may change.
*/ */
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
Object... bsmArgs) {
// TODO add edges to try catch blocks! // TODO add edges to try catch blocks!
currBlock.add(currInsn); currBlock.add(currInsn);
@@ -303,14 +309,16 @@ public abstract class CFGraph {
} }
/** /**
* Visits a jump instruction. A jump instruction is an instruction that may jump to another * Visits a jump instruction. A jump instruction is an instruction that may jump
* instruction. * to another instruction.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either * @param opcode the opcode of the type instruction to be visited. This opcode
* IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
* IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* @param label the operand of the instruction to be visited. This operand is a label that * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* designates the instruction to which the jump instruction may jump. * @param label the operand of the instruction to be visited. This operand is a
* label that designates the instruction to which the jump
* instruction may jump.
*/ */
public void visitJumpInsn(int opcode, Label label) { public void visitJumpInsn(int opcode, Label label) {
currBlock.add(currInsn); currBlock.add(currInsn);
@@ -323,7 +331,8 @@ public abstract class CFGraph {
} }
/** /**
* Visits a label. A label designates the instruction that will be visited just after it. * Visits a label. A label designates the instruction that will be visited just
* after it.
* *
* @param label a {@link Label Label} object. * @param label a {@link Label Label} object.
*/ */
@@ -340,9 +349,10 @@ public abstract class CFGraph {
} }
/** /**
* Visits a LDC instruction. Note that new constant types may be added in future versions of * Visits a LDC instruction. Note that new constant types may be added in future
* the Java Virtual Machine. To easily detect new constant types, implementations of this * versions of the Java Virtual Machine. To easily detect new constant types,
* method should check for unexpected constant types, like this: * implementations of this method should check for unexpected constant types,
* like this:
* *
* <pre> * <pre>
* if (cst instanceof Integer) { * if (cst instanceof Integer) {
@@ -373,11 +383,12 @@ public abstract class CFGraph {
* } * }
* </pre> * </pre>
* *
* @param cst the constant to be loaded on the stack. This parameter must be a non null * @param cst the constant to be loaded on the stack. This parameter must be a
* {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a * non null {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link String}, a {@link Type} of OBJECT or ARRAY sort for <tt>.class</tt> * {@link Double}, a {@link String}, a {@link Type} of OBJECT or
* constants, for classes whose version is 49.0, a {@link Type} of METHOD sort or a * ARRAY sort for <tt>.class</tt> constants, for classes whose
* {@link Handle} for MethodType and MethodHandle constants, for classes whose * version is 49.0, a {@link Type} of METHOD sort or a {@link Handle}
* for MethodType and MethodHandle constants, for classes whose
* version is 51.0. * version is 51.0.
*/ */
public void visitLdcInsn(Object cst) { public void visitLdcInsn(Object cst) {
@@ -403,8 +414,8 @@ public abstract class CFGraph {
* @param min the minimum key value. * @param min the minimum key value.
* @param max the maximum key value. * @param max the maximum key value.
* @param dflt beginning of the default handler block. * @param dflt beginning of the default handler block.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the
* the handler block for the <tt>min + i</tt> key. * beginning of the handler block for the <tt>min + i</tt> key.
*/ */
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
currBlock.add(currInsn); currBlock.add(currInsn);
@@ -417,8 +428,8 @@ public abstract class CFGraph {
* *
* @param dflt beginning of the default handler block. * @param dflt beginning of the default handler block.
* @param keys the values of the keys. * @param keys the values of the keys.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the
* the handler block for the <tt>keys[i]</tt> key. * beginning of the handler block for the <tt>keys[i]</tt> key.
*/ */
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
currBlock.add(currInsn); currBlock.add(currInsn);
@@ -441,29 +452,31 @@ public abstract class CFGraph {
* *
* @param name the name of a local variable. * @param name the name of a local variable.
* @param desc the type descriptor of this local variable. * @param desc the type descriptor of this local variable.
* @param signature the type signature of this local variable. May be <tt>null</tt> if the * @param signature the type signature of this local variable. May be
* local variable type does not use generic types. * <tt>null</tt> if the local variable type does not use
* @param start the first instruction corresponding to the scope of this local variable * generic types.
* (inclusive). * @param start the first instruction corresponding to the scope of this
* @param end the last instruction corresponding to the scope of this local variable * local variable (inclusive).
* (exclusive). * @param end the last instruction corresponding to the scope of this
* local variable (exclusive).
* @param index the local variable's index. * @param index the local variable's index.
* @throws IllegalArgumentException if one of the labels has not already been visited by * @throws IllegalArgumentException if one of the labels has not already been
* this visitor (by the {@link #visitLabel visitLabel} method). * visited by this visitor (by the
* {@link #visitLabel visitLabel} method).
*/ */
public void visitLocalVariable(String name, String desc, String signature, Label start, public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
Label end, int index) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a line number declaration. * Visits a line number declaration.
* *
* @param line a line number. This number refers to the source file from which the class was * @param line a line number. This number refers to the source file from which
* compiled. * the class was compiled.
* @param start the first instruction corresponding to this line number. * @param start the first instruction corresponding to this line number.
* @throws IllegalArgumentException if <tt>start</tt> has not already been visited by this * @throws IllegalArgumentException if <tt>start</tt> has not already been
* visitor (by the {@link #visitLabel visitLabel} method). * visited by this visitor (by the
* {@link #visitLabel visitLabel} method).
*/ */
public void visitLineNumber(int line, Label start) { public void visitLineNumber(int line, Label start) {
currBlock.add(currInsn); currBlock.add(currInsn);
@@ -544,8 +557,7 @@ public abstract class CFGraph {
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
Object... bsmArgs) {
addTryCatchNodes(); addTryCatchNodes();
} }

View File

@@ -8,6 +8,10 @@ import java.util.List;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.bdware.analysis.BasicBlock;
import org.bdware.analysis.CFGraph;
import org.bdware.analysis.InsnPrinter;
import org.bdware.analysis.OpInfo;
import org.bdware.analysis.taint.TaintBB; import org.bdware.analysis.taint.TaintBB;
import org.bdware.analysis.taint.TaintCFG; import org.bdware.analysis.taint.TaintCFG;
@@ -47,10 +51,10 @@ public class FrontCF {
public static class FrontBB { public static class FrontBB {
String type; String type;
String name; // BlockNumber String name; //BlockNumber
List<String> stmts; // BlockInstructions List<String> stmts; //BlockInstructions
String original; String original;
String result; // preResult String result; //preResult
String blockDep; String blockDep;
} }
@@ -71,18 +75,18 @@ public class FrontCF {
fb.type = "Continuous"; fb.type = "Continuous";
fb.original = original; fb.original = original;
// added //added
TaintBB b = (TaintBB) bb; TaintBB b = (TaintBB) bb;
// if(b.preResult != null) //if(b.preResult != null)
// b.preResult.printResult(); //b.preResult.printResult();
fb.result = b.getResult(); fb.result = b.getResult();
if (ids == null) if(ids == null)
fb.blockDep = ""; fb.blockDep = "";
else { else{
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
// sb.append("Dependence: "); //sb.append("Dependence: ");
for (Integer id : ids) { for(Integer id : ids) {
// sb.append("B"+ id +" "); //sb.append("B"+ id +" ");
TaintBB tb = (TaintBB) cfg.getBasicBlockAt(id); TaintBB tb = (TaintBB) cfg.getBasicBlockAt(id);
sb.append(tb.preResult.frame.getStack(0).toReadableTaint()); sb.append(tb.preResult.frame.getStack(0).toReadableTaint());
} }

View File

@@ -25,17 +25,21 @@ public class InsnPrinter extends MethodVisitor {
/** /**
* Visits a zero operand instruction. * Visits a zero operand instruction.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is either NOP, * @param opcode the opcode of the instruction to be visited. This opcode is
* ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
* LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
* FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE, * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
* AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
* IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
* L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
* IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
* MONITORENTER, or MONITOREXIT. * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or
* MONITOREXIT.
*/ */
public void visitInsn(int opcode) { public void visitInsn(int opcode) {
ps.println(OpInfo.ops[opcode].toString()); ps.println(OpInfo.ops[opcode].toString());
@@ -44,31 +48,32 @@ public class InsnPrinter extends MethodVisitor {
/** /**
* Visits an instruction with a single int operand. * Visits an instruction with a single int operand.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, * @param opcode the opcode of the instruction to be visited. This opcode is
* SIPUSH or NEWARRAY. * either BIPUSH, SIPUSH or NEWARRAY.
* @param operand the operand of the instruction to be visited.<br> * @param operand the operand of the instruction to be visited.<br>
* When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and * When opcode is BIPUSH, operand value should be between
* Byte.MAX_VALUE.<br> * Byte.MIN_VALUE and Byte.MAX_VALUE.<br>
* When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and * When opcode is SIPUSH, operand value should be between
* Short.MAX_VALUE.<br> * Short.MIN_VALUE and Short.MAX_VALUE.<br>
* When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, * When opcode is NEWARRAY, operand value should be one of
* {@link Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
* {@link Opcodes#T_LONG}. * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/ */
public void visitIntInsn(int opcode, int operand) { public void visitIntInsn(int opcode, int operand) {
ps.println(OpInfo.ops[opcode].toString() + " " + operand); ps.println(OpInfo.ops[opcode].toString() + " " + operand);
} }
/** /**
* Visits a local variable instruction. A local variable instruction is an instruction that * Visits a local variable instruction. A local variable instruction is an
* loads or stores the value of a local variable. * instruction that loads or stores the value of a local variable.
* *
* @param opcode the opcode of the local variable instruction to be visited. This opcode is * @param opcode the opcode of the local variable instruction to be visited.
* either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
* RET. * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* @param var the operand of the instruction to be visited. This operand is the index of a local * @param var the operand of the instruction to be visited. This operand is
* variable. * the index of a local variable.
*/ */
public void visitVarInsn(int opcode, int var) { public void visitVarInsn(int opcode, int var) {
ps.println(OpInfo.ops[opcode].toString() + " " + var); ps.println(OpInfo.ops[opcode].toString() + " " + var);
@@ -76,13 +81,14 @@ public class InsnPrinter extends MethodVisitor {
} }
/** /**
* Visits a type instruction. A type instruction is an instruction that takes the internal name * Visits a type instruction. A type instruction is an instruction that takes
* of a class as parameter. * the internal name of a class as parameter.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either NEW, * @param opcode the opcode of the type instruction to be visited. This opcode
* ANEWARRAY, CHECKCAST or INSTANCEOF. * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
* @param type the operand of the instruction to be visited. This operand must be the internal * @param type the operand of the instruction to be visited. This operand must
* name of an object or array class (see {@link Type#getInternalName() getInternalName}). * be the internal name of an object or array class (see
* {@link Type#getInternalName() getInternalName}).
*/ */
public void visitTypeInsn(int opcode, String type) { public void visitTypeInsn(int opcode, String type) {
ps.println(OpInfo.ops[opcode].toString() + " " + type); ps.println(OpInfo.ops[opcode].toString() + " " + type);
@@ -90,13 +96,13 @@ public class InsnPrinter extends MethodVisitor {
} }
/** /**
* Visits a field instruction. A field instruction is an instruction that loads or stores the * Visits a field instruction. A field instruction is an instruction that loads
* value of a field of an object. * or stores the value of a field of an object.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either * @param opcode the opcode of the type instruction to be visited. This opcode
* GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* @param owner the internal name of the field's owner class (see {@link Type#getInternalName() * @param owner the internal name of the field's owner class (see
* getInternalName}). * {@link Type#getInternalName() getInternalName}).
* @param name the field's name. * @param name the field's name.
* @param desc the field's descriptor (see {@link Type Type}). * @param desc the field's descriptor (see {@link Type Type}).
*/ */
@@ -106,12 +112,14 @@ public class InsnPrinter extends MethodVisitor {
} }
/** /**
* Visits a method instruction. A method instruction is an instruction that invokes a method. * Visits a method instruction. A method instruction is an instruction that
* invokes a method.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either * @param opcode the opcode of the type instruction to be visited. This opcode
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
* @param owner the internal name of the method's owner class (see {@link Type#getInternalName() * INVOKEINTERFACE.
* getInternalName}). * @param owner the internal name of the method's owner class (see
* {@link Type#getInternalName() getInternalName}).
* @param name the method's name. * @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}). * @param desc the method's descriptor (see {@link Type Type}).
*/ */
@@ -126,14 +134,15 @@ public class InsnPrinter extends MethodVisitor {
* @param name the method's name. * @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}). * @param desc the method's descriptor (see {@link Type Type}).
* @param bsm the bootstrap method. * @param bsm the bootstrap method.
* @param bsmArgs the bootstrap method constant arguments. Each argument must be an * @param bsmArgs the bootstrap method constant arguments. Each argument must be
* {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, * an {@link Integer}, {@link Float}, {@link Long},
* {@link Type} or {@link Handle} value. This method is allowed to modify the content of * {@link Double}, {@link String}, {@link Type} or {@link Handle}
* the array so a caller should expect that this array may change. * value. This method is allowed to modify the content of the
* array so a caller should expect that this array may change.
*/ */
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
ps.println(OpInfo.INVOKEDYNAMIC.toString() + " " + name + " " + desc + " HANDLE:" ps.println(OpInfo.INVOKEDYNAMIC.toString() + " " + name + " " + desc + " HANDLE:" + bsm.toString() + " "
+ bsm.toString() + " " + objs2Str(bsmArgs)); + objs2Str(bsmArgs));
} }
@@ -145,14 +154,16 @@ public class InsnPrinter extends MethodVisitor {
} }
/** /**
* Visits a jump instruction. A jump instruction is an instruction that may jump to another * Visits a jump instruction. A jump instruction is an instruction that may jump
* instruction. * to another instruction.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ, * @param opcode the opcode of the type instruction to be visited. This opcode
* IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
* IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* @param label the operand of the instruction to be visited. This operand is a label that * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* designates the instruction to which the jump instruction may jump. * @param label the operand of the instruction to be visited. This operand is a
* label that designates the instruction to which the jump
* instruction may jump.
*/ */
public void visitJumpInsn(int opcode, Label label) { public void visitJumpInsn(int opcode, Label label) {
ps.println(OpInfo.ops[opcode].toString() + getLabelStr(label)); ps.println(OpInfo.ops[opcode].toString() + getLabelStr(label));
@@ -160,7 +171,8 @@ public class InsnPrinter extends MethodVisitor {
} }
/** /**
* Visits a label. A label designates the instruction that will be visited just after it. * Visits a label. A label designates the instruction that will be visited just
* after it.
* *
* @param label a {@link Label Label} object. * @param label a {@link Label Label} object.
*/ */
@@ -178,9 +190,10 @@ public class InsnPrinter extends MethodVisitor {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Visits a LDC instruction. Note that new constant types may be added in future versions of the * Visits a LDC instruction. Note that new constant types may be added in future
* Java Virtual Machine. To easily detect new constant types, implementations of this method * versions of the Java Virtual Machine. To easily detect new constant types,
* should check for unexpected constant types, like this: * implementations of this method should check for unexpected constant types,
* like this:
* *
* <pre> * <pre>
* if (cst instanceof Integer) { * if (cst instanceof Integer) {
@@ -211,11 +224,13 @@ public class InsnPrinter extends MethodVisitor {
* } * }
* </pre> * </pre>
* *
* @param cst the constant to be loaded on the stack. This parameter must be a non null * @param cst the constant to be loaded on the stack. This parameter must be a
* {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, * non null {@link Integer}, a {@link Float}, a {@link Long}, a
* a {@link Type} of OBJECT or ARRAY sort for <tt>.class</tt> constants, for classes * {@link Double}, a {@link String}, a {@link Type} of OBJECT or
* whose version is 49.0, a {@link Type} of METHOD sort or a {@link Handle} for * ARRAY sort for <tt>.class</tt> constants, for classes whose
* MethodType and MethodHandle constants, for classes whose version is 51.0. * version is 49.0, a {@link Type} of METHOD sort or a {@link Handle}
* for MethodType and MethodHandle constants, for classes whose
* version is 51.0.
*/ */
public void visitLdcInsn(Object cst) { public void visitLdcInsn(Object cst) {
ps.println("ldc " + cst); ps.println("ldc " + cst);
@@ -237,12 +252,11 @@ public class InsnPrinter extends MethodVisitor {
* @param min the minimum key value. * @param min the minimum key value.
* @param max the maximum key value. * @param max the maximum key value.
* @param dflt beginning of the default handler block. * @param dflt beginning of the default handler block.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the
* handler block for the <tt>min + i</tt> key. * beginning of the handler block for the <tt>min + i</tt> key.
*/ */
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
ps.println(OpInfo.TABLESWITCH.toString() + " labels:" + getLabelStr(dflt) + " " ps.println(OpInfo.TABLESWITCH.toString() + " labels:" + getLabelStr(dflt) + " " + convertLabels(labels));
+ convertLabels(labels));
} }
@@ -258,12 +272,11 @@ public class InsnPrinter extends MethodVisitor {
* *
* @param dflt beginning of the default handler block. * @param dflt beginning of the default handler block.
* @param keys the values of the keys. * @param keys the values of the keys.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the
* handler block for the <tt>keys[i]</tt> key. * beginning of the handler block for the <tt>keys[i]</tt> key.
*/ */
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
ps.println(OpInfo.LOOKUPSWITCH.toString() + " labels:" + getLabelStr(dflt) + " " ps.println(OpInfo.LOOKUPSWITCH.toString() + " labels:" + getLabelStr(dflt) + " " + convertLabels(labels));
+ convertLabels(labels));
} }

View File

@@ -186,8 +186,7 @@ public enum OpInfo implements CFType {
INVOKEVIRTUAL(0xb6, "invokevirtual", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- INVOKEVIRTUAL(0xb6, "invokevirtual", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
INVOKESPECIAL(0xb7, "invokespecial", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- INVOKESPECIAL(0xb7, "invokespecial", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
INVOKESTATIC(0xb8, "invokestatic", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- INVOKESTATIC(0xb8, "invokestatic", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
INVOKEINTERFACE(0xb9, "invokeinterface", kInstrInvoke | kInstrCanThrow, 0), // dynamic INVOKEINTERFACE(0xb9, "invokeinterface", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
// changing-- --
INVOKEDYNAMIC(0xba, "invokedynamic", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- INVOKEDYNAMIC(0xba, "invokedynamic", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
NEW(0xbb, "new", kInstrCanContinue, 1), // -- NEW(0xbb, "new", kInstrCanContinue, 1), // --
NEWARRAY(0xbc, "newarray", kInstrCanContinue, 0), // -- NEWARRAY(0xbc, "newarray", kInstrCanContinue, 0), // --
@@ -204,7 +203,6 @@ public enum OpInfo implements CFType {
IFNONNULL(0xc7, "ifnonnull", kInstrCanBranch, -1), // -- IFNONNULL(0xc7, "ifnonnull", kInstrCanBranch, -1), // --
GOTO_W(0xc8, "goto_w", kInstrCanBranch, 0), // -- GOTO_W(0xc8, "goto_w", kInstrCanBranch, 0), // --
JSR_W(0xc9, "jsr_w", kInstrCanContinue, 1);// ??-- JSR_W(0xc9, "jsr_w", kInstrCanContinue, 1);// ??--
public final static OpInfo ops[] = new OpInfo[256]; public final static OpInfo ops[] = new OpInfo[256];
static { static {
@@ -221,7 +219,8 @@ public enum OpInfo implements CFType {
private String displayName; private String displayName;
private int opcode; private int opcode;
OpInfo() {} OpInfo() {
}
OpInfo(int opcode, String displayName, int branchType, int changStack) { OpInfo(int opcode, String displayName, int branchType, int changStack) {
flags = branchType; flags = branchType;

View File

@@ -18,8 +18,7 @@ import org.objectweb.asm.tree.MethodNode;
import java.util.*; import java.util.*;
public class FieldSensitiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, TaintBB> { public class FieldSensitiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, TaintBB> {
private static final Logger LOGGER = private static final Logger LOGGER = LogManager.getLogger(FieldSensitiveDynamicTaintAnalysis.class);
LogManager.getLogger(FieldSensitiveDynamicTaintAnalysis.class);
public static boolean isDebug = false; public static boolean isDebug = false;
TaintCFG cfg; TaintCFG cfg;
TracedFile tf; TracedFile tf;
@@ -80,8 +79,8 @@ public class FieldSensitiveDynamicTaintAnalysis extends BreadthFirstSearch<Taint
// subBlock.clear(); // subBlock.clear();
subBlock.add(cfg.getBasicBlockAt(t.blockID + 1)); subBlock.add(cfg.getBasicBlockAt(t.blockID + 1));
} else if (OpInfo.ops[insn.getOpcode()].canBranch()) { } else if (OpInfo.ops[insn.getOpcode()].canBranch()) {
// subBlock.clear(); // subBlock.clear();
// LOGGER.info("can branch " + t.blockID); // LOGGER.info("can branch " + t.blockID);
int block = handleBranchCase(subBlock, insn, t); int block = handleBranchCase(subBlock, insn, t);
subBlock.add(cfg.getBasicBlockAt(block)); subBlock.add(cfg.getBasicBlockAt(block));
} else if (OpInfo.ops[insn.getOpcode()].canSwitch()) { } else if (OpInfo.ops[insn.getOpcode()].canSwitch()) {
@@ -92,14 +91,14 @@ public class FieldSensitiveDynamicTaintAnalysis extends BreadthFirstSearch<Taint
} }
} }
Set<TaintBB> ret = new HashSet<>(); Set<TaintBB> ret = new HashSet<>();
// StringBuilder log = new StringBuilder("nextBB:"); // StringBuilder log = new StringBuilder("nextBB:");
for (BasicBlock bb : subBlock) { for (BasicBlock bb : subBlock) {
// log.append("\n\t").append(bb.blockID); // log.append("\n\t").append(bb.blockID);
TaintBB ntbb = (TaintBB) bb; TaintBB ntbb = (TaintBB) bb;
ntbb.preResult.mergeResult(t.sucResult); ntbb.preResult.mergeResult(t.sucResult);
ret.add(ntbb); ret.add(ntbb);
} }
// LOGGER.info(log.toString()); // LOGGER.info(log.toString());
return ret; return ret;
} }

View File

@@ -27,8 +27,7 @@ public class NaiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, T
String methodDesc = mn.desc; String methodDesc = mn.desc;
methodDesc = methodDesc.replaceAll("\\).*$", ")"); methodDesc = methodDesc.replaceAll("\\).*$", ")");
int pos = 2; int pos = 2;
if (methodDesc.split(";").length == 3) if (methodDesc.split(";").length == 3) pos = 1;
pos = 1;
// TODO add inputBlock! // TODO add inputBlock!
TaintBB b = (TaintBB) cfg.getBasicBlockAt(0); TaintBB b = (TaintBB) cfg.getBasicBlockAt(0);
b.preResult = new TaintResult(); b.preResult = new TaintResult();
@@ -48,7 +47,10 @@ public class NaiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, T
setToAnalysis(toAnalysis); setToAnalysis(toAnalysis);
if (isDebug) { if (isDebug) {
System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc); System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc);
System.out.println("===Local:" + cfg.getMethodNode().maxLocals + " " System.out.println(
"===Local:"
+ cfg.getMethodNode().maxLocals
+ " "
+ cfg.getMethodNode().maxStack); + cfg.getMethodNode().maxStack);
} }
} }
@@ -66,8 +68,7 @@ public class NaiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, T
AbstractInsnNode insn = t.lastInsn(); AbstractInsnNode insn = t.lastInsn();
if (insn != null) { if (insn != null) {
OpInfo info = null; OpInfo info = null;
if (insn.getOpcode() >= 0) if (insn.getOpcode() >= 0) info = OpInfo.ops[insn.getOpcode()];
info = OpInfo.ops[insn.getOpcode()];
if (info == null) { if (info == null) {
subBlock.addAll(cfg.getSucBlocks(t)); subBlock.addAll(cfg.getSucBlocks(t));
} else if (info.canThrow()) { } else if (info.canThrow()) {
@@ -103,8 +104,9 @@ public class NaiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, T
if (functionName.contains("traceif")) { if (functionName.contains("traceif")) {
traceIfNum = (int) invoke; traceIfNum = (int) invoke;
if (branchCount.get(functionGlobel).containsKey(traceIfNum)) { if (branchCount.get(functionGlobel).containsKey(traceIfNum)) {
branchCount.get(functionGlobel).put(traceIfNum, branchCount
branchCount.get(functionGlobel).get(traceIfNum) + 1); .get(functionGlobel)
.put(traceIfNum, branchCount.get(functionGlobel).get(traceIfNum) + 1);
} else { } else {
branchCount.get(functionGlobel).put(traceIfNum, 1); branchCount.get(functionGlobel).put(traceIfNum, 1);
} }

View File

@@ -43,13 +43,13 @@ public class ProgramPoint {
JsonObject jo = JsonUtil.parseStringAsJsonObject(string); JsonObject jo = JsonUtil.parseStringAsJsonObject(string);
if (jo.get("traceMark") != null) { if (jo.get("traceMark") != null) {
if (jo.get("lval") != null) { if (jo.get("lval") != null) {
transaction.insert(jo.get("traceMark").getAsInt(), transaction.insert(
jo.get("lval").getAsInt()); jo.get("traceMark").getAsInt(), jo.get("lval").getAsInt());
transaction.insert(jo.get("traceMark").getAsInt(), transaction.insert(
jo.get("rval").getAsInt()); jo.get("traceMark").getAsInt(), jo.get("rval").getAsInt());
} else { } else {
transaction.insert(jo.get("traceMark").getAsInt(), transaction.insert(
jo.get("val").getAsInt()); jo.get("traceMark").getAsInt(), jo.get("val").getAsInt());
} }
} }
} }

View File

@@ -21,14 +21,16 @@ public class FieldSensitiveTaintAnalysis extends BreadthFirstSearch<TaintResult,
this.cfg = cfg; this.cfg = cfg;
List<TaintBB> toAnalysis = new ArrayList<>(); List<TaintBB> toAnalysis = new ArrayList<>();
/* /*
* NaiveTaintBB<42><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD> boolean inList NaiveTaintResult preResult NaiveTaintResult sucResult * NaiveTaintBB<42><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD> boolean inList NaiveTaintResult preResult NaiveTaintResult
* sucResult
*/ */
TaintBB b = (TaintBB) cfg.getBasicBlockAt(0); TaintBB b = (TaintBB) cfg.getBasicBlockAt(0);
/* /*
* NaiveTaintResult<6C>еı<D0B5><C4B1><EFBFBD><EFBFBD><EFBFBD> Frame<TaintValue> frame TaintInterpreter interpreter TaintValue * NaiveTaintResult<6C>еı<D0B5><C4B1><EFBFBD><EFBFBD><EFBFBD> Frame<TaintValue> frame TaintInterpreter interpreter
* ret InsnPrinter printer int nLocals int nStack NaiveTaintResult<6C>е<EFBFBD><D0B5>ࣺ TaintValue int size * TaintValue ret InsnPrinter printer int nLocals int nStack
* boolean isTainted TaintInterpreter() NaiveTaintResult currentResult Frame<6D>еı<D0B5><C4B1><EFBFBD><EFBFBD><EFBFBD> V * NaiveTaintResult<EFBFBD>е<EFBFBD><EFBFBD>ࣺ TaintValue int size boolean isTainted
* returnValue //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>Ϊvoid<69><64>Ϊnull V[] values //<2F>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD> int locals * TaintInterpreter() NaiveTaintResult currentResult Frame<6D>еı<D0B5><C4B1><EFBFBD><EFBFBD><EFBFBD> V returnValue
* //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>Ϊvoid<69><64>Ϊnull V[] values //<2F>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD> int locals
* //<2F>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD> int top //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>Ԫ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD> * //<2F>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD> int top //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>Ԫ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>
*/ */
b.preResult = new TaintResult(); b.preResult = new TaintResult();
@@ -38,9 +40,10 @@ public class FieldSensitiveTaintAnalysis extends BreadthFirstSearch<TaintResult,
TaintResult.interpreter.setTaintBits(cfg.taintBits); TaintResult.interpreter.setTaintBits(cfg.taintBits);
b.preResult.frame.setLocal(arg, new TaintValue(1, cfg.taintBits.allocate("arg" + arg))); b.preResult.frame.setLocal(arg, new TaintValue(1, cfg.taintBits.allocate("arg" + arg)));
/* /*
* if (NaiveTaintResult.nLocals > 2) { b.preResult.frame.setLocal(0, new TaintValue(1, * if (NaiveTaintResult.nLocals > 2) { b.preResult.frame.setLocal(0, new
* cfg.taintBits.allocate("arg0"))); b.preResult.frame.setLocal(1, new TaintValue(1, * TaintValue(1, cfg.taintBits.allocate("arg0"))); b.preResult.frame.setLocal(1,
* cfg.taintBits.allocate("arg1"))); b.preResult.frame.setLocal(2, new TaintValue(1, * new TaintValue(1, cfg.taintBits.allocate("arg1")));
* b.preResult.frame.setLocal(2, new TaintValue(1,
* cfg.taintBits.allocate("arg2"))); } * cfg.taintBits.allocate("arg2"))); }
*/ */
// .ret = TaintValue<75><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>size=1 // .ret = TaintValue<75><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>size=1
@@ -51,7 +54,8 @@ public class FieldSensitiveTaintAnalysis extends BreadthFirstSearch<TaintResult,
b.setInList(true); b.setInList(true);
// <20><><EFBFBD><EFBFBD>BreadthFirstSearch<63><68><EFBFBD>еĺ<D0B5><C4BA><EFBFBD>setToAnalysis<69><73><EFBFBD><EFBFBD>ʱBreadthFirstSearch<63><68><EFBFBD><EFBFBD><EFBFBD>toAnalysisΪ<73><CEAA>ǰ<EFBFBD>Ŀ<EFBFBD><C4BF>б<EFBFBD>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>B0 // <20><><EFBFBD><EFBFBD>BreadthFirstSearch<63><68><EFBFBD>еĺ<D0B5><C4BA><EFBFBD>setToAnalysis<69><73><EFBFBD><EFBFBD>ʱBreadthFirstSearch<63><68><EFBFBD><EFBFBD><EFBFBD>toAnalysisΪ<73><CEAA>ǰ<EFBFBD>Ŀ<EFBFBD><C4BF>б<EFBFBD>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>B0
/* /*
* BreadthFirstSearch<63><68><EFBFBD>еı<D0B5><C4B1><EFBFBD><EFBFBD><EFBFBD> Map<T, AnalysisResult> results; List<T> toAnalysis; * BreadthFirstSearch<63><68><EFBFBD>еı<D0B5><C4B1><EFBFBD><EFBFBD><EFBFBD> Map<T, AnalysisResult> results; List<T>
* toAnalysis;
*/ */
setToAnalysis(toAnalysis); setToAnalysis(toAnalysis);
if (isDebug) { if (isDebug) {

View File

@@ -37,7 +37,10 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
setToAnalysis(toAnalysis); setToAnalysis(toAnalysis);
if (TaintConfig.isDebug) { if (TaintConfig.isDebug) {
System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc); System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc);
System.out.println("===Local:" + cfg.getMethodNode().maxLocals + " " System.out.println(
"===Local:"
+ cfg.getMethodNode().maxLocals
+ " "
+ cfg.getMethodNode().maxStack); + cfg.getMethodNode().maxStack);
} }
} }
@@ -54,11 +57,17 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
for (BasicBlock bb : subBlock) { for (BasicBlock bb : subBlock) {
TaintBB ntbb = (TaintBB) bb; TaintBB ntbb = (TaintBB) bb;
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out.println("[MultiSoruceTaintAnalysis] B" + ntbb.blockID + " beforeMerge:" System.out.println(
"[MultiSoruceTaintAnalysis] B"
+ ntbb.blockID
+ " beforeMerge:"
+ ntbb.preResult.frame2Str()); + ntbb.preResult.frame2Str());
ntbb.preResult.mergeResult(t.sucResult); ntbb.preResult.mergeResult(t.sucResult);
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out.println("[MultiSoruceTaintAnalysis] B" + ntbb.blockID + " afterMerge:" System.out.println(
"[MultiSoruceTaintAnalysis] B"
+ ntbb.blockID
+ " afterMerge:"
+ ntbb.preResult.frame2Str()); + ntbb.preResult.frame2Str());
ret.add(ntbb); ret.add(ntbb);
@@ -86,10 +95,9 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
} }
} }
} }
/* /*Step2: Traverse all the blocks, for each block, traverse all the depBlocks,
* Step2: Traverse all the blocks, for each block, traverse all the depBlocks, for each * for each depBlock, traverse all the sucBlocks,
* depBlock, traverse all the sucBlocks, if all the sucBlocks are arrival from each block, * if all the sucBlocks are arrival from each block, then the block is dependency with the depBlock.
* then the block is dependency with the depBlock.
*/ */
List<BasicBlock> blocks = cfg.getBlocks(); List<BasicBlock> blocks = cfg.getBlocks();
Map<Integer, List<Integer>> map = new HashMap<>(); Map<Integer, List<Integer>> map = new HashMap<>();
@@ -100,11 +108,9 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
int sucSize = sucBlocks.size(); int sucSize = sucBlocks.size();
int count = 0; int count = 0;
for (BasicBlock sucBlock : sucBlocks) { for (BasicBlock sucBlock : sucBlocks) {
if (isArrival(cfg, sucBlock, bb)) if (isArrival(cfg, sucBlock, bb)) count++;
count++;
} }
if (count > 0 && count != sucSize) if (count > 0 && count != sucSize) list.add(id);
list.add(id);
} }
map.put(bb.blockID, list); map.put(bb.blockID, list);
} }
@@ -123,7 +129,9 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
} }
} }
/* /*
* for(int i : entry.getValue()) System.out.print(i+ " "); System.out.println(); for(int i : entry.getValue())
System.out.print(i+ " ");
System.out.println();
*/ */
} }
@@ -133,8 +141,7 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
for (Map.Entry<Integer, List<Integer>> entry : returnMap.entrySet()) { for (Map.Entry<Integer, List<Integer>> entry : returnMap.entrySet()) {
List<Integer> listID = entry.getValue(); List<Integer> listID = entry.getValue();
for (Integer i : listID) { for (Integer i : listID) {
if (!lastBlockDep.contains(i)) if (!lastBlockDep.contains(i)) lastBlockDep.add(i);
lastBlockDep.add(i);
} }
} }
returnMap.put(cfg.getBasicBlockSize() - 1, lastBlockDep); returnMap.put(cfg.getBasicBlockSize() - 1, lastBlockDep);
@@ -142,9 +149,13 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
// TODO get value from branch block // TODO get value from branch block
/* /*
* List<Integer> list = returnMap.get(cfg.getBasicBlockSize()-1); for(int i : list) { List<Integer> list = returnMap.get(cfg.getBasicBlockSize()-1);
* System.out.println(i); TaintBB tb = (TaintBB) cfg.getBasicBlockAt(i); for(int i : list) {
* System.out.println("Test:"); tb.preResult.printResult(); } System.out.println(i);
TaintBB tb = (TaintBB) cfg.getBasicBlockAt(i);
System.out.println("Test:");
tb.preResult.printResult();
}
*/ */
return returnMap; return returnMap;
@@ -153,14 +164,20 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
public static boolean isArrival(TaintCFG cfg, BasicBlock suc, BasicBlock bb) { public static boolean isArrival(TaintCFG cfg, BasicBlock suc, BasicBlock bb) {
// Test // Test
/* /*
* if(suc.blockID == bb.blockID) return true; if(suc.blockID == 7 && bb.blockID == 11) if(suc.blockID == bb.blockID)
* return true; if(suc.blockID == 9 && bb.blockID == 11) return true; if(suc.blockID == 7 && return true;
* bb.blockID == 12) return true; if(suc.blockID == 9 && bb.blockID == 12) return true; if(suc.blockID == 7 && bb.blockID == 11)
* return false; return true;
if(suc.blockID == 9 && bb.blockID == 11)
return true;
if(suc.blockID == 7 && bb.blockID == 12)
return true;
if(suc.blockID == 9 && bb.blockID == 12)
return true;
return false;
*/ */
if (suc.blockID == bb.blockID) if (suc.blockID == bb.blockID) return true;
return true;
DirectGraphDFS dgDFS = new DirectGraphDFS(cfg, suc); DirectGraphDFS dgDFS = new DirectGraphDFS(cfg, suc);
return dgDFS.isArrival(bb); return dgDFS.isArrival(bb);
} }

View File

@@ -33,7 +33,10 @@ public class NaiveTaintAnalysis extends BreadthFirstSearch<TaintResult, TaintBB>
setToAnalysis(toAnalysis); setToAnalysis(toAnalysis);
if (TaintConfig.isDebug) { if (TaintConfig.isDebug) {
System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc); System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc);
System.out.println("===Local:" + cfg.getMethodNode().maxLocals + " " System.out.println(
"===Local:"
+ cfg.getMethodNode().maxLocals
+ " "
+ cfg.getMethodNode().maxStack); + cfg.getMethodNode().maxStack);
} }
} }

View File

@@ -7,15 +7,13 @@ import org.bdware.analysis.BasicBlock;
public abstract class BFS { public abstract class BFS {
protected List<BasicBlock> toAnalysis; protected List<BasicBlock> toAnalysis;
public abstract Collection<BasicBlock> getSuc(BasicBlock BB); public abstract Collection<BasicBlock> getSuc(BasicBlock BB);
public void analysis() { public void analysis() {
BasicBlock current = null; BasicBlock current = null;
for (int i = 0; i < toAnalysis.size(); i++) { for (int i = 0; i < toAnalysis.size(); i++) {
current = toAnalysis.get(i); current = toAnalysis.get(i);
// current.setInList(false); //current.setInList(false);
if (current.inList()) { if(current.inList()) {
Collection<BasicBlock> sucs = getSuc(current); Collection<BasicBlock> sucs = getSuc(current);
for (BasicBlock next : sucs) { for (BasicBlock next : sucs) {
if (!next.inList()) { if (!next.inList()) {
@@ -26,7 +24,6 @@ public abstract class BFS {
} }
} }
} }
public void setToAnalysis(List<BasicBlock> l) { public void setToAnalysis(List<BasicBlock> l) {
toAnalysis = l; toAnalysis = l;
} }

View File

@@ -15,8 +15,7 @@ public abstract class DFS {
// System.out.println("[start.blockID]" + start.blockID); // System.out.println("[start.blockID]" + start.blockID);
Set<BasicBlock> sucBlocks = getSuc(start); Set<BasicBlock> sucBlocks = getSuc(start);
for (BasicBlock bb : sucBlocks) { for (BasicBlock bb : sucBlocks) {
if (!marked[bb.blockID]) if (!marked[bb.blockID]) dfs(cfg, bb);
dfs(cfg, bb);
} }
} }

View File

@@ -62,8 +62,8 @@ public class Evaluates {
Set<HashMap<String, Long>> set = new HashSet<>(); Set<HashMap<String, Long>> set = new HashSet<>();
public void getGas(HashMap<String, Set<Map<Integer, HashMap<String, Integer>>>> branchCount) { public void getGas(HashMap<String, Set<Map<Integer, HashMap<String, Integer>>>> branchCount) {
for (Entry<String, Set<Map<Integer, HashMap<String, Integer>>>> varInsn : branchCount for (Entry<String, Set<Map<Integer, HashMap<String, Integer>>>> varInsn :
.entrySet()) { branchCount.entrySet()) {
sum = 0; sum = 0;
for (Map<Integer, HashMap<String, Integer>> m : varInsn.getValue()) { for (Map<Integer, HashMap<String, Integer>> m : varInsn.getValue()) {
blockGas(m); blockGas(m);
@@ -84,8 +84,8 @@ public class Evaluates {
public static HashMap<String, Long> map = new HashMap<>(); public static HashMap<String, Long> map = new HashMap<>();
public void getInsnGas(Map<Integer, Set<Map<Integer, HashMap<String, Integer>>>> ppMap) { public void getInsnGas(Map<Integer, Set<Map<Integer, HashMap<String, Integer>>>> ppMap) {
for (Entry<Integer, Set<Map<Integer, HashMap<String, Integer>>>> varInsn : ppMap for (Entry<Integer, Set<Map<Integer, HashMap<String, Integer>>>> varInsn :
.entrySet()) { ppMap.entrySet()) {
sum = 0; sum = 0;
for (Map<Integer, HashMap<String, Integer>> m : varInsn.getValue()) { for (Map<Integer, HashMap<String, Integer>> m : varInsn.getValue()) {
blockGas(m); blockGas(m);

View File

@@ -2,8 +2,7 @@ package org.bdware.analysis.gas;
public enum FeeSchedule { public enum FeeSchedule {
// BDaload(20L),BDstore(200L), // BDaload(20L),BDstore(200L),
BDgetMethod(10L), BDsetMethod(20L), BDnew(20L), BDcallUtil(30L), BDcallFuntion(40L), BDcall( BDgetMethod(10L), BDsetMethod(20L), BDnew(20L),BDcallUtil(30L), BDcallFuntion(40L), BDcall(10L), BDjump(15L), BDInsn(1L);
10L), BDjump(15L), BDInsn(1L);
long fee; long fee;
@@ -16,28 +15,28 @@ public enum FeeSchedule {
} }
public long getValue(String name) { public long getValue(String name) {
long value = 0; long value=0;
switch (name) { switch (name) {
case "BDgetMethod": case "BDgetMethod":
value = BDgetMethod.getFee(); value=BDgetMethod.getFee();
break; break;
case "BDsetMethod": case "BDsetMethod":
value = BDsetMethod.getFee(); value= BDsetMethod.getFee();
break; break;
case "BDcallUtil": case "BDcallUtil":
value = BDcallUtil.getFee(); value= BDcallUtil.getFee();
break; break;
case "BDcallFuntion": case "BDcallFuntion":
value = BDcallFuntion.getFee(); value= BDcallFuntion.getFee();
break; break;
case "BDcall": case "BDcall":
value = BDcall.getFee(); value= BDcall.getFee();
break; break;
case "BDjump": case "BDjump":
value = BDjump.getFee(); value= BDjump.getFee();
break; break;
case "BDInsn": case "BDInsn":
value = BDInsn.getFee(); value= BDInsn.getFee();
break; break;
default: default:
break; break;

View File

@@ -11,8 +11,12 @@ import java.util.Set;
import org.bdware.analysis.BasicBlock; import org.bdware.analysis.BasicBlock;
import org.bdware.analysis.CFGraph; import org.bdware.analysis.CFGraph;
import org.bdware.analysis.OpInfo; import org.bdware.analysis.OpInfo;
import org.bdware.analysis.gas.DFS;
import org.bdware.analysis.gas.FeeSchedule;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode; import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode; import org.objectweb.asm.tree.LabelNode;
@@ -45,7 +49,7 @@ public class PPCount extends DFS {
BasicBlock b = cfg.getBasicBlockAt(0); BasicBlock b = cfg.getBasicBlockAt(0);
toAnalysis.add(b); toAnalysis.add(b);
b.setInList(true); b.setInList(true);
// System.out.println("=========:"+cfg.getMethodNode().name); // System.out.println("=========:"+cfg.getMethodNode().name);
functionList.add(cfg.getMethodNode().name); functionList.add(cfg.getMethodNode().name);
isBranchBlock = new boolean[cfg.getBasicBlockSize()]; isBranchBlock = new boolean[cfg.getBasicBlockSize()];
// setToAnalysis(toAnalysis); // setToAnalysis(toAnalysis);
@@ -298,32 +302,32 @@ public class PPCount extends DFS {
if (function.contains("getProp")) { if (function.contains("getProp")) {
bdName = FeeSchedule.BDgetMethod.name(); bdName = FeeSchedule.BDgetMethod.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID).put(bdName, BlockInsn.get(globalBlockID)
BlockInsn.get(globalBlockID).get(bdName) + 1); .put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (function.contains("setProp")) { } else if (function.contains("setProp")) {
bdName = FeeSchedule.BDsetMethod.name(); bdName = FeeSchedule.BDsetMethod.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID).put(bdName, BlockInsn.get(globalBlockID)
BlockInsn.get(globalBlockID).get(bdName) + 1); .put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (function.contains("new")) { } else if (function.contains("new")) {
bdName = FeeSchedule.BDnew.name(); bdName = FeeSchedule.BDnew.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID).put(bdName, BlockInsn.get(globalBlockID)
BlockInsn.get(globalBlockID).get(bdName) + 1); .put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (function.contains("call") && functionName.split(":")[2].contains("Util")) { } else if (function.contains("call") && functionName.split(":")[2].contains("Util")) {
bdName = FeeSchedule.BDcallUtil.name(); bdName = FeeSchedule.BDcallUtil.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID).put(bdName, BlockInsn.get(globalBlockID)
BlockInsn.get(globalBlockID).get(bdName) + 1); .put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
@@ -332,7 +336,9 @@ public class PPCount extends DFS {
String methName = functionName.split(":")[2]; String methName = functionName.split(":")[2];
bdName = FeeSchedule.BDcallFuntion.name(); bdName = FeeSchedule.BDcallFuntion.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID).put(bdName + "," + methName, BlockInsn.get(globalBlockID)
.put(
bdName + "," + methName,
BlockInsn.get(globalBlockID).get(bdName + "," + methName) + 1); BlockInsn.get(globalBlockID).get(bdName + "," + methName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
@@ -342,16 +348,16 @@ public class PPCount extends DFS {
} else if (function.contains("call")) { } else if (function.contains("call")) {
bdName = FeeSchedule.BDcall.name(); bdName = FeeSchedule.BDcall.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID).put(bdName, BlockInsn.get(globalBlockID)
BlockInsn.get(globalBlockID).get(bdName) + 1); .put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (functionName.contains("traceif")) { } else if (functionName.contains("traceif")) {
bdName = FeeSchedule.BDjump.name(); bdName = FeeSchedule.BDjump.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID).put(bdName, BlockInsn.get(globalBlockID)
BlockInsn.get(globalBlockID).get(bdName) + 1); .put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }

View File

@@ -15,8 +15,8 @@ public class DirectGraphDFS {
private void dfs(TaintCFG cfg, BasicBlock start) { private void dfs(TaintCFG cfg, BasicBlock start) {
marked[start.blockID] = true; marked[start.blockID] = true;
Set<BasicBlock> sucBlocks = cfg.getSucBlocks(start); Set<BasicBlock> sucBlocks = cfg.getSucBlocks(start);
for (BasicBlock bb : sucBlocks) { for(BasicBlock bb : sucBlocks) {
if (!marked[bb.blockID]) if(!marked[bb.blockID])
dfs(cfg, bb); dfs(cfg, bb);
} }
} }

View File

@@ -99,8 +99,7 @@ public class HeapObject extends TaintValue {
retVal = heapObject.getProp(desc); retVal = heapObject.getProp(desc);
if (retVal != null) { if (retVal != null) {
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out.println( System.out.println("[HeapObject] get:" + desc + " taintVal:" + retVal);
"[HeapObject] get:" + desc + " taintVal:" + retVal);
return retVal; return retVal;
} else { } else {
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
@@ -114,14 +113,13 @@ public class HeapObject extends TaintValue {
} else if (isDynSet((InvokeDynamicInsnNode) insn)) { } else if (isDynSet((InvokeDynamicInsnNode) insn)) {
// TaintValue tv = values.get(0); // TaintValue tv = values.get(0);
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out System.out.println("[HeapObject] set:" + desc + " taintVal:" + values.get(1));
.println("[HeapObject] set:" + desc + " taintVal:" + values.get(1));
TaintValue tval = values.get(0); TaintValue tval = values.get(0);
if (tval instanceof HeapObject) { if (tval instanceof HeapObject) {
HeapObject heapObject = (HeapObject) tval; HeapObject heapObject = (HeapObject) tval;
// heapObject.merge(values.get(1)); // heapObject.merge(values.get(1));
heapObject.setProp(desc, values.get(1) instanceof HeapObject ? values.get(1) heapObject.setProp(desc,
: new HeapObject(values.get(1))); values.get(1) instanceof HeapObject ? values.get(1) : new HeapObject(values.get(1)));
} else { } else {
HeapObject heapObject = new HeapObject(tval); HeapObject heapObject = new HeapObject(tval);
heapObject.merge(tval); heapObject.merge(tval);
@@ -160,8 +158,7 @@ public class HeapObject extends TaintValue {
} }
private static boolean isGetScopeObject(MethodInsnNode insn) { private static boolean isGetScopeObject(MethodInsnNode insn) {
if (insn.owner.contains("wrp/jdk/nashorn/internal/runtime/ScriptFunction") if (insn.owner.contains("wrp/jdk/nashorn/internal/runtime/ScriptFunction") && insn.name.equals("getScope"))
&& insn.name.equals("getScope"))
return true; return true;
return false; return false;
} }

View File

@@ -42,8 +42,7 @@ public class TaintBB extends BasicBlock implements AnalysisTarget {
TaintResult currentResult = sucResult; TaintResult currentResult = sucResult;
List<AbstractInsnNode> insns = getInsn(); List<AbstractInsnNode> insns = getInsn();
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out.println( System.out.println("[TaintBB] Enter B" + blockID + ":" + getResult() + " size:" + insns.size());
"[TaintBB] Enter B" + blockID + ":" + getResult() + " size:" + insns.size());
for (int i = 0; i < insns.size(); i++) { for (int i = 0; i < insns.size(); i++) {
currentResult = (TaintResult) currentResult.merge(insns.get(i)); currentResult = (TaintResult) currentResult.merge(insns.get(i));
@@ -51,8 +50,7 @@ public class TaintBB extends BasicBlock implements AnalysisTarget {
currentResult.mergeResult(oldSuc); currentResult.mergeResult(oldSuc);
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out.println( System.out.println("[TaintBB] Leave B" + blockID + ":" + getResult() + " size:" + insns.size());
"[TaintBB] Leave B" + blockID + ":" + getResult() + " size:" + insns.size());
// already done. // already done.
return currentResult; return currentResult;
} }
@@ -60,11 +58,9 @@ public class TaintBB extends BasicBlock implements AnalysisTarget {
public AbstractInsnNode lastInsn() { public AbstractInsnNode lastInsn() {
return list.get(list.size() - 1); return list.get(list.size() - 1);
} }
public AbstractInsnNode firstInsn() { public AbstractInsnNode firstInsn() {
return list.get(0); return list.get(0);
} }
public List<AbstractInsnNode> AllInsn() { public List<AbstractInsnNode> AllInsn() {
return list; return list;
} }

View File

@@ -48,8 +48,7 @@ public class TaintCFG extends CFGraph {
public void printSelf() { public void printSelf() {
InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out); InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out);
printer.setLabelOrder(getLabelOrder()); printer.setLabelOrder(getLabelOrder());
System.out System.out.println("======Method:" + getMethodNode().name + getMethodNode().desc + "=======");
.println("======Method:" + getMethodNode().name + getMethodNode().desc + "=======");
System.out.println("=====TaintInfo: " + taintBits.taintInfo() + "==========="); System.out.println("=====TaintInfo: " + taintBits.taintInfo() + "===========");
for (BasicBlock bb : basicBlocks) { for (BasicBlock bb : basicBlocks) {
System.out.print("==B" + bb.blockID); System.out.print("==B" + bb.blockID);
@@ -62,7 +61,7 @@ public class TaintCFG extends CFGraph {
if (b.preResult != null) { if (b.preResult != null) {
System.out.print("前序分析结果:"); System.out.print("前序分析结果:");
b.preResult.printResult(); b.preResult.printResult();
// System.out.println("test:"+b.getResultWithTaintBit()); //System.out.println("test:"+b.getResultWithTaintBit());
} }
for (AbstractInsnNode an : bb.getInsn()) { for (AbstractInsnNode an : bb.getInsn()) {

View File

@@ -52,14 +52,12 @@ public class TaintInterpreter extends Interpreter<TaintValue> {
} }
@Override @Override
public TaintValue copyOperation(AbstractInsnNode insn, TaintValue value) public TaintValue copyOperation(AbstractInsnNode insn, TaintValue value) throws AnalyzerException {
throws AnalyzerException {
return value; return value;
} }
@Override @Override
public TaintValue unaryOperation(AbstractInsnNode insn, TaintValue value) public TaintValue unaryOperation(AbstractInsnNode insn, TaintValue value) throws AnalyzerException {
throws AnalyzerException {
return value; return value;
} }
@@ -67,11 +65,12 @@ public class TaintInterpreter extends Interpreter<TaintValue> {
public TaintValue binaryOperation(AbstractInsnNode insn, TaintValue value1, TaintValue value2) public TaintValue binaryOperation(AbstractInsnNode insn, TaintValue value1, TaintValue value2)
throws AnalyzerException { throws AnalyzerException {
/* /*
* IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, LADD, FADD, DADD, * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, LADD,
* ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, * FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV,
* DREM, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, * DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND,
* FCMPL, FCMPG, DCMPL, DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, * LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IF_ICMPEQ,
* IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, PUTFIELD * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE,
* PUTFIELD
*/ */
TaintValue ret = new TaintValue(1); TaintValue ret = new TaintValue(1);
ret.isTainted = value1.isTainted | value2.isTainted; ret.isTainted = value1.isTainted | value2.isTainted;
@@ -101,20 +100,19 @@ public class TaintInterpreter extends Interpreter<TaintValue> {
} }
@Override @Override
public TaintValue ternaryOperation(AbstractInsnNode insn, TaintValue value1, TaintValue value2, public TaintValue ternaryOperation(AbstractInsnNode insn, TaintValue value1, TaintValue value2, TaintValue value3)
TaintValue value3) throws AnalyzerException { throws AnalyzerException {
// TODO // TODO
value1.isTainted |= value3.isTainted; value1.isTainted |= value3.isTainted;
return value1; return value1;
} }
@Override @Override
public TaintValue naryOperation(AbstractInsnNode insn, List<? extends TaintValue> values) public TaintValue naryOperation(AbstractInsnNode insn, List<? extends TaintValue> values) throws AnalyzerException {
throws AnalyzerException {
int size = 1; int size = 1;
/* /*
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY and * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY
* INVOKEDYNAMIC * and INVOKEDYNAMIC
*/ */
String desc; String desc;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
@@ -123,14 +121,12 @@ public class TaintInterpreter extends Interpreter<TaintValue> {
case Opcodes.INVOKESTATIC: case Opcodes.INVOKESTATIC:
case Opcodes.INVOKEINTERFACE: case Opcodes.INVOKEINTERFACE:
desc = ((MethodInsnNode) insn).desc; desc = ((MethodInsnNode) insn).desc;
if (desc != null && (desc.charAt(desc.length() - 1) == 'D' if (desc != null && (desc.charAt(desc.length() - 1) == 'D' || desc.charAt(desc.length() - 1) == 'J'))
|| desc.charAt(desc.length() - 1) == 'J'))
size = 2; size = 2;
break; break;
case Opcodes.INVOKEDYNAMIC: case Opcodes.INVOKEDYNAMIC:
desc = ((InvokeDynamicInsnNode) insn).desc; desc = ((InvokeDynamicInsnNode) insn).desc;
if (desc != null && (desc.charAt(desc.length() - 1) == 'D' if (desc != null && (desc.charAt(desc.length() - 1) == 'D' || desc.charAt(desc.length() - 1) == 'J'))
|| desc.charAt(desc.length() - 1) == 'J'))
size = 2; size = 2;
// Extra..Judgeffff x // Extra..Judgeffff x
@@ -147,8 +143,7 @@ public class TaintInterpreter extends Interpreter<TaintValue> {
if (v != null) if (v != null)
ret.isTainted |= v.isTainted; ret.isTainted |= v.isTainted;
if (insn instanceof InvokeDynamicInsnNode) { if (insn instanceof InvokeDynamicInsnNode) {
long taint = (taintBits long taint = (taintBits.getTaintValue(((InvokeDynamicInsnNode) insn).name + insn.hashCode()));
.getTaintValue(((InvokeDynamicInsnNode) insn).name + insn.hashCode()));
if (taint > 0L) if (taint > 0L)
ret.isTainted |= taint; ret.isTainted |= taint;
@@ -157,11 +152,10 @@ public class TaintInterpreter extends Interpreter<TaintValue> {
} }
@Override @Override
public void returnOperation(AbstractInsnNode insn, TaintValue value, TaintValue expected) public void returnOperation(AbstractInsnNode insn, TaintValue value, TaintValue expected) throws AnalyzerException {
throws AnalyzerException {
if (value instanceof HeapObject) { if (value instanceof HeapObject) {
currentResult.ret.isTainted |= ((HeapObject) value).wholeTaint(); currentResult.ret.isTainted |= ((HeapObject) value).wholeTaint();
} else if (value != null) } else if (value!=null)
currentResult.ret.isTainted |= value.isTainted; currentResult.ret.isTainted |= value.isTainted;
} }

View File

@@ -87,8 +87,8 @@ public class TaintResult extends AnalysisResult {
} }
/* /*
* private static boolean isTainted(TaintValue t1) { if (t1 != null && t1.isTainted) { return * private static boolean isTainted(TaintValue t1) { if (t1 != null &&
* true; } return false; } * t1.isTainted) { return true; } return false; }
*/ */
private static boolean isTainted(TaintValue t1) { private static boolean isTainted(TaintValue t1) {
if (t1 != null && t1.isTainted != 0) { if (t1 != null && t1.isTainted != 0) {
@@ -164,7 +164,7 @@ public class TaintResult extends AnalysisResult {
if (target != null) if (target != null)
frame.push(target.clone()); frame.push(target.clone());
else else
frame.push(new TaintValue(1, 0)); frame.push(new TaintValue(1,0));
} }
} }
ret.merge(from.ret); ret.merge(from.ret);

View File

@@ -1,30 +1,38 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
/** /**
* A visitor to visit a Java annotation. The methods of this class must be called in the following * A visitor to visit a Java annotation. The methods of this class must be
* order: ( <tt>visit</tt> | <tt>visitEnum</tt> | <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* * called in the following order: ( <tt>visit</tt> | <tt>visitEnum</tt> |
* <tt>visitEnd</tt>. * <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* <tt>visitEnd</tt>.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Eugene Kuleshov * @author Eugene Kuleshov
@@ -32,21 +40,23 @@ package org.objectweb.asm;
public abstract class AnnotationVisitor { public abstract class AnnotationVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field must be one of * The ASM API version implemented by this visitor. The value of this field
* {@link Opcodes#ASM4}. * must be one of {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* The annotation visitor to which this visitor must delegate method calls. May be null. * The annotation visitor to which this visitor must delegate method calls.
* May be null.
*/ */
protected AnnotationVisitor av; protected AnnotationVisitor av;
/** /**
* Constructs a new {@link AnnotationVisitor}. * Constructs a new {@link AnnotationVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
*/ */
public AnnotationVisitor(final int api) { public AnnotationVisitor(final int api) {
this(api, null); this(api, null);
@@ -55,10 +65,12 @@ public abstract class AnnotationVisitor {
/** /**
* Constructs a new {@link AnnotationVisitor}. * Constructs a new {@link AnnotationVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param av the annotation visitor to which this visitor must delegate method calls. May be * of {@link Opcodes#ASM4}.
* null. * @param av
* the annotation visitor to which this visitor must delegate
* method calls. May be null.
*/ */
public AnnotationVisitor(final int api, final AnnotationVisitor av) { public AnnotationVisitor(final int api, final AnnotationVisitor av) {
if (api != Opcodes.ASM4) { if (api != Opcodes.ASM4) {
@@ -71,13 +83,17 @@ public abstract class AnnotationVisitor {
/** /**
* Visits a primitive value of the annotation. * Visits a primitive value of the annotation.
* *
* @param name the value name. * @param name
* @param value the actual value, whose type must be {@link Byte}, {@link Boolean}, * the value name.
* {@link Character}, {@link Short}, {@link Integer} , {@link Long}, {@link Float}, * @param value
* {@link Double}, {@link String} or {@link Type} or OBJECT or ARRAY sort. This value can * the actual value, whose type must be {@link Byte},
* also be an array of byte, boolean, short, char, int, long, float or double values * {@link Boolean}, {@link Character}, {@link Short},
* (this is equivalent to using {@link #visitArray visitArray} and visiting each array * {@link Integer} , {@link Long}, {@link Float}, {@link Double},
* element in turn, but is more convenient). * {@link String} or {@link Type} or OBJECT or ARRAY sort. This
* value can also be an array of byte, boolean, short, char, int,
* long, float or double values (this is equivalent to using
* {@link #visitArray visitArray} and visiting each array element
* in turn, but is more convenient).
*/ */
public void visit(String name, Object value) { public void visit(String name, Object value) {
if (av != null) { if (av != null) {
@@ -88,9 +104,12 @@ public abstract class AnnotationVisitor {
/** /**
* Visits an enumeration value of the annotation. * Visits an enumeration value of the annotation.
* *
* @param name the value name. * @param name
* @param desc the class descriptor of the enumeration class. * the value name.
* @param value the actual enumeration value. * @param desc
* the class descriptor of the enumeration class.
* @param value
* the actual enumeration value.
*/ */
public void visitEnum(String name, String desc, String value) { public void visitEnum(String name, String desc, String value) {
if (av != null) { if (av != null) {
@@ -101,12 +120,15 @@ public abstract class AnnotationVisitor {
/** /**
* Visits a nested annotation value of the annotation. * Visits a nested annotation value of the annotation.
* *
* @param name the value name. * @param name
* @param desc the class descriptor of the nested annotation class. * the value name.
* @return a visitor to visit the actual nested annotation value, or <tt>null</tt> if this * @param desc
* visitor is not interested in visiting this nested annotation. <i>The nested * the class descriptor of the nested annotation class.
* annotation value must be fully visited before calling other methods on this * @return a visitor to visit the actual nested annotation value, or
* annotation visitor</i>. * <tt>null</tt> if this visitor is not interested in visiting this
* nested annotation. <i>The nested annotation value must be fully
* visited before calling other methods on this annotation
* visitor</i>.
*/ */
public AnnotationVisitor visitAnnotation(String name, String desc) { public AnnotationVisitor visitAnnotation(String name, String desc) {
if (av != null) { if (av != null) {
@@ -116,15 +138,18 @@ public abstract class AnnotationVisitor {
} }
/** /**
* Visits an array value of the annotation. Note that arrays of primitive types (such as byte, * Visits an array value of the annotation. Note that arrays of primitive
* boolean, short, char, int, long, float or double) can be passed as value to {@link #visit * types (such as byte, boolean, short, char, int, long, float or double)
* visit}. This is what {@link ClassReader} does. * can be passed as value to {@link #visit visit}. This is what
* {@link ClassReader} does.
* *
* @param name the value name. * @param name
* @return a visitor to visit the actual array value elements, or <tt>null</tt> if this visitor * the value name.
* is not interested in visiting these values. The 'name' parameters passed to the * @return a visitor to visit the actual array value elements, or
* methods of this visitor are ignored. <i>All the array values must be visited before * <tt>null</tt> if this visitor is not interested in visiting these
* calling other methods on this annotation visitor</i>. * values. The 'name' parameters passed to the methods of this
* visitor are ignored. <i>All the array values must be visited
* before calling other methods on this annotation visitor</i>.
*/ */
public AnnotationVisitor visitArray(String name) { public AnnotationVisitor visitArray(String name) {
if (av != null) { if (av != null) {

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -27,7 +35,8 @@ package org.objectweb.asm;
* @author Eric Bruneton * @author Eric Bruneton
* @author Eugene Kuleshov * @author Eugene Kuleshov
*/ */
final class AnnotationWriter extends AnnotationVisitor { final class AnnotationWriter extends AnnotationVisitor
{
/** /**
* The class writer to which this annotation must be added. * The class writer to which this annotation must be added.
@@ -40,24 +49,28 @@ final class AnnotationWriter extends AnnotationVisitor {
private int size; private int size;
/** /**
* <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation writers used for * <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation
* annotation default and annotation arrays use unnamed values. * writers used for annotation default and annotation arrays use unnamed
* values.
*/ */
private final boolean named; private final boolean named;
/** /**
* The annotation values in bytecode form. This byte vector only contains the values themselves, * The annotation values in bytecode form. This byte vector only contains
* i.e. the number of values must be stored as a unsigned short just before these bytes. * the values themselves, i.e. the number of values must be stored as a
* unsigned short just before these bytes.
*/ */
private final ByteVector bv; private final ByteVector bv;
/** /**
* The byte vector to be used to store the number of values of this annotation. See {@link #bv}. * The byte vector to be used to store the number of values of this
* annotation. See {@link #bv}.
*/ */
private final ByteVector parent; private final ByteVector parent;
/** /**
* Where the number of values of this annotation must be stored in {@link #parent}. * Where the number of values of this annotation must be stored in
* {@link #parent}.
*/ */
private final int offset; private final int offset;
@@ -78,14 +91,21 @@ final class AnnotationWriter extends AnnotationVisitor {
/** /**
* Constructs a new {@link AnnotationWriter}. * Constructs a new {@link AnnotationWriter}.
* *
* @param cw the class writer to which this annotation must be added. * @param cw
* @param named <tt>true<tt> if values are named, <tt>false</tt> otherwise. * the class writer to which this annotation must be added.
* @param bv where the annotation values must be stored. * @param named
* @param parent where the number of annotation values must be stored. * <tt>true<tt> if values are named, <tt>false</tt> otherwise.
* @param offset where in <tt>parent</tt> the number of annotation values must be stored. * @param bv
* where the annotation values must be stored.
* @param parent
* where the number of annotation values must be stored.
* @param offset
* where in <tt>parent</tt> the number of annotation values must
* be stored.
*/ */
AnnotationWriter(final ClassWriter cw, final boolean named, final ByteVector bv, AnnotationWriter(final ClassWriter cw, final boolean named,
final ByteVector parent, final int offset) { final ByteVector bv, final ByteVector parent, final int offset)
{
super(Opcodes.ASM4); super(Opcodes.ASM4);
this.cw = cw; this.cw = cw;
this.named = named; this.named = named;
@@ -99,92 +119,137 @@ final class AnnotationWriter extends AnnotationVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public void visit(final String name, final Object value) { public void visit(final String name, final Object value)
{
++size; ++size;
if (named) { if (named)
{
bv.putShort(cw.newUTF8(name)); bv.putShort(cw.newUTF8(name));
} }
if (value instanceof String) { if (value instanceof String)
{
bv.put12('s', cw.newUTF8((String) value)); bv.put12('s', cw.newUTF8((String) value));
} else if (value instanceof Byte) { }
else if (value instanceof Byte)
{
bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index); bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
} else if (value instanceof Boolean) { }
else if (value instanceof Boolean)
{
int v = ((Boolean) value).booleanValue() ? 1 : 0; int v = ((Boolean) value).booleanValue() ? 1 : 0;
bv.put12('Z', cw.newInteger(v).index); bv.put12('Z', cw.newInteger(v).index);
} else if (value instanceof Character) { }
else if (value instanceof Character)
{
bv.put12('C', cw.newInteger(((Character) value).charValue()).index); bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
} else if (value instanceof Short) { }
else if (value instanceof Short)
{
bv.put12('S', cw.newInteger(((Short) value).shortValue()).index); bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
} else if (value instanceof Type) { }
else if (value instanceof Type)
{
bv.put12('c', cw.newUTF8(((Type) value).getDescriptor())); bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
} else if (value instanceof byte[]) { }
else if (value instanceof byte[])
{
byte[] v = (byte[]) value; byte[] v = (byte[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) { for (int i = 0; i < v.length; i++)
{
bv.put12('B', cw.newInteger(v[i]).index); bv.put12('B', cw.newInteger(v[i]).index);
} }
} else if (value instanceof boolean[]) { }
else if (value instanceof boolean[])
{
boolean[] v = (boolean[]) value; boolean[] v = (boolean[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) { for (int i = 0; i < v.length; i++)
{
bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index); bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
} }
} else if (value instanceof short[]) { }
else if (value instanceof short[])
{
short[] v = (short[]) value; short[] v = (short[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) { for (int i = 0; i < v.length; i++)
{
bv.put12('S', cw.newInteger(v[i]).index); bv.put12('S', cw.newInteger(v[i]).index);
} }
} else if (value instanceof char[]) { }
else if (value instanceof char[])
{
char[] v = (char[]) value; char[] v = (char[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) { for (int i = 0; i < v.length; i++)
{
bv.put12('C', cw.newInteger(v[i]).index); bv.put12('C', cw.newInteger(v[i]).index);
} }
} else if (value instanceof int[]) { }
else if (value instanceof int[])
{
int[] v = (int[]) value; int[] v = (int[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) { for (int i = 0; i < v.length; i++)
{
bv.put12('I', cw.newInteger(v[i]).index); bv.put12('I', cw.newInteger(v[i]).index);
} }
} else if (value instanceof long[]) { }
else if (value instanceof long[])
{
long[] v = (long[]) value; long[] v = (long[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) { for (int i = 0; i < v.length; i++)
{
bv.put12('J', cw.newLong(v[i]).index); bv.put12('J', cw.newLong(v[i]).index);
} }
} else if (value instanceof float[]) { }
else if (value instanceof float[])
{
float[] v = (float[]) value; float[] v = (float[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) { for (int i = 0; i < v.length; i++)
{
bv.put12('F', cw.newFloat(v[i]).index); bv.put12('F', cw.newFloat(v[i]).index);
} }
} else if (value instanceof double[]) { }
else if (value instanceof double[])
{
double[] v = (double[]) value; double[] v = (double[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) { for (int i = 0; i < v.length; i++)
{
bv.put12('D', cw.newDouble(v[i]).index); bv.put12('D', cw.newDouble(v[i]).index);
} }
} else { }
else
{
Item i = cw.newConstItem(value); Item i = cw.newConstItem(value);
bv.put12(".s.IFJDCS".charAt(i.type), i.index); bv.put12(".s.IFJDCS".charAt(i.type), i.index);
} }
} }
@Override @Override
public void visitEnum(final String name, final String desc, final String value) { public void visitEnum(final String name, final String desc,
final String value)
{
++size; ++size;
// TODO add by chq! &&name!=null; // TODO add by chq! &&name!=null;
if (named && name != null) { if (named && name != null)
{
bv.putShort(cw.newUTF8(name)); bv.putShort(cw.newUTF8(name));
} }
bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value)); bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
} }
@Override @Override
public AnnotationVisitor visitAnnotation(final String name, final String desc) { public AnnotationVisitor visitAnnotation(final String name,
final String desc)
{
++size; ++size;
if (named) { if (named)
{
bv.putShort(cw.newUTF8(name)); bv.putShort(cw.newUTF8(name));
} }
// write tag and type, and reserve space for values count // write tag and type, and reserve space for values count
@@ -193,9 +258,11 @@ final class AnnotationWriter extends AnnotationVisitor {
} }
@Override @Override
public AnnotationVisitor visitArray(final String name) { public AnnotationVisitor visitArray(final String name)
{
++size; ++size;
if (named) { if (named)
{
bv.putShort(cw.newUTF8(name)); bv.putShort(cw.newUTF8(name));
} }
// write tag, and reserve space for array size // write tag, and reserve space for array size
@@ -204,8 +271,10 @@ final class AnnotationWriter extends AnnotationVisitor {
} }
@Override @Override
public void visitEnd() { public void visitEnd()
if (parent != null) { {
if (parent != null)
{
byte[] data = parent.data; byte[] data = parent.data;
data[offset] = (byte) (size >>> 8); data[offset] = (byte) (size >>> 8);
data[offset + 1] = (byte) size; data[offset + 1] = (byte) size;
@@ -221,10 +290,12 @@ final class AnnotationWriter extends AnnotationVisitor {
* *
* @return the size of this annotation writer list. * @return the size of this annotation writer list.
*/ */
int getSize() { int getSize()
{
int size = 0; int size = 0;
AnnotationWriter aw = this; AnnotationWriter aw = this;
while (aw != null) { while (aw != null)
{
size += aw.bv.length; size += aw.bv.length;
aw = aw.next; aw = aw.next;
} }
@@ -232,16 +303,20 @@ final class AnnotationWriter extends AnnotationVisitor {
} }
/** /**
* Puts the annotations of this annotation writer list into the given byte vector. * Puts the annotations of this annotation writer list into the given byte
* vector.
* *
* @param out where the annotations must be put. * @param out
* where the annotations must be put.
*/ */
void put(final ByteVector out) { void put(final ByteVector out)
{
int n = 0; int n = 0;
int size = 2; int size = 2;
AnnotationWriter aw = this; AnnotationWriter aw = this;
AnnotationWriter last = null; AnnotationWriter last = null;
while (aw != null) { while (aw != null)
{
++n; ++n;
size += aw.bv.length; size += aw.bv.length;
aw.visitEnd(); // in case user forgot to call visitEnd aw.visitEnd(); // in case user forgot to call visitEnd
@@ -252,7 +327,8 @@ final class AnnotationWriter extends AnnotationVisitor {
out.putInt(size); out.putInt(size);
out.putShort(n); out.putShort(n);
aw = last; aw = last;
while (aw != null) { while (aw != null)
{
out.putByteArray(aw.bv.data, 0, aw.bv.length); out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev; aw = aw.prev;
} }
@@ -261,21 +337,29 @@ final class AnnotationWriter extends AnnotationVisitor {
/** /**
* Puts the given annotation lists into the given byte vector. * Puts the given annotation lists into the given byte vector.
* *
* @param panns an array of annotation writer lists. * @param panns
* @param off index of the first annotation to be written. * an array of annotation writer lists.
* @param out where the annotations must be put. * @param off
* index of the first annotation to be written.
* @param out
* where the annotations must be put.
*/ */
static void put(final AnnotationWriter[] panns, final int off, final ByteVector out) { static void put(final AnnotationWriter[] panns, final int off,
final ByteVector out)
{
int size = 1 + 2 * (panns.length - off); int size = 1 + 2 * (panns.length - off);
for (int i = off; i < panns.length; ++i) { for (int i = off; i < panns.length; ++i)
{
size += panns[i] == null ? 0 : panns[i].getSize(); size += panns[i] == null ? 0 : panns[i].getSize();
} }
out.putInt(size).putByte(panns.length - off); out.putInt(size).putByte(panns.length - off);
for (int i = off; i < panns.length; ++i) { for (int i = off; i < panns.length; ++i)
{
AnnotationWriter aw = panns[i]; AnnotationWriter aw = panns[i];
AnnotationWriter last = null; AnnotationWriter last = null;
int n = 0; int n = 0;
while (aw != null) { while (aw != null)
{
++n; ++n;
aw.visitEnd(); // in case user forgot to call visitEnd aw.visitEnd(); // in case user forgot to call visitEnd
aw.prev = last; aw.prev = last;
@@ -284,7 +368,8 @@ final class AnnotationWriter extends AnnotationVisitor {
} }
out.putShort(n); out.putShort(n);
aw = last; aw = last;
while (aw != null) { while (aw != null)
{
out.putByteArray(aw.bv.data, 0, aw.bv.length); out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev; aw = aw.prev;
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -47,15 +55,16 @@ public class Attribute {
/** /**
* Constructs a new empty attribute. * Constructs a new empty attribute.
* *
* @param type the type of the attribute. * @param type
* the type of the attribute.
*/ */
protected Attribute(final String type) { protected Attribute(final String type) {
this.type = type; this.type = type;
} }
/** /**
* Returns <tt>true</tt> if this type of attribute is unknown. The default implementation of * Returns <tt>true</tt> if this type of attribute is unknown. The default
* this method always returns <tt>true</tt>. * implementation of this method always returns <tt>true</tt>.
* *
* @return <tt>true</tt> if this type of attribute is unknown. * @return <tt>true</tt> if this type of attribute is unknown.
*/ */
@@ -75,36 +84,47 @@ public class Attribute {
/** /**
* Returns the labels corresponding to this attribute. * Returns the labels corresponding to this attribute.
* *
* @return the labels corresponding to this attribute, or <tt>null</tt> if this attribute is not * @return the labels corresponding to this attribute, or <tt>null</tt> if
* a code attribute that contains labels. * this attribute is not a code attribute that contains labels.
*/ */
protected Label[] getLabels() { protected Label[] getLabels() {
return null; return null;
} }
/** /**
* Reads a {@link #type type} attribute. This method must return a <i>new</i> {@link Attribute} * Reads a {@link #type type} attribute. This method must return a
* object, of type {@link #type type}, corresponding to the <tt>len</tt> bytes starting at the * <i>new</i> {@link Attribute} object, of type {@link #type type},
* given offset, in the given class reader. * corresponding to the <tt>len</tt> bytes starting at the given offset, in
* the given class reader.
* *
* @param cr the class that contains the attribute to be read. * @param cr
* @param off index of the first byte of the attribute's content in {@link ClassReader#b cr.b}. * the class that contains the attribute to be read.
* The 6 attribute header bytes, containing the type and the length of the attribute, are * @param off
* not taken into account here. * index of the first byte of the attribute's content in
* @param len the length of the attribute's content. * {@link ClassReader#b cr.b}. The 6 attribute header bytes,
* @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8}, * containing the type and the length of the attribute, are not
* {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst * taken into account here.
* readConst}. * @param len
* @param codeOff index of the first byte of code's attribute content in {@link ClassReader#b * the length of the attribute's content.
* cr.b}, or -1 if the attribute to be read is not a code attribute. The 6 attribute * @param buf
* header bytes, containing the type and the length of the attribute, are not taken into * buffer to be used to call {@link ClassReader#readUTF8
* account here. * readUTF8}, {@link ClassReader#readClass(int,char[]) readClass}
* @param labels the labels of the method's code, or <tt>null</tt> if the attribute to be read * or {@link ClassReader#readConst readConst}.
* is not a code attribute. * @param codeOff
* @return a <i>new</i> {@link Attribute} object corresponding to the given bytes. * index of the first byte of code's attribute content in
* {@link ClassReader#b cr.b}, or -1 if the attribute to be read
* is not a code attribute. The 6 attribute header bytes,
* containing the type and the length of the attribute, are not
* taken into account here.
* @param labels
* the labels of the method's code, or <tt>null</tt> if the
* attribute to be read is not a code attribute.
* @return a <i>new</i> {@link Attribute} object corresponding to the given
* bytes.
*/ */
protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, protected Attribute read(final ClassReader cr, final int off,
final int codeOff, final Label[] labels) { final int len, final char[] buf, final int codeOff,
final Label[] labels) {
Attribute attr = new Attribute(type); Attribute attr = new Attribute(type);
attr.value = new byte[len]; attr.value = new byte[len];
System.arraycopy(cr.b, off, attr.value, 0, len); System.arraycopy(cr.b, off, attr.value, 0, len);
@@ -114,20 +134,30 @@ public class Attribute {
/** /**
* Returns the byte array form of this attribute. * Returns the byte array form of this attribute.
* *
* @param cw the class to which this attribute must be added. This parameter can be used to add * @param cw
* to the constant pool of this class the items that corresponds to this attribute. * the class to which this attribute must be added. This
* @param code the bytecode of the method corresponding to this code attribute, or <tt>null</tt> * parameter can be used to add to the constant pool of this
* if this attribute is not a code attributes. * class the items that corresponds to this attribute.
* @param len the length of the bytecode of the method corresponding to this code attribute, or * @param code
* <tt>null</tt> if this attribute is not a code attribute. * the bytecode of the method corresponding to this code
* @param maxStack the maximum stack size of the method corresponding to this code attribute, or * attribute, or <tt>null</tt> if this attribute is not a code
* -1 if this attribute is not a code attribute. * attributes.
* @param maxLocals the maximum number of local variables of the method corresponding to this * @param len
* code attribute, or -1 if this attribute is not a code attribute. * the length of the bytecode of the method corresponding to this
* code attribute, or <tt>null</tt> if this attribute is not a
* code attribute.
* @param maxStack
* the maximum stack size of the method corresponding to this
* code attribute, or -1 if this attribute is not a code
* attribute.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to this code attribute, or -1 if this attribute
* is not a code attribute.
* @return the byte array form of this attribute. * @return the byte array form of this attribute.
*/ */
protected ByteVector write(final ClassWriter cw, final byte[] code, final int len, protected ByteVector write(final ClassWriter cw, final byte[] code,
final int maxStack, final int maxLocals) { final int len, final int maxStack, final int maxLocals) {
ByteVector v = new ByteVector(); ByteVector v = new ByteVector();
v.data = value; v.data = value;
v.length = value.length; v.length = value.length;
@@ -152,21 +182,30 @@ public class Attribute {
/** /**
* Returns the size of all the attributes in this attribute list. * Returns the size of all the attributes in this attribute list.
* *
* @param cw the class writer to be used to convert the attributes into byte arrays, with the * @param cw
* {@link #write write} method. * the class writer to be used to convert the attributes into
* @param code the bytecode of the method corresponding to these code attributes, or * byte arrays, with the {@link #write write} method.
* <tt>null</tt> if these attributes are not code attributes. * @param code
* @param len the length of the bytecode of the method corresponding to these code attributes, * the bytecode of the method corresponding to these code
* or <tt>null</tt> if these attributes are not code attributes. * attributes, or <tt>null</tt> if these attributes are not code
* @param maxStack the maximum stack size of the method corresponding to these code attributes, * attributes.
* or -1 if these attributes are not code attributes. * @param len
* @param maxLocals the maximum number of local variables of the method corresponding to these * the length of the bytecode of the method corresponding to
* code attributes, or -1 if these attributes are not code attributes. * these code attributes, or <tt>null</tt> if these attributes
* @return the size of all the attributes in this attribute list. This size includes the size of * are not code attributes.
* the attribute headers. * @param maxStack
* the maximum stack size of the method corresponding to these
* code attributes, or -1 if these attributes are not code
* attributes.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @return the size of all the attributes in this attribute list. This size
* includes the size of the attribute headers.
*/ */
final int getSize(final ClassWriter cw, final byte[] code, final int len, final int maxStack, final int getSize(final ClassWriter cw, final byte[] code, final int len,
final int maxLocals) { final int maxStack, final int maxLocals) {
Attribute attr = this; Attribute attr = this;
int size = 0; int size = 0;
while (attr != null) { while (attr != null) {
@@ -178,22 +217,33 @@ public class Attribute {
} }
/** /**
* Writes all the attributes of this attribute list in the given byte vector. * Writes all the attributes of this attribute list in the given byte
* vector.
* *
* @param cw the class writer to be used to convert the attributes into byte arrays, with the * @param cw
* {@link #write write} method. * the class writer to be used to convert the attributes into
* @param code the bytecode of the method corresponding to these code attributes, or * byte arrays, with the {@link #write write} method.
* <tt>null</tt> if these attributes are not code attributes. * @param code
* @param len the length of the bytecode of the method corresponding to these code attributes, * the bytecode of the method corresponding to these code
* or <tt>null</tt> if these attributes are not code attributes. * attributes, or <tt>null</tt> if these attributes are not code
* @param maxStack the maximum stack size of the method corresponding to these code attributes, * attributes.
* or -1 if these attributes are not code attributes. * @param len
* @param maxLocals the maximum number of local variables of the method corresponding to these * the length of the bytecode of the method corresponding to
* code attributes, or -1 if these attributes are not code attributes. * these code attributes, or <tt>null</tt> if these attributes
* @param out where the attributes must be written. * are not code attributes.
* @param maxStack
* the maximum stack size of the method corresponding to these
* code attributes, or -1 if these attributes are not code
* attributes.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @param out
* where the attributes must be written.
*/ */
final void put(final ClassWriter cw, final byte[] code, final int len, final int maxStack, final void put(final ClassWriter cw, final byte[] code, final int len,
final int maxLocals, final ByteVector out) { final int maxStack, final int maxLocals, final ByteVector out) {
Attribute attr = this; Attribute attr = this;
while (attr != null) { while (attr != null) {
ByteVector b = attr.write(cw, code, len, maxStack, maxLocals); ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);

View File

@@ -1,29 +1,37 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
/** /**
* A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream * A dynamically extensible vector of bytes. This class is roughly equivalent to
* on top of a ByteArrayOutputStream, but is more efficient. * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -40,25 +48,30 @@ public class ByteVector {
int length; int length;
/** /**
* Constructs a new {@link ByteVector ByteVector} with a default initial size. * Constructs a new {@link ByteVector ByteVector} with a default initial
* size.
*/ */
public ByteVector() { public ByteVector() {
data = new byte[64]; data = new byte[64];
} }
/** /**
* Constructs a new {@link ByteVector ByteVector} with the given initial size. * Constructs a new {@link ByteVector ByteVector} with the given initial
* size.
* *
* @param initialSize the initial size of the byte vector to be constructed. * @param initialSize
* the initial size of the byte vector to be constructed.
*/ */
public ByteVector(final int initialSize) { public ByteVector(final int initialSize) {
data = new byte[initialSize]; data = new byte[initialSize];
} }
/** /**
* Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary. * Puts a byte into this byte vector. The byte vector is automatically
* enlarged if necessary.
* *
* @param b a byte. * @param b
* a byte.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putByte(final int b) { public ByteVector putByte(final int b) {
@@ -72,10 +85,13 @@ public class ByteVector {
} }
/** /**
* Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary. * Puts two bytes into this byte vector. The byte vector is automatically
* enlarged if necessary.
* *
* @param b1 a byte. * @param b1
* @param b2 another byte. * a byte.
* @param b2
* another byte.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector put11(final int b1, final int b2) { ByteVector put11(final int b1, final int b2) {
@@ -91,9 +107,11 @@ public class ByteVector {
} }
/** /**
* Puts a short into this byte vector. The byte vector is automatically enlarged if necessary. * Puts a short into this byte vector. The byte vector is automatically
* enlarged if necessary.
* *
* @param s a short. * @param s
* a short.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putShort(final int s) { public ByteVector putShort(final int s) {
@@ -109,11 +127,13 @@ public class ByteVector {
} }
/** /**
* Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if * Puts a byte and a short into this byte vector. The byte vector is
* necessary. * automatically enlarged if necessary.
* *
* @param b a byte. * @param b
* @param s a short. * a byte.
* @param s
* a short.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector put12(final int b, final int s) { ByteVector put12(final int b, final int s) {
@@ -130,9 +150,11 @@ public class ByteVector {
} }
/** /**
* Puts an int into this byte vector. The byte vector is automatically enlarged if necessary. * Puts an int into this byte vector. The byte vector is automatically
* enlarged if necessary.
* *
* @param i an int. * @param i
* an int.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putInt(final int i) { public ByteVector putInt(final int i) {
@@ -150,9 +172,11 @@ public class ByteVector {
} }
/** /**
* Puts a long into this byte vector. The byte vector is automatically enlarged if necessary. * Puts a long into this byte vector. The byte vector is automatically
* enlarged if necessary.
* *
* @param l a long. * @param l
* a long.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putLong(final long l) { public ByteVector putLong(final long l) {
@@ -176,10 +200,11 @@ public class ByteVector {
} }
/** /**
* Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if * Puts an UTF8 string into this byte vector. The byte vector is
* necessary. * automatically enlarged if necessary.
* *
* @param s a String whose UTF8 encoded length must be less than 65536. * @param s
* a String whose UTF8 encoded length must be less than 65536.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putUTF8(final String s) { public ByteVector putUTF8(final String s) {
@@ -247,13 +272,16 @@ public class ByteVector {
} }
/** /**
* Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if * Puts an array of bytes into this byte vector. The byte vector is
* necessary. * automatically enlarged if necessary.
* *
* @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt> null bytes into this * @param b
* byte vector. * an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
* @param off index of the fist byte of b that must be copied. * null bytes into this byte vector.
* @param len number of bytes of b that must be copied. * @param off
* index of the fist byte of b that must be copied.
* @param len
* number of bytes of b that must be copied.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putByteArray(final byte[] b, final int off, final int len) { public ByteVector putByteArray(final byte[] b, final int off, final int len) {
@@ -270,7 +298,9 @@ public class ByteVector {
/** /**
* Enlarge this byte vector so that it can receive n more bytes. * Enlarge this byte vector so that it can receive n more bytes.
* *
* @param size number of additional bytes that this byte vector should be able to receive. * @param size
* number of additional bytes that this byte vector should be
* able to receive.
*/ */
private void enlarge(final int size) { private void enlarge(final int size) {
int length1 = 2 * data.length; int length1 = 2 * data.length;

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +1,38 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
/** /**
* A visitor to visit a Java class. The methods of this class must be called in the following order: * A visitor to visit a Java class. The methods of this class must be called in
* <tt>visit</tt> [ <tt>visitSource</tt> ] [ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> | * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
* <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> | <tt>visitField</tt> | * <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> | <tt>visitField</tt> |
* <tt>visitMethod</tt> )* <tt>visitEnd</tt>. * <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
* *
@@ -32,21 +41,23 @@ package org.objectweb.asm;
public abstract class ClassVisitor { public abstract class ClassVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field must be one of * The ASM API version implemented by this visitor. The value of this field
* {@link Opcodes#ASM4}. * must be one of {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* The class visitor to which this visitor must delegate method calls. May be null. * The class visitor to which this visitor must delegate method calls. May
* be null.
*/ */
protected ClassVisitor cv; protected ClassVisitor cv;
/** /**
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
*/ */
public ClassVisitor(final int api) { public ClassVisitor(final int api) {
this(api, null); this(api, null);
@@ -55,9 +66,12 @@ public abstract class ClassVisitor {
/** /**
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param cv the class visitor to which this visitor must delegate method calls. May be null. * of {@link Opcodes#ASM4}.
* @param cv
* the class visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public ClassVisitor(final int api, final ClassVisitor cv) { public ClassVisitor(final int api, final ClassVisitor cv) {
if (api != Opcodes.ASM4) { if (api != Opcodes.ASM4) {
@@ -70,21 +84,30 @@ public abstract class ClassVisitor {
/** /**
* Visits the header of the class. * Visits the header of the class.
* *
* @param version the class version. * @param version
* @param access the class's access flags (see {@link Opcodes}). This parameter also indicates * the class version.
* if the class is deprecated. * @param access
* @param name the internal name of the class (see {@link Type#getInternalName() * the class's access flags (see {@link Opcodes}). This parameter
* getInternalName}). * also indicates if the class is deprecated.
* @param signature the signature of this class. May be <tt>null</tt> if the class is not a * @param name
* generic one, and does not extend or implement generic classes or interfaces. * the internal name of the class (see
* @param superName the internal of name of the super class (see {@link Type#getInternalName() * {@link Type#getInternalName() getInternalName}).
* getInternalName}). For interfaces, the super class is {@link Object}. May be * @param signature
* the signature of this class. May be <tt>null</tt> if the class
* is not a generic one, and does not extend or implement generic
* classes or interfaces.
* @param superName
* the internal of name of the super class (see
* {@link Type#getInternalName() getInternalName}). For
* interfaces, the super class is {@link Object}. May be
* <tt>null</tt>, but only for the {@link Object} class. * <tt>null</tt>, but only for the {@link Object} class.
* @param interfaces the internal names of the class's interfaces (see * @param interfaces
* {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>. * the internal names of the class's interfaces (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public void visit(int version, int access, String name, String signature, String superName, public void visit(int version, int access, String name, String signature,
String[] interfaces) { String superName, String[] interfaces) {
if (cv != null) { if (cv != null) {
cv.visit(version, access, name, signature, superName, interfaces); cv.visit(version, access, name, signature, superName, interfaces);
} }
@@ -93,10 +116,13 @@ public abstract class ClassVisitor {
/** /**
* Visits the source of the class. * Visits the source of the class.
* *
* @param source the name of the source file from which the class was compiled. May be * @param source
* the name of the source file from which the class was compiled.
* May be <tt>null</tt>.
* @param debug
* additional debug information to compute the correspondance
* between source and compiled elements of the class. May be
* <tt>null</tt>. * <tt>null</tt>.
* @param debug additional debug information to compute the correspondance between source and
* compiled elements of the class. May be <tt>null</tt>.
*/ */
public void visitSource(String source, String debug) { public void visitSource(String source, String debug) {
if (cv != null) { if (cv != null) {
@@ -105,14 +131,19 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits the enclosing class of the class. This method must be called only if the class has an * Visits the enclosing class of the class. This method must be called only
* enclosing class. * if the class has an enclosing class.
* *
* @param owner internal name of the enclosing class of the class. * @param owner
* @param name the name of the method that contains the class, or <tt>null</tt> if the class is * internal name of the enclosing class of the class.
* not enclosed in a method of its enclosing class. * @param name
* @param desc the descriptor of the method that contains the class, or <tt>null</tt> if the * the name of the method that contains the class, or
* class is not enclosed in a method of its enclosing class. * <tt>null</tt> if the class is not enclosed in a method of its
* enclosing class.
* @param desc
* the descriptor of the method that contains the class, or
* <tt>null</tt> if the class is not enclosed in a method of its
* enclosing class.
*/ */
public void visitOuterClass(String owner, String name, String desc) { public void visitOuterClass(String owner, String name, String desc) {
if (cv != null) { if (cv != null) {
@@ -123,10 +154,12 @@ public abstract class ClassVisitor {
/** /**
* Visits an annotation of the class. * Visits an annotation of the class.
* *
* @param desc the class descriptor of the annotation class. * @param desc
* @param visible <tt>true</tt> if the annotation is visible at runtime. * the class descriptor of the annotation class.
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not * @param visible
* interested in visiting this annotation. * <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (cv != null) { if (cv != null) {
@@ -138,7 +171,8 @@ public abstract class ClassVisitor {
/** /**
* Visits a non standard attribute of the class. * Visits a non standard attribute of the class.
* *
* @param attr an attribute. * @param attr
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (cv != null) { if (cv != null) {
@@ -147,20 +181,25 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits information about an inner class. This inner class is not necessarily a member of the * Visits information about an inner class. This inner class is not
* class being visited. * necessarily a member of the class being visited.
* *
* @param name the internal name of an inner class (see {@link Type#getInternalName() * @param name
* getInternalName}). * the internal name of an inner class (see
* @param outerName the internal name of the class to which the inner class belongs (see * {@link Type#getInternalName() getInternalName}).
* {@link Type#getInternalName() getInternalName}). May be <tt>null</tt> for not member * @param outerName
* classes. * the internal name of the class to which the inner class
* @param innerName the (simple) name of the inner class inside its enclosing class. May be * belongs (see {@link Type#getInternalName() getInternalName}).
* <tt>null</tt> for anonymous inner classes. * May be <tt>null</tt> for not member classes.
* @param access the access flags of the inner class as originally declared in the enclosing * @param innerName
* class. * the (simple) name of the inner class inside its enclosing
* class. May be <tt>null</tt> for anonymous inner classes.
* @param access
* the access flags of the inner class as originally declared in
* the enclosing class.
*/ */
public void visitInnerClass(String name, String outerName, String innerName, int access) { public void visitInnerClass(String name, String outerName,
String innerName, int access) {
if (cv != null) { if (cv != null) {
cv.visitInnerClass(name, outerName, innerName, access); cv.visitInnerClass(name, outerName, innerName, access);
} }
@@ -169,23 +208,32 @@ public abstract class ClassVisitor {
/** /**
* Visits a field of the class. * Visits a field of the class.
* *
* @param access the field's access flags (see {@link Opcodes}). This parameter also indicates * @param access
* if the field is synthetic and/or deprecated. * the field's access flags (see {@link Opcodes}). This parameter
* @param name the field's name. * also indicates if the field is synthetic and/or deprecated.
* @param desc the field's descriptor (see {@link Type Type}). * @param name
* @param signature the field's signature. May be <tt>null</tt> if the field's type does not use * the field's name.
* generic types. * @param desc
* @param value the field's initial value. This parameter, which may be <tt>null</tt> if the * the field's descriptor (see {@link Type Type}).
* field does not have an initial value, must be an {@link Integer}, a {@link Float}, a * @param signature
* {@link Long}, a {@link Double} or a {@link String} (for <tt>int</tt>, <tt>float</tt>, * the field's signature. May be <tt>null</tt> if the field's
* <tt>long</tt> or <tt>String</tt> fields respectively). <i>This parameter is only used * type does not use generic types.
* for static fields</i>. Its value is ignored for non static fields, which must be * @param value
* initialized through bytecode instructions in constructors or methods. * the field's initial value. This parameter, which may be
* @return a visitor to visit field annotations and attributes, or <tt>null</tt> if this class * <tt>null</tt> if the field does not have an initial value,
* visitor is not interested in visiting these annotations and attributes. * must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String} (for <tt>int</tt>,
* <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
* respectively). <i>This parameter is only used for static
* fields</i>. Its value is ignored for non static fields, which
* must be initialized through bytecode instructions in
* constructors or methods.
* @return a visitor to visit field annotations and attributes, or
* <tt>null</tt> if this class visitor is not interested in visiting
* these annotations and attributes.
*/ */
public FieldVisitor visitField(int access, String name, String desc, String signature, public FieldVisitor visitField(int access, String name, String desc,
Object value) { String signature, Object value) {
if (cv != null) { if (cv != null) {
return cv.visitField(access, name, desc, signature, value); return cv.visitField(access, name, desc, signature, value);
} }
@@ -193,23 +241,32 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor} * Visits a method of the class. This method <i>must</i> return a new
* instance (or <tt>null</tt>) each time it is called, i.e., it should not return a previously * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is called,
* returned visitor. * i.e., it should not return a previously returned visitor.
* *
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates * @param access
* if the method is synthetic and/or deprecated. * the method's access flags (see {@link Opcodes}). This
* @param name the method's name. * parameter also indicates if the method is synthetic and/or
* @param desc the method's descriptor (see {@link Type Type}). * deprecated.
* @param signature the method's signature. May be <tt>null</tt> if the method parameters, * @param name
* return type and exceptions do not use generic types. * the method's name.
* @param exceptions the internal names of the method's exception classes (see * @param desc
* {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>. * the method's descriptor (see {@link Type Type}).
* @return an object to visit the byte code of the method, or <tt>null</tt> if this class * @param signature
* visitor is not interested in visiting the code of this method. * the method's signature. May be <tt>null</tt> if the method
* parameters, return type and exceptions do not use generic
* types.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
* @return an object to visit the byte code of the method, or <tt>null</tt>
* if this class visitor is not interested in visiting the code of
* this method.
*/ */
public MethodVisitor visitMethod(int access, String name, String desc, String signature, public MethodVisitor visitMethod(int access, String name, String desc,
String[] exceptions) { String signature, String[] exceptions) {
if (cv != null) { if (cv != null) {
return cv.visitMethod(access, name, desc, signature, exceptions); return cv.visitMethod(access, name, desc, signature, exceptions);
} }
@@ -217,8 +274,9 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits the end of the class. This method, which is the last one to be called, is used to * Visits the end of the class. This method, which is the last one to be
* inform the visitor that all the fields and methods of the class have been visited. * called, is used to inform the visitor that all the fields and methods of
* the class have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (cv != null) { if (cv != null) {

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -80,8 +88,8 @@ class Context {
int localCount; int localCount;
/** /**
* The number locals in the latest stack map frame that has been parsed, minus the number of * The number locals in the latest stack map frame that has been parsed,
* locals in the previous frame. * minus the number of locals in the previous frame.
*/ */
int localDiff; int localDiff;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -34,20 +42,23 @@ class Edge {
static final int NORMAL = 0; static final int NORMAL = 0;
/** /**
* Denotes a control flow graph edge corresponding to an exception handler. More precisely any * Denotes a control flow graph edge corresponding to an exception handler.
* {@link Edge} whose {@link #info} is strictly positive corresponds to an exception handler. * More precisely any {@link Edge} whose {@link #info} is strictly positive
* The actual value of {@link #info} is the index, in the {@link ClassWriter} type table, of the * corresponds to an exception handler. The actual value of {@link #info} is
* exception that is catched. * the index, in the {@link ClassWriter} type table, of the exception that
* is catched.
*/ */
static final int EXCEPTION = 0x7FFFFFFF; static final int EXCEPTION = 0x7FFFFFFF;
/** /**
* Information about this control flow graph edge. If {@link ClassWriter#COMPUTE_MAXS} is used * Information about this control flow graph edge. If
* this field is the (relative) stack size in the basic block from which this edge originates. * {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative)
* This size is equal to the stack size at the "jump" instruction to which this edge * stack size in the basic block from which this edge originates. This size
* corresponds, relatively to the stack size at the beginning of the originating basic block. If * is equal to the stack size at the "jump" instruction to which this edge
* {@link ClassWriter#COMPUTE_FRAMES} is used, this field is the kind of this control flow graph * corresponds, relatively to the stack size at the beginning of the
* edge (i.e. NORMAL or EXCEPTION). * originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used,
* this field is the kind of this control flow graph edge (i.e. NORMAL or
* EXCEPTION).
*/ */
int info; int info;
@@ -57,8 +68,8 @@ class Edge {
Label successor; Label successor;
/** /**
* The next edge in the list of successors of the originating basic block. See * The next edge in the list of successors of the originating basic block.
* {@link Label#successors successors}. * See {@link Label#successors successors}.
*/ */
Edge next; Edge next;
} }

View File

@@ -1,50 +1,61 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
/** /**
* A visitor to visit a Java field. The methods of this class must be called in the following order: * A visitor to visit a Java field. The methods of this class must be called in
* ( <tt>visitAnnotation</tt> | <tt>visitAttribute</tt> )* <tt>visitEnd</tt>. * the following order: ( <tt>visitAnnotation</tt> | <tt>visitAttribute</tt> )*
* <tt>visitEnd</tt>.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public abstract class FieldVisitor { public abstract class FieldVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field must be one of * The ASM API version implemented by this visitor. The value of this field
* {@link Opcodes#ASM4}. * must be one of {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* The field visitor to which this visitor must delegate method calls. May be null. * The field visitor to which this visitor must delegate method calls. May
* be null.
*/ */
protected FieldVisitor fv; protected FieldVisitor fv;
/** /**
* Constructs a new {@link FieldVisitor}. * Constructs a new {@link FieldVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
*/ */
public FieldVisitor(final int api) { public FieldVisitor(final int api) {
this(api, null); this(api, null);
@@ -53,9 +64,12 @@ public abstract class FieldVisitor {
/** /**
* Constructs a new {@link FieldVisitor}. * Constructs a new {@link FieldVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param fv the field visitor to which this visitor must delegate method calls. May be null. * of {@link Opcodes#ASM4}.
* @param fv
* the field visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public FieldVisitor(final int api, final FieldVisitor fv) { public FieldVisitor(final int api, final FieldVisitor fv) {
if (api != Opcodes.ASM4) { if (api != Opcodes.ASM4) {
@@ -68,10 +82,12 @@ public abstract class FieldVisitor {
/** /**
* Visits an annotation of the field. * Visits an annotation of the field.
* *
* @param desc the class descriptor of the annotation class. * @param desc
* @param visible <tt>true</tt> if the annotation is visible at runtime. * the class descriptor of the annotation class.
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not * @param visible
* interested in visiting this annotation. * <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (fv != null) { if (fv != null) {
@@ -83,7 +99,8 @@ public abstract class FieldVisitor {
/** /**
* Visits a non standard attribute of the field. * Visits a non standard attribute of the field.
* *
* @param attr an attribute. * @param attr
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (fv != null) { if (fv != null) {
@@ -92,8 +109,9 @@ public abstract class FieldVisitor {
} }
/** /**
* Visits the end of the field. This method, which is the last one to be called, is used to * Visits the end of the field. This method, which is the last one to be
* inform the visitor that all the annotations and attributes of the field have been visited. * called, is used to inform the visitor that all the annotations and
* attributes of the field have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (fv != null) { if (fv != null) {

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -39,22 +47,26 @@ final class FieldWriter extends FieldVisitor {
private final int access; private final int access;
/** /**
* The index of the constant pool item that contains the name of this method. * The index of the constant pool item that contains the name of this
* method.
*/ */
private final int name; private final int name;
/** /**
* The index of the constant pool item that contains the descriptor of this field. * The index of the constant pool item that contains the descriptor of this
* field.
*/ */
private final int desc; private final int desc;
/** /**
* The index of the constant pool item that contains the signature of this field. * The index of the constant pool item that contains the signature of this
* field.
*/ */
private int signature; private int signature;
/** /**
* The index of the constant pool item that contains the constant value of this field. * The index of the constant pool item that contains the constant value of
* this field.
*/ */
private int value; private int value;
@@ -80,15 +92,21 @@ final class FieldWriter extends FieldVisitor {
/** /**
* Constructs a new {@link FieldWriter}. * Constructs a new {@link FieldWriter}.
* *
* @param cw the class writer to which this field must be added. * @param cw
* @param access the field's access flags (see {@link Opcodes}). * the class writer to which this field must be added.
* @param name the field's name. * @param access
* @param desc the field's descriptor (see {@link Type}). * the field's access flags (see {@link Opcodes}).
* @param signature the field's signature. May be <tt>null</tt>. * @param name
* @param value the field's constant value. May be <tt>null</tt>. * the field's name.
* @param desc
* the field's descriptor (see {@link Type}).
* @param signature
* the field's signature. May be <tt>null</tt>.
* @param value
* the field's constant value. May be <tt>null</tt>.
*/ */
FieldWriter(final ClassWriter cw, final int access, final String name, final String desc, FieldWriter(final ClassWriter cw, final int access, final String name,
final String signature, final Object value) { final String desc, final String signature, final Object value) {
super(Opcodes.ASM4); super(Opcodes.ASM4);
if (cw.firstField == null) { if (cw.firstField == null) {
cw.firstField = this; cw.firstField = this;
@@ -113,7 +131,8 @@ final class FieldWriter extends FieldVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
if (!ClassReader.ANNOTATIONS) { if (!ClassReader.ANNOTATIONS) {
return null; return null;
} }
@@ -138,7 +157,8 @@ final class FieldWriter extends FieldVisitor {
} }
@Override @Override
public void visitEnd() {} public void visitEnd() {
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Utility methods // Utility methods
@@ -187,7 +207,8 @@ final class FieldWriter extends FieldVisitor {
/** /**
* Puts the content of this field into the given byte vector. * Puts the content of this field into the given byte vector.
* *
* @param out where the content of this field must be put. * @param out
* where the content of this field must be put.
*/ */
void put(final ByteVector out) { void put(final ByteVector out) {
final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -29,51 +37,61 @@ package org.objectweb.asm;
final class Frame { final class Frame {
/* /*
* Frames are computed in a two steps process: during the visit of each instruction, the state * Frames are computed in a two steps process: during the visit of each
* of the frame at the end of current basic block is updated by simulating the action of the * instruction, the state of the frame at the end of current basic block is
* instruction on the previous state of this so called "output frame". In visitMaxs, a fix point * updated by simulating the action of the instruction on the previous state
* algorithm is used to compute the "input frame" of each basic block, i.e. the stack map frame * of this so called "output frame". In visitMaxs, a fix point algorithm is
* at the beginning of the basic block, starting from the input frame of the first basic block * used to compute the "input frame" of each basic block, i.e. the stack map
* (which is computed from the method descriptor), and by using the previously computed output * frame at the beginning of the basic block, starting from the input frame
* frames to compute the input state of the other blocks. * of the first basic block (which is computed from the method descriptor),
* and by using the previously computed output frames to compute the input
* state of the other blocks.
* *
* All output and input frames are stored as arrays of integers. Reference and array types are * All output and input frames are stored as arrays of integers. Reference
* represented by an index into a type table (which is not the same as the constant pool of the * and array types are represented by an index into a type table (which is
* class, in order to avoid adding unnecessary constants in the pool - not all computed frames * not the same as the constant pool of the class, in order to avoid adding
* will end up being stored in the stack map table). This allows very fast type comparisons. * unnecessary constants in the pool - not all computed frames will end up
* being stored in the stack map table). This allows very fast type
* comparisons.
* *
* Output stack map frames are computed relatively to the input frame of the basic block, which * Output stack map frames are computed relatively to the input frame of the
* is not yet known when output frames are computed. It is therefore necessary to be able to * basic block, which is not yet known when output frames are computed. It
* represent abstract types such as "the type at position x in the input frame locals" or "the * is therefore necessary to be able to represent abstract types such as
* type at position x from the top of the input frame stack" or even "the type at position x in * "the type at position x in the input frame locals" or "the type at
* the input frame, with y more (or less) array dimensions". This explains the rather * position x from the top of the input frame stack" or even "the type at
* complicated type format used in output frames. * position x in the input frame, with y more (or less) array dimensions".
* This explains the rather complicated type format used in output frames.
* *
* This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a signed number of * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a
* array dimensions (from -8 to 7). KIND is either BASE, LOCAL or STACK. BASE is used for types * signed number of array dimensions (from -8 to 7). KIND is either BASE,
* that are not relative to the input frame. LOCAL is used for types that are relative to the * LOCAL or STACK. BASE is used for types that are not relative to the input
* input local variable types. STACK is used for types that are relative to the input stack * frame. LOCAL is used for types that are relative to the input local
* types. VALUE depends on KIND. For LOCAL types, it is an index in the input local variable * variable types. STACK is used for types that are relative to the input
* types. For STACK types, it is a position relatively to the top of input frame stack. For BASE * stack types. VALUE depends on KIND. For LOCAL types, it is an index in
* types, it is either one of the constants defined in FrameVisitor, or for OBJECT and * the input local variable types. For STACK types, it is a position
* relatively to the top of input frame stack. For BASE types, it is either
* one of the constants defined in FrameVisitor, or for OBJECT and
* UNINITIALIZED types, a tag and an index in the type table. * UNINITIALIZED types, a tag and an index in the type table.
* *
* Output frames can contain types of any kind and with a positive or negative dimension (and * Output frames can contain types of any kind and with a positive or
* even unassigned types, represented by 0 - which does not correspond to any valid type value). * negative dimension (and even unassigned types, represented by 0 - which
* Input frames can only contain BASE types of positive or null dimension. In all cases the type * does not correspond to any valid type value). Input frames can only
* table contains only internal type names (array type descriptors are forbidden - dimensions * contain BASE types of positive or null dimension. In all cases the type
* must be represented through the DIM field). * table contains only internal type names (array type descriptors are
* forbidden - dimensions must be represented through the DIM field).
* *
* The LONG and DOUBLE types are always represented by using two slots (LONG + TOP or DOUBLE + * The LONG and DOUBLE types are always represented by using two slots (LONG
* TOP), for local variable types as well as in the operand stack. This is necessary to be able * + TOP or DOUBLE + TOP), for local variable types as well as in the
* to simulate DUPx_y instructions, whose effect would be dependent on the actual type values if * operand stack. This is necessary to be able to simulate DUPx_y
* types were always represented by a single slot in the stack (and this is not possible, since * instructions, whose effect would be dependent on the actual type values
* actual type values are not always known - cf LOCAL and STACK type kinds). * if types were always represented by a single slot in the stack (and this
* is not possible, since actual type values are not always known - cf LOCAL
* and STACK type kinds).
*/ */
/** /**
* Mask to get the dimension of a frame type. This dimension is a signed integer between -8 and * Mask to get the dimension of a frame type. This dimension is a signed
* 7. * integer between -8 and 7.
*/ */
static final int DIM = 0xF0000000; static final int DIM = 0xF0000000;
@@ -97,10 +115,11 @@ final class Frame {
static final int KIND = 0xF000000; static final int KIND = 0xF000000;
/** /**
* Flag used for LOCAL and STACK types. Indicates that if this type happens to be a long or * Flag used for LOCAL and STACK types. Indicates that if this type happens
* double type (during the computations of input frames), then it must be set to TOP because the * to be a long or double type (during the computations of input frames),
* second word of this value has been reused to store other data in the basic block. Hence the * then it must be set to TOP because the second word of this value has been
* first word no longer stores a valid long or double value. * reused to store other data in the basic block. Hence the first word no
* longer stores a valid long or double value.
*/ */
static final int TOP_IF_LONG_OR_DOUBLE = 0x800000; static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
@@ -125,27 +144,28 @@ final class Frame {
static final int BASE = 0x1000000; static final int BASE = 0x1000000;
/** /**
* Base kind of the base reference types. The BASE_VALUE of such types is an index into the type * Base kind of the base reference types. The BASE_VALUE of such types is an
* table. * index into the type table.
*/ */
static final int OBJECT = BASE | 0x700000; static final int OBJECT = BASE | 0x700000;
/** /**
* Base kind of the uninitialized base types. The BASE_VALUE of such types in an index into the * Base kind of the uninitialized base types. The BASE_VALUE of such types
* type table (the Item at that index contains both an instruction offset and an internal class * in an index into the type table (the Item at that index contains both an
* name). * instruction offset and an internal class name).
*/ */
static final int UNINITIALIZED = BASE | 0x800000; static final int UNINITIALIZED = BASE | 0x800000;
/** /**
* Kind of the types that are relative to the local variable types of an input stack map frame. * Kind of the types that are relative to the local variable types of an
* The value of such types is a local variable index. * input stack map frame. The value of such types is a local variable index.
*/ */
private static final int LOCAL = 0x2000000; private static final int LOCAL = 0x2000000;
/** /**
* Kind of the the types that are relative to the stack of an input stack map frame. The value * Kind of the the types that are relative to the stack of an input stack
* of such types is a position relatively to the top of this stack. * map frame. The value of such types is a position relatively to the top of
* this stack.
*/ */
private static final int STACK = 0x3000000; private static final int STACK = 0x3000000;
@@ -205,9 +225,9 @@ final class Frame {
static final int UNINITIALIZED_THIS = BASE | 6; static final int UNINITIALIZED_THIS = BASE | 6;
/** /**
* The stack size variation corresponding to each JVM instruction. This stack variation is equal * The stack size variation corresponding to each JVM instruction. This
* to the size of the values produced by an instruction, minus the size of the values consumed * stack variation is equal to the size of the values produced by an
* by this instruction. * instruction, minus the size of the values consumed by this instruction.
*/ */
static final int[] SIZE; static final int[] SIZE;
@@ -441,7 +461,8 @@ final class Frame {
} }
/** /**
* The label (i.e. basic block) to which these input and output stack map frames correspond. * The label (i.e. basic block) to which these input and output stack map
* frames correspond.
*/ */
Label owner; Label owner;
@@ -466,14 +487,14 @@ final class Frame {
private int[] outputStack; private int[] outputStack;
/** /**
* Relative size of the output stack. The exact semantics of this field depends on the algorithm * Relative size of the output stack. The exact semantics of this field
* that is used. * depends on the algorithm that is used.
* *
* When only the maximum stack size is computed, this field is the size of the output stack * When only the maximum stack size is computed, this field is the size of
* relatively to the top of the input stack. * the output stack relatively to the top of the input stack.
* *
* When the stack map frames are completely computed, this field is the actual number of types * When the stack map frames are completely computed, this field is the
* in {@link #outputStack}. * actual number of types in {@link #outputStack}.
*/ */
private int outputStackTop; private int outputStackTop;
@@ -485,22 +506,25 @@ final class Frame {
private int initializationCount; private int initializationCount;
/** /**
* The types that are initialized in the basic block. A constructor invocation on an * The types that are initialized in the basic block. A constructor
* UNINITIALIZED or UNINITIALIZED_THIS type must replace <i>every occurence</i> of this type in * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
* the local variables and in the operand stack. This cannot be done during the first phase of * <i>every occurence</i> of this type in the local variables and in the
* the algorithm since, during this phase, the local variables and the operand stack are not * operand stack. This cannot be done during the first phase of the
* completely computed. It is therefore necessary to store the types on which constructors are * algorithm since, during this phase, the local variables and the operand
* invoked in the basic block, in order to do this replacement during the second phase of the * stack are not completely computed. It is therefore necessary to store the
* algorithm, where the frames are fully computed. Note that this array can contain types that * types on which constructors are invoked in the basic block, in order to
* are relative to input locals or to the input stack (see below for the description of the * do this replacement during the second phase of the algorithm, where the
* algorithm). * frames are fully computed. Note that this array can contain types that
* are relative to input locals or to the input stack (see below for the
* description of the algorithm).
*/ */
private int[] initializations; private int[] initializations;
/** /**
* Returns the output frame local variable type at the given index. * Returns the output frame local variable type at the given index.
* *
* @param local the index of the local that must be returned. * @param local
* the index of the local that must be returned.
* @return the output frame local variable type at the given index. * @return the output frame local variable type at the given index.
*/ */
private int get(final int local) { private int get(final int local) {
@@ -522,8 +546,10 @@ final class Frame {
/** /**
* Sets the output frame local variable type at the given index. * Sets the output frame local variable type at the given index.
* *
* @param local the index of the local that must be set. * @param local
* @param type the value of the local that must be set. * the index of the local that must be set.
* @param type
* the value of the local that must be set.
*/ */
private void set(final int local, final int type) { private void set(final int local, final int type) {
// creates and/or resizes the output local variables array if necessary // creates and/or resizes the output local variables array if necessary
@@ -543,7 +569,8 @@ final class Frame {
/** /**
* Pushes a new type onto the output frame stack. * Pushes a new type onto the output frame stack.
* *
* @param type the type that must be pushed. * @param type
* the type that must be pushed.
*/ */
private void push(final int type) { private void push(final int type) {
// creates and/or resizes the output stack array if necessary // creates and/or resizes the output stack array if necessary
@@ -568,9 +595,12 @@ final class Frame {
/** /**
* Pushes a new type onto the output frame stack. * Pushes a new type onto the output frame stack.
* *
* @param cw the ClassWriter to which this label belongs. * @param cw
* @param desc the descriptor of the type to be pushed. Can also be a method descriptor (in this * the ClassWriter to which this label belongs.
* case this method pushes its return type onto the output frame stack). * @param desc
* the descriptor of the type to be pushed. Can also be a method
* descriptor (in this case this method pushes its return type
* onto the output frame stack).
*/ */
private void push(final ClassWriter cw, final String desc) { private void push(final ClassWriter cw, final String desc) {
int type = type(cw, desc); int type = type(cw, desc);
@@ -585,8 +615,10 @@ final class Frame {
/** /**
* Returns the int encoding of the given type. * Returns the int encoding of the given type.
* *
* @param cw the ClassWriter to which this label belongs. * @param cw
* @param desc a type descriptor. * the ClassWriter to which this label belongs.
* @param desc
* a type descriptor.
* @return the int encoding of the given type. * @return the int encoding of the given type.
*/ */
private static int type(final ClassWriter cw, final String desc) { private static int type(final ClassWriter cw, final String desc) {
@@ -671,7 +703,8 @@ final class Frame {
/** /**
* Pops the given number of types from the output frame stack. * Pops the given number of types from the output frame stack.
* *
* @param elements the number of types that must be popped. * @param elements
* the number of types that must be popped.
*/ */
private void pop(final int elements) { private void pop(final int elements) {
if (outputStackTop >= elements) { if (outputStackTop >= elements) {
@@ -688,8 +721,10 @@ final class Frame {
/** /**
* Pops a type from the output frame stack. * Pops a type from the output frame stack.
* *
* @param desc the descriptor of the type to be popped. Can also be a method descriptor (in this * @param desc
* case this method pops the types corresponding to the method arguments). * the descriptor of the type to be popped. Can also be a method
* descriptor (in this case this method pops the types
* corresponding to the method arguments).
*/ */
private void pop(final String desc) { private void pop(final String desc) {
char c = desc.charAt(0); char c = desc.charAt(0);
@@ -703,9 +738,11 @@ final class Frame {
} }
/** /**
* Adds a new type to the list of types on which a constructor is invoked in the basic block. * Adds a new type to the list of types on which a constructor is invoked in
* the basic block.
* *
* @param var a type on a which a constructor is invoked. * @param var
* a type on a which a constructor is invoked.
*/ */
private void init(final int var) { private void init(final int var) {
// creates and/or resizes the initializations array if necessary // creates and/or resizes the initializations array if necessary
@@ -723,13 +760,15 @@ final class Frame {
} }
/** /**
* Replaces the given type with the appropriate type if it is one of the types on which a * Replaces the given type with the appropriate type if it is one of the
* constructor is invoked in the basic block. * types on which a constructor is invoked in the basic block.
* *
* @param cw the ClassWriter to which this label belongs. * @param cw
* @param t a type * the ClassWriter to which this label belongs.
* @return t or, if t is one of the types on which a constructor is invoked in the basic block, * @param t
* the type corresponding to this constructor. * a type
* @return t or, if t is one of the types on which a constructor is invoked
* in the basic block, the type corresponding to this constructor.
*/ */
private int init(final ClassWriter cw, final int t) { private int init(final ClassWriter cw, final int t) {
int s; int s;
@@ -758,15 +797,20 @@ final class Frame {
} }
/** /**
* Initializes the input frame of the first basic block from the method descriptor. * Initializes the input frame of the first basic block from the method
* descriptor.
* *
* @param cw the ClassWriter to which this label belongs. * @param cw
* @param access the access flags of the method to which this label belongs. * the ClassWriter to which this label belongs.
* @param args the formal parameter types of this method. * @param access
* @param maxLocals the maximum number of local variables of this method. * the access flags of the method to which this label belongs.
* @param args
* the formal parameter types of this method.
* @param maxLocals
* the maximum number of local variables of this method.
*/ */
void initInputFrame(final ClassWriter cw, final int access, final Type[] args, void initInputFrame(final ClassWriter cw, final int access,
final int maxLocals) { final Type[] args, final int maxLocals) {
inputLocals = new int[maxLocals]; inputLocals = new int[maxLocals];
inputStack = new int[0]; inputStack = new int[0];
int i = 0; int i = 0;
@@ -792,12 +836,17 @@ final class Frame {
/** /**
* Simulates the action of the given instruction on the output stack frame. * Simulates the action of the given instruction on the output stack frame.
* *
* @param opcode the opcode of the instruction. * @param opcode
* @param arg the operand of the instruction, if any. * the opcode of the instruction.
* @param cw the class writer to which this label belongs. * @param arg
* @param item the operand of the instructions, if any. * the operand of the instruction, if any.
* @param cw
* the class writer to which this label belongs.
* @param item
* the operand of the instructions, if any.
*/ */
void execute(final int opcode, final int arg, final ClassWriter cw, final Item item) { void execute(final int opcode, final int arg, final ClassWriter cw,
final Item item) {
int t1, t2, t3, t4; int t1, t2, t3, t4;
switch (opcode) { switch (opcode) {
case Opcodes.NOP: case Opcodes.NOP:
@@ -1126,7 +1175,8 @@ final class Frame {
break; break;
case Opcodes.JSR: case Opcodes.JSR:
case Opcodes.RET: case Opcodes.RET:
throw new RuntimeException("JSR/RET are not supported with computeFrames option"); throw new RuntimeException(
"JSR/RET are not supported with computeFrames option");
case Opcodes.GETSTATIC: case Opcodes.GETSTATIC:
push(cw, item.strVal3); push(cw, item.strVal3);
break; break;
@@ -1148,7 +1198,8 @@ final class Frame {
pop(item.strVal3); pop(item.strVal3);
if (opcode != Opcodes.INVOKESTATIC) { if (opcode != Opcodes.INVOKESTATIC) {
t1 = pop(); t1 = pop();
if (opcode == Opcodes.INVOKESPECIAL && item.strVal2.charAt(0) == '<') { if (opcode == Opcodes.INVOKESPECIAL
&& item.strVal2.charAt(0) == '<') {
init(t1); init(t1);
} }
} }
@@ -1218,16 +1269,19 @@ final class Frame {
} }
/** /**
* Merges the input frame of the given basic block with the input and output frames of this * Merges the input frame of the given basic block with the input and output
* basic block. Returns <tt>true</tt> if the input frame of the given label has been changed by * frames of this basic block. Returns <tt>true</tt> if the input frame of
* this operation. * the given label has been changed by this operation.
* *
* @param cw the ClassWriter to which this label belongs. * @param cw
* @param frame the basic block whose input frame must be updated. * the ClassWriter to which this label belongs.
* @param edge the kind of the {@link Edge} between this label and 'label'. See * @param frame
* {@link Edge#info}. * the basic block whose input frame must be updated.
* @return <tt>true</tt> if the input frame of the given label has been changed by this * @param edge
* operation. * the kind of the {@link Edge} between this label and 'label'.
* See {@link Edge#info}.
* @return <tt>true</tt> if the input frame of the given label has been
* changed by this operation.
*/ */
boolean merge(final ClassWriter cw, final Frame frame, final int edge) { boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
boolean changed = false; boolean changed = false;
@@ -1256,7 +1310,8 @@ final class Frame {
} else { } else {
t = dim + inputStack[nStack - (s & VALUE)]; t = dim + inputStack[nStack - (s & VALUE)];
} }
if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) { if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
&& (t == LONG || t == DOUBLE)) {
t = TOP; t = TOP;
} }
} }
@@ -1308,7 +1363,8 @@ final class Frame {
} else { } else {
t = dim + inputStack[nStack - (s & VALUE)]; t = dim + inputStack[nStack - (s & VALUE)];
} }
if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) { if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
&& (t == LONG || t == DOUBLE)) {
t = TOP; t = TOP;
} }
} }
@@ -1321,16 +1377,23 @@ final class Frame {
} }
/** /**
* Merges the type at the given index in the given type array with the given type. Returns * Merges the type at the given index in the given type array with the given
* <tt>true</tt> if the type array has been modified by this operation. * type. Returns <tt>true</tt> if the type array has been modified by this
* operation.
* *
* @param cw the ClassWriter to which this label belongs. * @param cw
* @param t the type with which the type array element must be merged. * the ClassWriter to which this label belongs.
* @param types an array of types. * @param t
* @param index the index of the type that must be merged in 'types'. * the type with which the type array element must be merged.
* @return <tt>true</tt> if the type array has been modified by this operation. * @param types
* an array of types.
* @param index
* the index of the type that must be merged in 'types'.
* @return <tt>true</tt> if the type array has been modified by this
* operation.
*/ */
private static boolean merge(final ClassWriter cw, int t, final int[] types, final int index) { private static boolean merge(final ClassWriter cw, int t,
final int[] types, final int index) {
int u = types[index]; int u = types[index];
if (u == t) { if (u == t) {
// if the types are equal, merge(u,t)=u, so there is no change // if the types are equal, merge(u,t)=u, so there is no change
@@ -1358,7 +1421,8 @@ final class Frame {
// if t is also a reference type, and if u and t have the // if t is also a reference type, and if u and t have the
// same dimension merge(u,t) = dim(t) | common parent of the // same dimension merge(u,t) = dim(t) | common parent of the
// element types of u and t // element types of u and t
v = (t & DIM) | OBJECT | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); v = (t & DIM) | OBJECT
| cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE);
} else { } else {
// if u and t are array types, but not with the same element // if u and t are array types, but not with the same element
// type, merge(u,t)=java/lang/Object // type, merge(u,t)=java/lang/Object

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -31,8 +39,9 @@ package org.objectweb.asm;
public final class Handle { public final class Handle {
/** /**
* The kind of field or method designated by this Handle. Should be {@link Opcodes#H_GETFIELD}, * The kind of field or method designated by this Handle. Should be
* {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
* {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}. * {@link Opcodes#H_INVOKEINTERFACE}.
@@ -40,7 +49,8 @@ public final class Handle {
final int tag; final int tag;
/** /**
* The internal name of the class that owns the field or method designated by this handle. * The internal name of the class that owns the field or method designated
* by this handle.
*/ */
final String owner; final String owner;
@@ -57,15 +67,23 @@ public final class Handle {
/** /**
* Constructs a new field or method handle. * Constructs a new field or method handle.
* *
* @param tag the kind of field or method designated by this Handle. Must be * @param tag
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, * the kind of field or method designated by this Handle. Must be
* {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
* {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. * {@link Opcodes#H_INVOKEVIRTUAL},
* @param owner the internal name of the class that owns the field or method designated by this * {@link Opcodes#H_INVOKESTATIC},
* {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}.
* @param owner
* the internal name of the class that owns the field or method
* designated by this handle.
* @param name
* the name of the field or method designated by this handle.
* @param desc
* the descriptor of the field or method designated by this
* handle. * handle.
* @param name the name of the field or method designated by this handle.
* @param desc the descriptor of the field or method designated by this handle.
*/ */
public Handle(int tag, String owner, String name, String desc) { public Handle(int tag, String owner, String name, String desc) {
this.tag = tag; this.tag = tag;
@@ -77,21 +95,23 @@ public final class Handle {
/** /**
* Returns the kind of field or method designated by this handle. * Returns the kind of field or method designated by this handle.
* *
* @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
* {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
* {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. * {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}.
*/ */
public int getTag() { public int getTag() {
return tag; return tag;
} }
/** /**
* Returns the internal name of the class that owns the field or method designated by this * Returns the internal name of the class that owns the field or method
* handle. * designated by this handle.
* *
* @return the internal name of the class that owns the field or method designated by this * @return the internal name of the class that owns the field or method
* handle. * designated by this handle.
*/ */
public String getOwner() { public String getOwner() {
return owner; return owner;
@@ -124,7 +144,8 @@ public final class Handle {
return false; return false;
} }
Handle h = (Handle) obj; Handle h = (Handle) obj;
return tag == h.tag && owner.equals(h.owner) && name.equals(h.name) && desc.equals(h.desc); return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
&& desc.equals(h.desc);
} }
@Override @Override
@@ -133,7 +154,8 @@ public final class Handle {
} }
/** /**
* Returns the textual representation of this handle. The textual representation is: * Returns the textual representation of this handle. The textual
* representation is:
* *
* <pre> * <pre>
* owner '.' name desc ' ' '(' tag ')' * owner '.' name desc ' ' '(' tag ')'

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -44,14 +52,14 @@ class Handler {
Label handler; Label handler;
/** /**
* Internal name of the type of exceptions handled by this handler, or <tt>null</tt> to catch * Internal name of the type of exceptions handled by this handler, or
* any exceptions. * <tt>null</tt> to catch any exceptions.
*/ */
String desc; String desc;
/** /**
* Constant pool index of the internal name of the type of exceptions handled by this handler, * Constant pool index of the internal name of the type of exceptions
* or 0 to catch any exceptions. * handled by this handler, or 0 to catch any exceptions.
*/ */
int type; int type;
@@ -61,11 +69,15 @@ class Handler {
Handler next; Handler next;
/** /**
* Removes the range between start and end from the given exception handlers. * Removes the range between start and end from the given exception
* handlers.
* *
* @param h an exception handler list. * @param h
* @param start the start of the range to be removed. * an exception handler list.
* @param end the end of the range to be removed. Maybe null. * @param start
* the start of the range to be removed.
* @param end
* the end of the range to be removed. Maybe null.
* @return the exception handler list with the start-end range removed. * @return the exception handler list with the start-end range removed.
*/ */
static Handler remove(Handler h, Label start, Label end) { static Handler remove(Handler h, Label start, Label end) {

View File

@@ -1,29 +1,37 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
/** /**
* A constant pool item. Constant pool items can be created with the 'newXXX' methods in the * A constant pool item. Constant pool items can be created with the 'newXXX'
* {@link ClassWriter} class. * methods in the {@link ClassWriter} class.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -35,21 +43,25 @@ final class Item {
int index; int index;
/** /**
* Type of this constant pool item. A single class is used to represent all constant pool item * Type of this constant pool item. A single class is used to represent all
* types, in order to minimize the bytecode size of this package. The value of this field is one * constant pool item types, in order to minimize the bytecode size of this
* of {@link ClassWriter#INT}, {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, * package. The value of this field is one of {@link ClassWriter#INT},
* {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, {@link ClassWriter#STR}, * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
* {@link ClassWriter#CLASS}, {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD}, * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH}, {@link ClassWriter#MTYPE}, * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
* {@link ClassWriter#INDY}. * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
* *
* MethodHandle constant 9 variations are stored using a range of 9 values from * MethodHandle constant 9 variations are stored using a range of 9 values
* {@link ClassWriter#HANDLE_BASE} + 1 to {@link ClassWriter#HANDLE_BASE} + 9. * from {@link ClassWriter#HANDLE_BASE} + 1 to
* {@link ClassWriter#HANDLE_BASE} + 9.
* *
* Special Item types are used for Items that are stored in the ClassWriter * Special Item types are used for Items that are stored in the ClassWriter
* {@link ClassWriter#typeTable}, instead of the constant pool, in order to avoid clashes with * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
* normal constant pool items in the ClassWriter constant pool's hash table. These special item * avoid clashes with normal constant pool items in the ClassWriter constant
* types are {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and * pool's hash table. These special item types are
* {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
* {@link ClassWriter#TYPE_MERGED}. * {@link ClassWriter#TYPE_MERGED}.
*/ */
int type; int type;
@@ -65,17 +77,20 @@ final class Item {
long longVal; long longVal;
/** /**
* First part of the value of this item, for items that do not hold a primitive value. * First part of the value of this item, for items that do not hold a
* primitive value.
*/ */
String strVal1; String strVal1;
/** /**
* Second part of the value of this item, for items that do not hold a primitive value. * Second part of the value of this item, for items that do not hold a
* primitive value.
*/ */
String strVal2; String strVal2;
/** /**
* Third part of the value of this item, for items that do not hold a primitive value. * Third part of the value of this item, for items that do not hold a
* primitive value.
*/ */
String strVal3; String strVal3;
@@ -85,20 +100,23 @@ final class Item {
int hashCode; int hashCode;
/** /**
* Link to another constant pool item, used for collision lists in the constant pool's hash * Link to another constant pool item, used for collision lists in the
* table. * constant pool's hash table.
*/ */
Item next; Item next;
/** /**
* Constructs an uninitialized {@link Item}. * Constructs an uninitialized {@link Item}.
*/ */
Item() {} Item() {
}
/** /**
* Constructs an uninitialized {@link Item} for constant pool element at given position. * Constructs an uninitialized {@link Item} for constant pool element at
* given position.
* *
* @param index index of the item to be constructed. * @param index
* index of the item to be constructed.
*/ */
Item(final int index) { Item(final int index) {
this.index = index; this.index = index;
@@ -107,8 +125,10 @@ final class Item {
/** /**
* Constructs a copy of the given item. * Constructs a copy of the given item.
* *
* @param index index of the item to be constructed. * @param index
* @param i the item that must be copied into the item to be constructed. * index of the item to be constructed.
* @param i
* the item that must be copied into the item to be constructed.
*/ */
Item(final int index, final Item i) { Item(final int index, final Item i) {
this.index = index; this.index = index;
@@ -124,7 +144,8 @@ final class Item {
/** /**
* Sets this item to an integer item. * Sets this item to an integer item.
* *
* @param intVal the value of this item. * @param intVal
* the value of this item.
*/ */
void set(final int intVal) { void set(final int intVal) {
this.type = ClassWriter.INT; this.type = ClassWriter.INT;
@@ -135,7 +156,8 @@ final class Item {
/** /**
* Sets this item to a long item. * Sets this item to a long item.
* *
* @param longVal the value of this item. * @param longVal
* the value of this item.
*/ */
void set(final long longVal) { void set(final long longVal) {
this.type = ClassWriter.LONG; this.type = ClassWriter.LONG;
@@ -146,7 +168,8 @@ final class Item {
/** /**
* Sets this item to a float item. * Sets this item to a float item.
* *
* @param floatVal the value of this item. * @param floatVal
* the value of this item.
*/ */
void set(final float floatVal) { void set(final float floatVal) {
this.type = ClassWriter.FLOAT; this.type = ClassWriter.FLOAT;
@@ -157,7 +180,8 @@ final class Item {
/** /**
* Sets this item to a double item. * Sets this item to a double item.
* *
* @param doubleVal the value of this item. * @param doubleVal
* the value of this item.
*/ */
void set(final double doubleVal) { void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE; this.type = ClassWriter.DOUBLE;
@@ -168,12 +192,17 @@ final class Item {
/** /**
* Sets this item to an item that do not hold a primitive value. * Sets this item to an item that do not hold a primitive value.
* *
* @param type the type of this item. * @param type
* @param strVal1 first part of the value of this item. * the type of this item.
* @param strVal2 second part of the value of this item. * @param strVal1
* @param strVal3 third part of the value of this item. * first part of the value of this item.
* @param strVal2
* second part of the value of this item.
* @param strVal3
* third part of the value of this item.
*/ */
void set(final int type, final String strVal1, final String strVal2, final String strVal3) { void set(final int type, final String strVal1, final String strVal2,
final String strVal3) {
this.type = type; this.type = type;
this.strVal1 = strVal1; this.strVal1 = strVal1;
this.strVal2 = strVal2; this.strVal2 = strVal2;
@@ -187,7 +216,8 @@ final class Item {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return; return;
case ClassWriter.NAME_TYPE: { case ClassWriter.NAME_TYPE: {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode()); hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
* strVal2.hashCode());
return; return;
} }
// ClassWriter.FIELD: // ClassWriter.FIELD:
@@ -195,33 +225,39 @@ final class Item {
// ClassWriter.IMETH: // ClassWriter.IMETH:
// ClassWriter.HANDLE_BASE + 1..9 // ClassWriter.HANDLE_BASE + 1..9
default: default:
hashCode = 0x7FFFFFFF hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
& (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode()); * strVal2.hashCode() * strVal3.hashCode());
} }
} }
/** /**
* Sets the item to an InvokeDynamic item. * Sets the item to an InvokeDynamic item.
* *
* @param name invokedynamic's name. * @param name
* @param desc invokedynamic's desc. * invokedynamic's name.
* @param bsmIndex zero based index into the class attribute BootrapMethods. * @param desc
* invokedynamic's desc.
* @param bsmIndex
* zero based index into the class attribute BootrapMethods.
*/ */
void set(String name, String desc, int bsmIndex) { void set(String name, String desc, int bsmIndex) {
this.type = ClassWriter.INDY; this.type = ClassWriter.INDY;
this.longVal = bsmIndex; this.longVal = bsmIndex;
this.strVal1 = name; this.strVal1 = name;
this.strVal2 = desc; this.strVal2 = desc;
this.hashCode = 0x7FFFFFFF this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex
& (ClassWriter.INDY + bsmIndex * strVal1.hashCode() * strVal2.hashCode()); * strVal1.hashCode() * strVal2.hashCode());
} }
/** /**
* Sets the item to a BootstrapMethod item. * Sets the item to a BootstrapMethod item.
* *
* @param position position in byte in the class attribute BootrapMethods. * @param position
* @param hashCode hashcode of the item. This hashcode is processed from the hashcode of the * position in byte in the class attribute BootrapMethods.
* bootstrap method and the hashcode of all bootstrap arguments. * @param hashCode
* hashcode of the item. This hashcode is processed from the
* hashcode of the bootstrap method and the hashcode of all
* bootstrap arguments.
*/ */
void set(int position, int hashCode) { void set(int position, int hashCode) {
this.type = ClassWriter.BSM; this.type = ClassWriter.BSM;
@@ -230,11 +266,14 @@ final class Item {
} }
/** /**
* Indicates if the given item is equal to this one. <i>This method assumes that the two items * Indicates if the given item is equal to this one. <i>This method assumes
* have the same {@link #type}</i>. * that the two items have the same {@link #type}</i>.
* *
* @param i the item to be compared to this one. Both items must have the same {@link #type}. * @param i
* @return <tt>true</tt> if the given item if equal to this one, <tt>false</tt> otherwise. * the item to be compared to this one. Both items must have the
* same {@link #type}.
* @return <tt>true</tt> if the given item if equal to this one,
* <tt>false</tt> otherwise.
*/ */
boolean isEqualTo(final Item i) { boolean isEqualTo(final Item i) {
switch (type) { switch (type) {

View File

@@ -1,40 +1,50 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
/** /**
* A label represents a position in the bytecode of a method. Labels are used for jump, goto, and * A label represents a position in the bytecode of a method. Labels are used
* switch instructions, and for try catch blocks. A label designates the <i>instruction</i> that is * for jump, goto, and switch instructions, and for try catch blocks. A label
* just after. Note however that there can be other elements between a label and the instruction it * designates the <i>instruction</i> that is just after. Note however that there
* designates (such as other labels, stack map frames, line numbers, etc.). * can be other elements between a label and the instruction it designates (such
* as other labels, stack map frames, line numbers, etc.).
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class Label { public class Label {
/** /**
* Indicates if this label is only used for debug attributes. Such a label is not the start of a * Indicates if this label is only used for debug attributes. Such a label
* basic block, the target of a jump instruction, or an exception handler. It can be safely * is not the start of a basic block, the target of a jump instruction, or
* ignored in control flow graph analysis algorithms (for optimization purposes). * an exception handler. It can be safely ignored in control flow graph
* analysis algorithms (for optimization purposes).
*/ */
static final int DEBUG = 1; static final int DEBUG = 1;
@@ -49,14 +59,14 @@ public class Label {
static final int RESIZED = 4; static final int RESIZED = 4;
/** /**
* Indicates if this basic block has been pushed in the basic block stack. See * Indicates if this basic block has been pushed in the basic block stack.
* {@link MethodWriter#visitMaxs visitMaxs}. * See {@link MethodWriter#visitMaxs visitMaxs}.
*/ */
static final int PUSHED = 8; static final int PUSHED = 8;
/** /**
* Indicates if this label is the target of a jump instruction, or the start of an exception * Indicates if this label is the target of a jump instruction, or the start
* handler. * of an exception handler.
*/ */
static final int TARGET = 16; static final int TARGET = 16;
@@ -86,20 +96,21 @@ public class Label {
static final int SUBROUTINE = 512; static final int SUBROUTINE = 512;
/** /**
* Indicates if this subroutine basic block has been visited by a visitSubroutine(null, ...) * Indicates if this subroutine basic block has been visited by a
* call. * visitSubroutine(null, ...) call.
*/ */
static final int VISITED = 1024; static final int VISITED = 1024;
/** /**
* Indicates if this subroutine basic block has been visited by a visitSubroutine(!null, ...) * Indicates if this subroutine basic block has been visited by a
* call. * visitSubroutine(!null, ...) call.
*/ */
static final int VISITED2 = 2048; static final int VISITED2 = 2048;
/** /**
* Field used to associate user information to a label. Warning: this field is used by the ASM * Field used to associate user information to a label. Warning: this field
* tree package. In order to use it with the ASM tree package you must override the * is used by the ASM tree package. In order to use it with the ASM tree
* package you must override the
* {@link org.objectweb.asm.tree.MethodNode#getLabelNode} method. * {@link org.objectweb.asm.tree.MethodNode#getLabelNode} method.
*/ */
public Object info; public Object info;
@@ -135,89 +146,100 @@ public class Label {
private int referenceCount; private int referenceCount;
/** /**
* Informations about forward references. Each forward reference is described by two consecutive * Informations about forward references. Each forward reference is
* integers in this array: the first one is the position of the first byte of the bytecode * described by two consecutive integers in this array: the first one is the
* instruction that contains the forward reference, while the second is the position of the * position of the first byte of the bytecode instruction that contains the
* first byte of the forward reference itself. In fact the sign of the first integer indicates * forward reference, while the second is the position of the first byte of
* if this reference uses 2 or 4 bytes, and its absolute value gives the position of the * the forward reference itself. In fact the sign of the first integer
* bytecode instruction. This array is also used as a bitset to store the subroutines to which a * indicates if this reference uses 2 or 4 bytes, and its absolute value
* basic block belongs. This information is needed in {@linked MethodWriter#visitMaxs}, after * gives the position of the bytecode instruction. This array is also used
* all forward references have been resolved. Hence the same array can be used for both purposes * as a bitset to store the subroutines to which a basic block belongs. This
* without problems. * information is needed in {@linked MethodWriter#visitMaxs}, after all
* forward references have been resolved. Hence the same array can be used
* for both purposes without problems.
*/ */
private int[] srcAndRefPositions; private int[] srcAndRefPositions;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/* /*
* Fields for the control flow and data flow graph analysis algorithms (used to compute the * Fields for the control flow and data flow graph analysis algorithms (used
* maximum stack size or the stack map frames). A control flow graph contains one node per * to compute the maximum stack size or the stack map frames). A control
* "basic block", and one edge per "jump" from one basic block to another. Each node (i.e., each * flow graph contains one node per "basic block", and one edge per "jump"
* basic block) is represented by the Label object that corresponds to the first instruction of * from one basic block to another. Each node (i.e., each basic block) is
* this basic block. Each node also stores the list of its successors in the graph, as a linked * represented by the Label object that corresponds to the first instruction
* list of Edge objects. * of this basic block. Each node also stores the list of its successors in
* the graph, as a linked list of Edge objects.
* *
* The control flow analysis algorithms used to compute the maximum stack size or the stack map * The control flow analysis algorithms used to compute the maximum stack
* frames are similar and use two steps. The first step, during the visit of each instruction, * size or the stack map frames are similar and use two steps. The first
* builds information about the state of the local variables and the operand stack at the end of * step, during the visit of each instruction, builds information about the
* each basic block, called the "output frame", <i>relatively</i> to the frame state at the * state of the local variables and the operand stack at the end of each
* beginning of the basic block, which is called the "input frame", and which is <i>unknown</i> * basic block, called the "output frame", <i>relatively</i> to the frame
* during this step. The second step, in {@link MethodWriter#visitMaxs}, is a fix point * state at the beginning of the basic block, which is called the "input
* algorithm that computes information about the input frame of each basic block, from the input * frame", and which is <i>unknown</i> during this step. The second step, in
* state of the first basic block (known from the method signature), and by the using the * {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes
* previously computed relative output frames. * information about the input frame of each basic block, from the input
* state of the first basic block (known from the method signature), and by
* the using the previously computed relative output frames.
* *
* The algorithm used to compute the maximum stack size only computes the relative output and * The algorithm used to compute the maximum stack size only computes the
* absolute input stack heights, while the algorithm used to compute stack map frames computes * relative output and absolute input stack heights, while the algorithm
* relative output frames and absolute input frames. * used to compute stack map frames computes relative output frames and
* absolute input frames.
*/ */
/** /**
* Start of the output stack relatively to the input stack. The exact semantics of this field * Start of the output stack relatively to the input stack. The exact
* depends on the algorithm that is used. * semantics of this field depends on the algorithm that is used.
* *
* When only the maximum stack size is computed, this field is the number of elements in the * When only the maximum stack size is computed, this field is the number of
* input stack. * elements in the input stack.
* *
* When the stack map frames are completely computed, this field is the offset of the first * When the stack map frames are completely computed, this field is the
* output stack element relatively to the top of the input stack. This offset is always negative * offset of the first output stack element relatively to the top of the
* or null. A null offset means that the output stack must be appended to the input stack. A -n * input stack. This offset is always negative or null. A null offset means
* offset means that the first n output stack elements must replace the top n input stack * that the output stack must be appended to the input stack. A -n offset
* elements, and that the other elements must be appended to the input stack. * means that the first n output stack elements must replace the top n input
* stack elements, and that the other elements must be appended to the input
* stack.
*/ */
int inputStackTop; int inputStackTop;
/** /**
* Maximum height reached by the output stack, relatively to the top of the input stack. This * Maximum height reached by the output stack, relatively to the top of the
* maximum is always positive or null. * input stack. This maximum is always positive or null.
*/ */
int outputStackMax; int outputStackMax;
/** /**
* Information about the input and output stack map frames of this basic block. This field is * Information about the input and output stack map frames of this basic
* only used when {@link ClassWriter#COMPUTE_FRAMES} option is used. * block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES}
* option is used.
*/ */
Frame frame; Frame frame;
/** /**
* The successor of this label, in the order they are visited. This linked list does not include * The successor of this label, in the order they are visited. This linked
* labels used for debug info only. If {@link ClassWriter#COMPUTE_FRAMES} option is used then, * list does not include labels used for debug info only. If
* in addition, it does not contain successive labels that denote the same bytecode position (in * {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it
* this case only the first label appears in this list). * does not contain successive labels that denote the same bytecode position
* (in this case only the first label appears in this list).
*/ */
Label successor; Label successor;
/** /**
* The successors of this node in the control flow graph. These successors are stored in a * The successors of this node in the control flow graph. These successors
* linked list of {@link Edge Edge} objects, linked to each other by their {@link Edge#next} * are stored in a linked list of {@link Edge Edge} objects, linked to each
* field. * other by their {@link Edge#next} field.
*/ */
Edge successors; Edge successors;
/** /**
* The next basic block in the basic block stack. This stack is used in the main loop of the fix * The next basic block in the basic block stack. This stack is used in the
* point algorithm used in the second step of the control flow analysis algorithms. It is also * main loop of the fix point algorithm used in the second step of the
* used in {@link #visitSubroutine} to avoid using a recursive method. * control flow analysis algorithms. It is also used in
* {@link #visitSubroutine} to avoid using a recursive method.
* *
* @see MethodWriter#visitMaxs * @see MethodWriter#visitMaxs
*/ */
@@ -230,39 +252,49 @@ public class Label {
/** /**
* Constructs a new label. * Constructs a new label.
*/ */
public Label() {} public Label() {
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Methods to compute offsets and to manage forward references // Methods to compute offsets and to manage forward references
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the offset corresponding to this label. This offset is computed from the start of the * Returns the offset corresponding to this label. This offset is computed
* method's bytecode. <i>This method is intended for {@link Attribute} sub classes, and is * from the start of the method's bytecode. <i>This method is intended for
* normally not needed by class generators or adapters.</i> * {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.</i>
* *
* @return the offset corresponding to this label. * @return the offset corresponding to this label.
* @throws IllegalStateException if this label is not resolved yet. * @throws IllegalStateException
* if this label is not resolved yet.
*/ */
public int getOffset() { public int getOffset() {
if ((status & RESOLVED) == 0) { if ((status & RESOLVED) == 0) {
throw new IllegalStateException("Label offset position has not been resolved yet"); throw new IllegalStateException(
"Label offset position has not been resolved yet");
} }
return position; return position;
} }
/** /**
* Puts a reference to this label in the bytecode of a method. If the position of the label is * Puts a reference to this label in the bytecode of a method. If the
* known, the offset is computed and written directly. Otherwise, a null offset is written and a * position of the label is known, the offset is computed and written
* new forward reference is declared for this label. * directly. Otherwise, a null offset is written and a new forward reference
* is declared for this label.
* *
* @param owner the code writer that calls this method. * @param owner
* @param out the bytecode of the method. * the code writer that calls this method.
* @param source the position of first byte of the bytecode instruction that contains this * @param out
* label. * the bytecode of the method.
* @param wideOffset <tt>true</tt> if the reference must be stored in 4 bytes, or <tt>false</tt> * @param source
* if it must be stored with 2 bytes. * the position of first byte of the bytecode instruction that
* @throws IllegalArgumentException if this label has not been created by the given code writer. * contains this label.
* @param wideOffset
* <tt>true</tt> if the reference must be stored in 4 bytes, or
* <tt>false</tt> if it must be stored with 2 bytes.
* @throws IllegalArgumentException
* if this label has not been created by the given code writer.
*/ */
void put(final MethodWriter owner, final ByteVector out, final int source, void put(final MethodWriter owner, final ByteVector out, final int source,
final boolean wideOffset) { final boolean wideOffset) {
@@ -284,22 +316,27 @@ public class Label {
} }
/** /**
* Adds a forward reference to this label. This method must be called only for a true forward * Adds a forward reference to this label. This method must be called only
* reference, i.e. only if this label is not resolved yet. For backward references, the offset * for a true forward reference, i.e. only if this label is not resolved
* of the reference can be, and must be, computed and stored directly. * yet. For backward references, the offset of the reference can be, and
* must be, computed and stored directly.
* *
* @param sourcePosition the position of the referencing instruction. This position will be used * @param sourcePosition
* to compute the offset of this forward reference. * the position of the referencing instruction. This position
* @param referencePosition the position where the offset for this forward reference must be * will be used to compute the offset of this forward reference.
* stored. * @param referencePosition
* the position where the offset for this forward reference must
* be stored.
*/ */
private void addReference(final int sourcePosition, final int referencePosition) { private void addReference(final int sourcePosition,
final int referencePosition) {
if (srcAndRefPositions == null) { if (srcAndRefPositions == null) {
srcAndRefPositions = new int[6]; srcAndRefPositions = new int[6];
} }
if (referenceCount >= srcAndRefPositions.length) { if (referenceCount >= srcAndRefPositions.length) {
int[] a = new int[srcAndRefPositions.length + 6]; int[] a = new int[srcAndRefPositions.length + 6];
System.arraycopy(srcAndRefPositions, 0, a, 0, srcAndRefPositions.length); System.arraycopy(srcAndRefPositions, 0, a, 0,
srcAndRefPositions.length);
srcAndRefPositions = a; srcAndRefPositions = a;
} }
srcAndRefPositions[referenceCount++] = sourcePosition; srcAndRefPositions[referenceCount++] = sourcePosition;
@@ -307,23 +344,30 @@ public class Label {
} }
/** /**
* Resolves all forward references to this label. This method must be called when this label is * Resolves all forward references to this label. This method must be called
* added to the bytecode of the method, i.e. when its position becomes known. This method fills * when this label is added to the bytecode of the method, i.e. when its
* in the blanks that where left in the bytecode by each forward reference previously added to * position becomes known. This method fills in the blanks that where left
* this label. * in the bytecode by each forward reference previously added to this label.
* *
* @param owner the code writer that calls this method. * @param owner
* @param position the position of this label in the bytecode. * the code writer that calls this method.
* @param data the bytecode of the method. * @param position
* @return <tt>true</tt> if a blank that was left for this label was to small to store the * the position of this label in the bytecode.
* offset. In such a case the corresponding jump instruction is replaced with a pseudo * @param data
* instruction (using unused opcodes) using an unsigned two bytes offset. These pseudo * the bytecode of the method.
* instructions will need to be replaced with true instructions with wider offsets (4 * @return <tt>true</tt> if a blank that was left for this label was to
* bytes instead of 2). This is done in {@link MethodWriter#resizeInstructions}. * small to store the offset. In such a case the corresponding jump
* @throws IllegalArgumentException if this label has already been resolved, or if it has not * instruction is replaced with a pseudo instruction (using unused
* opcodes) using an unsigned two bytes offset. These pseudo
* instructions will need to be replaced with true instructions with
* wider offsets (4 bytes instead of 2). This is done in
* {@link MethodWriter#resizeInstructions}.
* @throws IllegalArgumentException
* if this label has already been resolved, or if it has not
* been created by the given code writer. * been created by the given code writer.
*/ */
boolean resolve(final MethodWriter owner, final int position, final byte[] data) { boolean resolve(final MethodWriter owner, final int position,
final byte[] data) {
boolean needUpdate = false; boolean needUpdate = false;
this.status |= RESOLVED; this.status |= RESOLVED;
this.position = position; this.position = position;
@@ -336,11 +380,13 @@ public class Label {
offset = position - source; offset = position - source;
if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) { if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) {
/* /*
* changes the opcode of the jump instruction, in order to be able to find it * changes the opcode of the jump instruction, in order to
* later (see resizeInstructions in MethodWriter). These temporary opcodes are * be able to find it later (see resizeInstructions in
* similar to jump instruction opcodes, except that the 2 bytes offset is * MethodWriter). These temporary opcodes are similar to
* unsigned (and can therefore represent values from 0 to 65535, which is * jump instruction opcodes, except that the 2 bytes offset
* sufficient since the size of a method is limited to 65535 bytes). * is unsigned (and can therefore represent values from 0 to
* 65535, which is sufficient since the size of a method is
* limited to 65535 bytes).
*/ */
int opcode = data[reference - 1] & 0xFF; int opcode = data[reference - 1] & 0xFF;
if (opcode <= Opcodes.JSR) { if (opcode <= Opcodes.JSR) {
@@ -366,9 +412,10 @@ public class Label {
} }
/** /**
* Returns the first label of the series to which this label belongs. For an isolated label or * Returns the first label of the series to which this label belongs. For an
* for the first label in a series of successive labels, this method returns the label itself. * isolated label or for the first label in a series of successive labels,
* For other labels it returns the first label of the series. * this method returns the label itself. For other labels it returns the
* first label of the series.
* *
* @return the first label of the series to which this label belongs. * @return the first label of the series to which this label belongs.
*/ */
@@ -383,7 +430,8 @@ public class Label {
/** /**
* Returns true is this basic block belongs to the given subroutine. * Returns true is this basic block belongs to the given subroutine.
* *
* @param id a subroutine id. * @param id
* a subroutine id.
* @return true is this basic block belongs to the given subroutine. * @return true is this basic block belongs to the given subroutine.
*/ */
boolean inSubroutine(final long id) { boolean inSubroutine(final long id) {
@@ -394,10 +442,13 @@ public class Label {
} }
/** /**
* Returns true if this basic block and the given one belong to a common subroutine. * Returns true if this basic block and the given one belong to a common
* subroutine.
* *
* @param block another basic block. * @param block
* @return true if this basic block and the given one belong to a common subroutine. * another basic block.
* @return true if this basic block and the given one belong to a common
* subroutine.
*/ */
boolean inSameSubroutine(final Label block) { boolean inSameSubroutine(final Label block) {
if ((status & VISITED) == 0 || (block.status & VISITED) == 0) { if ((status & VISITED) == 0 || (block.status & VISITED) == 0) {
@@ -414,8 +465,10 @@ public class Label {
/** /**
* Marks this basic block as belonging to the given subroutine. * Marks this basic block as belonging to the given subroutine.
* *
* @param id a subroutine id. * @param id
* @param nbSubroutines the total number of subroutines in the method. * a subroutine id.
* @param nbSubroutines
* the total number of subroutines in the method.
*/ */
void addToSubroutine(final long id, final int nbSubroutines) { void addToSubroutine(final long id, final int nbSubroutines) {
if ((status & VISITED) == 0) { if ((status & VISITED) == 0) {
@@ -426,14 +479,19 @@ public class Label {
} }
/** /**
* Finds the basic blocks that belong to a given subroutine, and marks these blocks as belonging * Finds the basic blocks that belong to a given subroutine, and marks these
* to this subroutine. This method follows the control flow graph to find all the blocks that * blocks as belonging to this subroutine. This method follows the control
* are reachable from the current block WITHOUT following any JSR target. * flow graph to find all the blocks that are reachable from the current
* block WITHOUT following any JSR target.
* *
* @param JSR a JSR block that jumps to this subroutine. If this JSR is not null it is added to * @param JSR
* the successor of the RET blocks found in the subroutine. * a JSR block that jumps to this subroutine. If this JSR is not
* @param id the id of this subroutine. * null it is added to the successor of the RET blocks found in
* @param nbSubroutines the total number of subroutines in the method. * the subroutine.
* @param id
* the id of this subroutine.
* @param nbSubroutines
* the total number of subroutines in the method.
*/ */
void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) { void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) {
// user managed stack of labels, to avoid using a recursive method // user managed stack of labels, to avoid using a recursive method

View File

@@ -1,58 +1,71 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
/** /**
* A visitor to visit a Java method. The methods of this class must be called in the following * A visitor to visit a Java method. The methods of this class must be called in
* order: [ <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> | * the following order: [ <tt>visitAnnotationDefault</tt> ] (
* <tt>visitParameterAnnotation</tt> | <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( * <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
* <tt>visitFrame</tt> | <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> | * <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
* <tt>visitTryCatchBlock</tt> | <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt> )* * <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> |
* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the <tt>visit</tt><i>X</i>Insn</tt> and * <tt>visitTryCatchBlock</tt> | <tt>visitLocalVariable</tt> |
* <tt>visitLabel</tt> methods must be called in the sequential order of the bytecode instructions * <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
* of the visited code, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the labels passed * addition, the <tt>visit</tt><i>X</i>Insn</tt> and <tt>visitLabel</tt> methods
* as arguments have been visited, and the <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt> * must be called in the sequential order of the bytecode instructions of the
* methods must be called <i>after</i> the labels passed as arguments have been visited. * visited code, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
* labels passed as arguments have been visited, and the
* <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt> methods must be
* called <i>after</i> the labels passed as arguments have been visited.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public abstract class MethodVisitor { public abstract class MethodVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field must be one of * The ASM API version implemented by this visitor. The value of this field
* {@link Opcodes#ASM4}. * must be one of {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* The method visitor to which this visitor must delegate method calls. May be null. * The method visitor to which this visitor must delegate method calls. May
* be null.
*/ */
protected MethodVisitor mv; protected MethodVisitor mv;
/** /**
* Constructs a new {@link MethodVisitor}. * Constructs a new {@link MethodVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
*/ */
public MethodVisitor(final int api) { public MethodVisitor(final int api) {
this(api, null); this(api, null);
@@ -61,9 +74,12 @@ public abstract class MethodVisitor {
/** /**
* Constructs a new {@link MethodVisitor}. * Constructs a new {@link MethodVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param mv the method visitor to which this visitor must delegate method calls. May be null. * of {@link Opcodes#ASM4}.
* @param mv
* the method visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public MethodVisitor(final int api, final MethodVisitor mv) { public MethodVisitor(final int api, final MethodVisitor mv) {
if (api != Opcodes.ASM4) { if (api != Opcodes.ASM4) {
@@ -80,11 +96,12 @@ public abstract class MethodVisitor {
/** /**
* Visits the default value of this annotation interface method. * Visits the default value of this annotation interface method.
* *
* @return a visitor to the visit the actual default value of this annotation interface method, * @return a visitor to the visit the actual default value of this
* or <tt>null</tt> if this visitor is not interested in visiting this default value. * annotation interface method, or <tt>null</tt> if this visitor is
* The 'name' parameters passed to the methods of this annotation visitor are ignored. * not interested in visiting this default value. The 'name'
* Moreover, exacly one visit method must be called on this annotation visitor, followed * parameters passed to the methods of this annotation visitor are
* by visitEnd. * ignored. Moreover, exacly one visit method must be called on this
* annotation visitor, followed by visitEnd.
*/ */
public AnnotationVisitor visitAnnotationDefault() { public AnnotationVisitor visitAnnotationDefault() {
if (mv != null) { if (mv != null) {
@@ -96,10 +113,12 @@ public abstract class MethodVisitor {
/** /**
* Visits an annotation of this method. * Visits an annotation of this method.
* *
* @param desc the class descriptor of the annotation class. * @param desc
* @param visible <tt>true</tt> if the annotation is visible at runtime. * the class descriptor of the annotation class.
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not * @param visible
* interested in visiting this annotation. * <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (mv != null) { if (mv != null) {
@@ -111,13 +130,17 @@ public abstract class MethodVisitor {
/** /**
* Visits an annotation of a parameter this method. * Visits an annotation of a parameter this method.
* *
* @param parameter the parameter index. * @param parameter
* @param desc the class descriptor of the annotation class. * the parameter index.
* @param visible <tt>true</tt> if the annotation is visible at runtime. * @param desc
* @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not * the class descriptor of the annotation class.
* interested in visiting this annotation. * @param visible
* <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { public AnnotationVisitor visitParameterAnnotation(int parameter,
String desc, boolean visible) {
if (mv != null) { if (mv != null) {
return mv.visitParameterAnnotation(parameter, desc, visible); return mv.visitParameterAnnotation(parameter, desc, visible);
} }
@@ -127,7 +150,8 @@ public abstract class MethodVisitor {
/** /**
* Visits a non standard attribute of this method. * Visits a non standard attribute of this method.
* *
* @param attr an attribute. * @param attr
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (mv != null) { if (mv != null) {
@@ -145,63 +169,80 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the current state of the local variables and operand stack elements. This method * Visits the current state of the local variables and operand stack
* must(*) be called <i>just before</i> any instruction <b>i</b> that follows an unconditional * elements. This method must(*) be called <i>just before</i> any
* branch instruction such as GOTO or THROW, that is the target of a jump instruction, or that * instruction <b>i</b> that follows an unconditional branch instruction
* starts an exception handler block. The visited types must describe the values of the local * such as GOTO or THROW, that is the target of a jump instruction, or that
* variables and of the operand stack elements <i>just before</i> <b>i</b> is executed.<br> * starts an exception handler block. The visited types must describe the
* values of the local variables and of the operand stack elements <i>just
* before</i> <b>i</b> is executed.<br>
* <br> * <br>
* (*) this is mandatory only for classes whose version is greater than or equal to * (*) this is mandatory only for classes whose version is greater than or
* {@link Opcodes#V1_6 V1_6}. <br> * equal to {@link Opcodes#V1_6 V1_6}. <br>
* <br> * <br>
* The frames of a method must be given either in expanded form, or in compressed form (all * The frames of a method must be given either in expanded form, or in
* frames must use the same format, i.e. you must not mix expanded and compressed frames within * compressed form (all frames must use the same format, i.e. you must not
* a single method): * mix expanded and compressed frames within a single method):
* <ul> * <ul>
* <li>In expanded form, all frames must have the F_NEW type.</li> * <li>In expanded form, all frames must have the F_NEW type.</li>
* <li>In compressed form, frames are basically "deltas" from the state of the previous frame: * <li>In compressed form, frames are basically "deltas" from the state of
* the previous frame:
* <ul> * <ul>
* <li>{@link Opcodes#F_SAME} representing frame with exactly the same locals as the previous * <li>{@link Opcodes#F_SAME} representing frame with exactly the same
* frame and with the empty stack.</li> * locals as the previous frame and with the empty stack.</li>
* <li>{@link Opcodes#F_SAME1} representing frame with exactly the same locals as the previous * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same
* frame and with single value on the stack ( <code>nStack</code> is 1 and <code>stack[0]</code> * locals as the previous frame and with single value on the stack (
* contains value for the type of the stack item).</li> * <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the
* <li>{@link Opcodes#F_APPEND} representing frame with current locals are the same as the * type of the stack item).</li>
* locals in the previous frame, except that additional locals are defined (<code>nLocal</code> * <li>{@link Opcodes#F_APPEND} representing frame with current locals are
* is 1, 2 or 3 and <code>local</code> elements contains values representing added types).</li> * the same as the locals in the previous frame, except that additional
* <li>{@link Opcodes#F_CHOP} representing frame with current locals are the same as the locals * locals are defined (<code>nLocal</code> is 1, 2 or 3 and
* in the previous frame, except that the last 1-3 locals are absent and with the empty stack * <code>local</code> elements contains values representing added types).</li>
* (<code>nLocals</code> is 1, 2 or 3).</li> * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the
* same as the locals in the previous frame, except that the last 1-3 locals
* are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
* <li>{@link Opcodes#F_FULL} representing complete frame data.</li></li> * <li>{@link Opcodes#F_FULL} representing complete frame data.</li></li>
* </ul> * </ul>
* </ul> * </ul> <br>
* <br> * In both cases the first frame, corresponding to the method's parameters
* In both cases the first frame, corresponding to the method's parameters and access flags, is * and access flags, is implicit and must not be visited. Also, it is
* implicit and must not be visited. Also, it is illegal to visit two or more frames for the * illegal to visit two or more frames for the same code location (i.e., at
* same code location (i.e., at least one instruction must be visited between two calls to * least one instruction must be visited between two calls to visitFrame).
* visitFrame).
* *
* @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded * @param type
* frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, * the type of this stack map frame. Must be
* {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for * {@link Opcodes#F_NEW} for expanded frames, or
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
* {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
* compressed frames. * compressed frames.
* @param nLocal the number of local variables in the visited frame. * @param nLocal
* @param local the local variable types in this frame. This array must not be modified. * the number of local variables in the visited frame.
* Primitive types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, * @param local
* the local variable types in this frame. This array must not be
* modified. Primitive types are represented by
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
* (long and double are represented by a single element). Reference types are represented * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
* by String objects (representing internal names), and uninitialized types by Label * represented by a single element). Reference types are
* objects (this label designates the NEW instruction that created this uninitialized * represented by String objects (representing internal names),
* and uninitialized types by Label objects (this label
* designates the NEW instruction that created this uninitialized
* value). * value).
* @param nStack the number of operand stack elements in the visited frame. * @param nStack
* @param stack the operand stack types in this frame. This array must not be modified. Its * the number of operand stack elements in the visited frame.
* content has the same format as the "local" array. * @param stack
* @throws IllegalStateException if a frame is visited just after another one, without any * the operand stack types in this frame. This array must not be
* instruction between the two (unless this frame is a Opcodes#F_SAME frame, in which * modified. Its content has the same format as the "local"
* case it is silently ignored). * array.
* @throws IllegalStateException
* if a frame is visited just after another one, without any
* instruction between the two (unless this frame is a
* Opcodes#F_SAME frame, in which case it is silently ignored).
*/ */
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { public void visitFrame(int type, int nLocal, Object[] local, int nStack,
Object[] stack) {
if (mv != null) { if (mv != null) {
mv.visitFrame(type, nLocal, local, nStack, stack); mv.visitFrame(type, nLocal, local, nStack, stack);
} }
@@ -214,17 +255,22 @@ public abstract class MethodVisitor {
/** /**
* Visits a zero operand instruction. * Visits a zero operand instruction.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is either NOP, * @param opcode
* ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, * the opcode of the instruction to be visited. This opcode is
* LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
* FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE, * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
* AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
* IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
* ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
* IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
* MONITORENTER, or MONITOREXIT. * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
* or MONITOREXIT.
*/ */
public void visitInsn(int opcode) { public void visitInsn(int opcode) {
if (mv != null) { if (mv != null) {
@@ -235,17 +281,20 @@ public abstract class MethodVisitor {
/** /**
* Visits an instruction with a single int operand. * Visits an instruction with a single int operand.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, * @param opcode
* SIPUSH or NEWARRAY. * the opcode of the instruction to be visited. This opcode is
* @param operand the operand of the instruction to be visited.<br> * either BIPUSH, SIPUSH or NEWARRAY.
* When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and * @param operand
* Byte.MAX_VALUE.<br> * the operand of the instruction to be visited.<br>
* When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and * When opcode is BIPUSH, operand value should be between
* Short.MAX_VALUE.<br> * Byte.MIN_VALUE and Byte.MAX_VALUE.<br>
* When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, * When opcode is SIPUSH, operand value should be between
* {@link Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, * Short.MIN_VALUE and Short.MAX_VALUE.<br>
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or * When opcode is NEWARRAY, operand value should be one of
* {@link Opcodes#T_LONG}. * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
* {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/ */
public void visitIntInsn(int opcode, int operand) { public void visitIntInsn(int opcode, int operand) {
if (mv != null) { if (mv != null) {
@@ -254,14 +303,16 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a local variable instruction. A local variable instruction is an instruction that * Visits a local variable instruction. A local variable instruction is an
* loads or stores the value of a local variable. * instruction that loads or stores the value of a local variable.
* *
* @param opcode the opcode of the local variable instruction to be visited. This opcode is * @param opcode
* either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or * the opcode of the local variable instruction to be visited.
* RET. * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
* @param var the operand of the instruction to be visited. This operand is the index of a local * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* variable. * @param var
* the operand of the instruction to be visited. This operand is
* the index of a local variable.
*/ */
public void visitVarInsn(int opcode, int var) { public void visitVarInsn(int opcode, int var) {
if (mv != null) { if (mv != null) {
@@ -270,13 +321,16 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a type instruction. A type instruction is an instruction that takes the internal name * Visits a type instruction. A type instruction is an instruction that
* of a class as parameter. * takes the internal name of a class as parameter.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either NEW, * @param opcode
* ANEWARRAY, CHECKCAST or INSTANCEOF. * the opcode of the type instruction to be visited. This opcode
* @param type the operand of the instruction to be visited. This operand must be the internal * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
* name of an object or array class (see {@link Type#getInternalName() getInternalName}). * @param type
* the operand of the instruction to be visited. This operand
* must be the internal name of an object or array class (see
* {@link Type#getInternalName() getInternalName}).
*/ */
public void visitTypeInsn(int opcode, String type) { public void visitTypeInsn(int opcode, String type) {
if (mv != null) { if (mv != null) {
@@ -285,33 +339,45 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a field instruction. A field instruction is an instruction that loads or stores the * Visits a field instruction. A field instruction is an instruction that
* value of a field of an object. * loads or stores the value of a field of an object.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either * @param opcode
* GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * the opcode of the type instruction to be visited. This opcode
* @param owner the internal name of the field's owner class (see {@link Type#getInternalName() * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* getInternalName}). * @param owner
* @param name the field's name. * the internal name of the field's owner class (see
* @param desc the field's descriptor (see {@link Type Type}). * {@link Type#getInternalName() getInternalName}).
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link Type Type}).
*/ */
public void visitFieldInsn(int opcode, String owner, String name, String desc) { public void visitFieldInsn(int opcode, String owner, String name,
String desc) {
if (mv != null) { if (mv != null) {
mv.visitFieldInsn(opcode, owner, name, desc); mv.visitFieldInsn(opcode, owner, name, desc);
} }
} }
/** /**
* Visits a method instruction. A method instruction is an instruction that invokes a method. * Visits a method instruction. A method instruction is an instruction that
* invokes a method.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either * @param opcode
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. * the opcode of the type instruction to be visited. This opcode
* @param owner the internal name of the method's owner class (see {@link Type#getInternalName() * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
* getInternalName}). * INVOKEINTERFACE.
* @param name the method's name. * @param owner
* @param desc the method's descriptor (see {@link Type Type}). * the internal name of the method's owner class (see
* {@link Type#getInternalName() getInternalName}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
*/ */
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name,
String desc) {
if (mv != null) { if (mv != null) {
mv.visitMethodInsn(opcode, owner, name, desc); mv.visitMethodInsn(opcode, owner, name, desc);
} }
@@ -320,29 +386,39 @@ public abstract class MethodVisitor {
/** /**
* Visits an invokedynamic instruction. * Visits an invokedynamic instruction.
* *
* @param name the method's name. * @param name
* @param desc the method's descriptor (see {@link Type Type}). * the method's name.
* @param bsm the bootstrap method. * @param desc
* @param bsmArgs the bootstrap method constant arguments. Each argument must be an * the method's descriptor (see {@link Type Type}).
* {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, * @param bsm
* {@link Type} or {@link Handle} value. This method is allowed to modify the content of * the bootstrap method.
* the array so a caller should expect that this array may change. * @param bsmArgs
* the bootstrap method constant arguments. Each argument must be
* an {@link Integer}, {@link Float}, {@link Long},
* {@link Double}, {@link String}, {@link Type} or {@link Handle}
* value. This method is allowed to modify the content of the
* array so a caller should expect that this array may change.
*/ */
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
if (mv != null) { if (mv != null) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
} }
} }
/** /**
* Visits a jump instruction. A jump instruction is an instruction that may jump to another * Visits a jump instruction. A jump instruction is an instruction that may
* instruction. * jump to another instruction.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ, * @param opcode
* IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, * the opcode of the type instruction to be visited. This opcode
* IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
* @param label the operand of the instruction to be visited. This operand is a label that * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* designates the instruction to which the jump instruction may jump. * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* @param label
* the operand of the instruction to be visited. This operand is
* a label that designates the instruction to which the jump
* instruction may jump.
*/ */
public void visitJumpInsn(int opcode, Label label) { public void visitJumpInsn(int opcode, Label label) {
if (mv != null) { if (mv != null) {
@@ -351,9 +427,11 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a label. A label designates the instruction that will be visited just after it. * Visits a label. A label designates the instruction that will be visited
* just after it.
* *
* @param label a {@link Label Label} object. * @param label
* a {@link Label Label} object.
*/ */
public void visitLabel(Label label) { public void visitLabel(Label label) {
if (mv != null) { if (mv != null) {
@@ -366,9 +444,10 @@ public abstract class MethodVisitor {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Visits a LDC instruction. Note that new constant types may be added in future versions of the * Visits a LDC instruction. Note that new constant types may be added in
* Java Virtual Machine. To easily detect new constant types, implementations of this method * future versions of the Java Virtual Machine. To easily detect new
* should check for unexpected constant types, like this: * constant types, implementations of this method should check for
* unexpected constant types, like this:
* *
* <pre> * <pre>
* if (cst instanceof Integer) { * if (cst instanceof Integer) {
@@ -399,11 +478,14 @@ public abstract class MethodVisitor {
* } * }
* </pre> * </pre>
* *
* @param cst the constant to be loaded on the stack. This parameter must be a non null * @param cst
* {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, * the constant to be loaded on the stack. This parameter must be
* a {@link Type} of OBJECT or ARRAY sort for <tt>.class</tt> constants, for classes * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
* whose version is 49.0, a {@link Type} of METHOD sort or a {@link Handle} for * {@link Double}, a {@link String}, a {@link Type} of OBJECT or
* MethodType and MethodHandle constants, for classes whose version is 51.0. * ARRAY sort for <tt>.class</tt> constants, for classes whose
* version is 49.0, a {@link Type} of METHOD sort or a
* {@link Handle} for MethodType and MethodHandle constants, for
* classes whose version is 51.0.
*/ */
public void visitLdcInsn(Object cst) { public void visitLdcInsn(Object cst) {
if (mv != null) { if (mv != null) {
@@ -414,8 +496,10 @@ public abstract class MethodVisitor {
/** /**
* Visits an IINC instruction. * Visits an IINC instruction.
* *
* @param var index of the local variable to be incremented. * @param var
* @param increment amount to increment the local variable by. * index of the local variable to be incremented.
* @param increment
* amount to increment the local variable by.
*/ */
public void visitIincInsn(int var, int increment) { public void visitIincInsn(int var, int increment) {
if (mv != null) { if (mv != null) {
@@ -426,13 +510,18 @@ public abstract class MethodVisitor {
/** /**
* Visits a TABLESWITCH instruction. * Visits a TABLESWITCH instruction.
* *
* @param min the minimum key value. * @param min
* @param max the maximum key value. * the minimum key value.
* @param dflt beginning of the default handler block. * @param max
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the * the maximum key value.
* handler block for the <tt>min + i</tt> key. * @param dflt
* beginning of the default handler block.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>min + i</tt> key.
*/ */
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { public void visitTableSwitchInsn(int min, int max, Label dflt,
Label... labels) {
if (mv != null) { if (mv != null) {
mv.visitTableSwitchInsn(min, max, dflt, labels); mv.visitTableSwitchInsn(min, max, dflt, labels);
} }
@@ -441,10 +530,13 @@ public abstract class MethodVisitor {
/** /**
* Visits a LOOKUPSWITCH instruction. * Visits a LOOKUPSWITCH instruction.
* *
* @param dflt beginning of the default handler block. * @param dflt
* @param keys the values of the keys. * beginning of the default handler block.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the * @param keys
* handler block for the <tt>keys[i]</tt> key. * the values of the keys.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>keys[i]</tt> key.
*/ */
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
if (mv != null) { if (mv != null) {
@@ -455,8 +547,10 @@ public abstract class MethodVisitor {
/** /**
* Visits a MULTIANEWARRAY instruction. * Visits a MULTIANEWARRAY instruction.
* *
* @param desc an array type descriptor (see {@link Type Type}). * @param desc
* @param dims number of dimensions of the array to allocate. * an array type descriptor (see {@link Type Type}).
* @param dims
* number of dimensions of the array to allocate.
*/ */
public void visitMultiANewArrayInsn(String desc, int dims) { public void visitMultiANewArrayInsn(String desc, int dims) {
if (mv != null) { if (mv != null) {
@@ -471,15 +565,22 @@ public abstract class MethodVisitor {
/** /**
* Visits a try catch block. * Visits a try catch block.
* *
* @param start beginning of the exception handler's scope (inclusive). * @param start
* @param end end of the exception handler's scope (exclusive). * beginning of the exception handler's scope (inclusive).
* @param handler beginning of the exception handler's code. * @param end
* @param type internal name of the type of exceptions handled by the handler, or <tt>null</tt> * end of the exception handler's scope (exclusive).
* to catch any exceptions (for "finally" blocks). * @param handler
* @throws IllegalArgumentException if one of the labels has already been visited by this * beginning of the exception handler's code.
* visitor (by the {@link #visitLabel visitLabel} method). * @param type
* internal name of the type of exceptions handled by the
* handler, or <tt>null</tt> to catch any exceptions (for
* "finally" blocks).
* @throws IllegalArgumentException
* if one of the labels has already been visited by this visitor
* (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { public void visitTryCatchBlock(Label start, Label end, Label handler,
String type) {
if (mv != null) { if (mv != null) {
mv.visitTryCatchBlock(start, end, handler, type); mv.visitTryCatchBlock(start, end, handler, type);
} }
@@ -488,20 +589,28 @@ public abstract class MethodVisitor {
/** /**
* Visits a local variable declaration. * Visits a local variable declaration.
* *
* @param name the name of a local variable. * @param name
* @param desc the type descriptor of this local variable. * the name of a local variable.
* @param signature the type signature of this local variable. May be <tt>null</tt> if the local * @param desc
* variable type does not use generic types. * the type descriptor of this local variable.
* @param start the first instruction corresponding to the scope of this local variable * @param signature
* (inclusive). * the type signature of this local variable. May be
* @param end the last instruction corresponding to the scope of this local variable * <tt>null</tt> if the local variable type does not use generic
* (exclusive). * types.
* @param index the local variable's index. * @param start
* @throws IllegalArgumentException if one of the labels has not already been visited by this * the first instruction corresponding to the scope of this local
* variable (inclusive).
* @param end
* the last instruction corresponding to the scope of this local
* variable (exclusive).
* @param index
* the local variable's index.
* @throws IllegalArgumentException
* if one of the labels has not already been visited by this
* visitor (by the {@link #visitLabel visitLabel} method). * visitor (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitLocalVariable(String name, String desc, String signature, Label start, public void visitLocalVariable(String name, String desc, String signature,
Label end, int index) { Label start, Label end, int index) {
if (mv != null) { if (mv != null) {
mv.visitLocalVariable(name, desc, signature, start, end, index); mv.visitLocalVariable(name, desc, signature, start, end, index);
} }
@@ -510,10 +619,13 @@ public abstract class MethodVisitor {
/** /**
* Visits a line number declaration. * Visits a line number declaration.
* *
* @param line a line number. This number refers to the source file from which the class was * @param line
* compiled. * a line number. This number refers to the source file from
* @param start the first instruction corresponding to this line number. * which the class was compiled.
* @throws IllegalArgumentException if <tt>start</tt> has not already been visited by this * @param start
* the first instruction corresponding to this line number.
* @throws IllegalArgumentException
* if <tt>start</tt> has not already been visited by this
* visitor (by the {@link #visitLabel visitLabel} method). * visitor (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitLineNumber(int line, Label start) { public void visitLineNumber(int line, Label start) {
@@ -523,10 +635,13 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the maximum stack size and the maximum number of local variables of the method. * Visits the maximum stack size and the maximum number of local variables
* of the method.
* *
* @param maxStack maximum stack size of the method. * @param maxStack
* @param maxLocals maximum number of local variables for the method. * maximum stack size of the method.
* @param maxLocals
* maximum number of local variables for the method.
*/ */
public void visitMaxs(int maxStack, int maxLocals) { public void visitMaxs(int maxStack, int maxLocals) {
if (mv != null) { if (mv != null) {
@@ -535,8 +650,9 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the end of the method. This method, which is the last one to be called, is used to * Visits the end of the method. This method, which is the last one to be
* inform the visitor that all the annotations and attributes of the method have been visited. * called, is used to inform the visitor that all the annotations and
* attributes of the method have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (mv != null) { if (mv != null) {

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +1,42 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
/** /**
* Defines the JVM opcodes, access flags and array type codes. This interface does not define all * Defines the JVM opcodes, access flags and array type codes. This interface
* the JVM opcodes because some opcodes are automatically handled. For example, the xLOAD and xSTORE * does not define all the JVM opcodes because some opcodes are automatically
* opcodes are automatically replaced by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and * handled. For example, the xLOAD and xSTORE opcodes are automatically replaced
* xSTORE_n opcodes are therefore not defined in this interface. Likewise for LDC, automatically * by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n
* replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and JSR_W. * opcodes are therefore not defined in this interface. Likewise for LDC,
* automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and
* JSR_W.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Eugene Kuleshov * @author Eugene Kuleshov
@@ -110,26 +120,28 @@ public interface Opcodes {
int F_FULL = 0; int F_FULL = 0;
/** /**
* Represents a compressed frame where locals are the same as the locals in the previous frame, * Represents a compressed frame where locals are the same as the locals in
* except that additional 1-3 locals are defined, and with an empty stack. * the previous frame, except that additional 1-3 locals are defined, and
* with an empty stack.
*/ */
int F_APPEND = 1; int F_APPEND = 1;
/** /**
* Represents a compressed frame where locals are the same as the locals in the previous frame, * Represents a compressed frame where locals are the same as the locals in
* except that the last 1-3 locals are absent and with an empty stack. * the previous frame, except that the last 1-3 locals are absent and with
* an empty stack.
*/ */
int F_CHOP = 2; int F_CHOP = 2;
/** /**
* Represents a compressed frame with exactly the same locals as the previous frame and with an * Represents a compressed frame with exactly the same locals as the
* empty stack. * previous frame and with an empty stack.
*/ */
int F_SAME = 3; int F_SAME = 3;
/** /**
* Represents a compressed frame with exactly the same locals as the previous frame and with a * Represents a compressed frame with exactly the same locals as the
* single value on the stack. * previous frame and with a single value on the stack.
*/ */
int F_SAME1 = 4; int F_SAME1 = 4;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm; package org.objectweb.asm;
@@ -25,8 +33,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/** /**
* A Java field or method type. This class can be used to make it easier to manipulate type and * A Java field or method type. This class can be used to make it easier to
* method descriptors. * manipulate type and method descriptors.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Chris Nokleberg * @author Chris Nokleberg
@@ -96,56 +104,56 @@ public class Type {
/** /**
* The <tt>void</tt> type. * The <tt>void</tt> type.
*/ */
public static final Type VOID_TYPE = public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24)
new Type(VOID, null, ('V' << 24) | (5 << 16) | (0 << 8) | 0, 1); | (5 << 16) | (0 << 8) | 0, 1);
/** /**
* The <tt>boolean</tt> type. * The <tt>boolean</tt> type.
*/ */
public static final Type BOOLEAN_TYPE = public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24)
new Type(BOOLEAN, null, ('Z' << 24) | (0 << 16) | (5 << 8) | 1, 1); | (0 << 16) | (5 << 8) | 1, 1);
/** /**
* The <tt>char</tt> type. * The <tt>char</tt> type.
*/ */
public static final Type CHAR_TYPE = public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24)
new Type(CHAR, null, ('C' << 24) | (0 << 16) | (6 << 8) | 1, 1); | (0 << 16) | (6 << 8) | 1, 1);
/** /**
* The <tt>byte</tt> type. * The <tt>byte</tt> type.
*/ */
public static final Type BYTE_TYPE = public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24)
new Type(BYTE, null, ('B' << 24) | (0 << 16) | (5 << 8) | 1, 1); | (0 << 16) | (5 << 8) | 1, 1);
/** /**
* The <tt>short</tt> type. * The <tt>short</tt> type.
*/ */
public static final Type SHORT_TYPE = public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24)
new Type(SHORT, null, ('S' << 24) | (0 << 16) | (7 << 8) | 1, 1); | (0 << 16) | (7 << 8) | 1, 1);
/** /**
* The <tt>int</tt> type. * The <tt>int</tt> type.
*/ */
public static final Type INT_TYPE = public static final Type INT_TYPE = new Type(INT, null, ('I' << 24)
new Type(INT, null, ('I' << 24) | (0 << 16) | (0 << 8) | 1, 1); | (0 << 16) | (0 << 8) | 1, 1);
/** /**
* The <tt>float</tt> type. * The <tt>float</tt> type.
*/ */
public static final Type FLOAT_TYPE = public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24)
new Type(FLOAT, null, ('F' << 24) | (2 << 16) | (2 << 8) | 1, 1); | (2 << 16) | (2 << 8) | 1, 1);
/** /**
* The <tt>long</tt> type. * The <tt>long</tt> type.
*/ */
public static final Type LONG_TYPE = public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24)
new Type(LONG, null, ('J' << 24) | (1 << 16) | (1 << 8) | 2, 1); | (1 << 16) | (1 << 8) | 2, 1);
/** /**
* The <tt>double</tt> type. * The <tt>double</tt> type.
*/ */
public static final Type DOUBLE_TYPE = public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24)
new Type(DOUBLE, null, ('D' << 24) | (3 << 16) | (3 << 8) | 2, 1); | (3 << 16) | (3 << 8) | 2, 1);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Fields // Fields
@@ -157,16 +165,16 @@ public class Type {
private final int sort; private final int sort;
/** /**
* A buffer containing the internal name of this Java type. This field is only used for * A buffer containing the internal name of this Java type. This field is
* reference types. * only used for reference types.
*/ */
private final char[] buf; private final char[] buf;
/** /**
* The offset of the internal name of this Java type in {@link #buf buf} or, for primitive * The offset of the internal name of this Java type in {@link #buf buf} or,
* types, the size, descriptor and getOpcode offsets for this type (byte 0 contains the size, * for primitive types, the size, descriptor and getOpcode offsets for this
* byte 1 the descriptor, byte 2 the offset for IALOAD or IASTORE, byte 3 the offset for all * type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset
* other instructions). * for IALOAD or IASTORE, byte 3 the offset for all other instructions).
*/ */
private final int off; private final int off;
@@ -182,10 +190,14 @@ public class Type {
/** /**
* Constructs a reference type. * Constructs a reference type.
* *
* @param sort the sort of the reference type to be constructed. * @param sort
* @param buf a buffer containing the descriptor of the previous type. * the sort of the reference type to be constructed.
* @param off the offset of this descriptor in the previous buffer. * @param buf
* @param len the length of this descriptor. * a buffer containing the descriptor of the previous type.
* @param off
* the offset of this descriptor in the previous buffer.
* @param len
* the length of this descriptor.
*/ */
private Type(final int sort, final char[] buf, final int off, final int len) { private Type(final int sort, final char[] buf, final int off, final int len) {
this.sort = sort; this.sort = sort;
@@ -197,7 +209,8 @@ public class Type {
/** /**
* Returns the Java type corresponding to the given type descriptor. * Returns the Java type corresponding to the given type descriptor.
* *
* @param typeDescriptor a field or method type descriptor. * @param typeDescriptor
* a field or method type descriptor.
* @return the Java type corresponding to the given type descriptor. * @return the Java type corresponding to the given type descriptor.
*/ */
public static Type getType(final String typeDescriptor) { public static Type getType(final String typeDescriptor) {
@@ -207,7 +220,8 @@ public class Type {
/** /**
* Returns the Java type corresponding to the given internal name. * Returns the Java type corresponding to the given internal name.
* *
* @param internalName an internal name. * @param internalName
* an internal name.
* @return the Java type corresponding to the given internal name. * @return the Java type corresponding to the given internal name.
*/ */
public static Type getObjectType(final String internalName) { public static Type getObjectType(final String internalName) {
@@ -216,10 +230,11 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the given method descriptor. Equivalent to * Returns the Java type corresponding to the given method descriptor.
* <code>Type.getType(methodDescriptor)</code>. * Equivalent to <code>Type.getType(methodDescriptor)</code>.
* *
* @param methodDescriptor a method descriptor. * @param methodDescriptor
* a method descriptor.
* @return the Java type corresponding to the given method descriptor. * @return the Java type corresponding to the given method descriptor.
*/ */
public static Type getMethodType(final String methodDescriptor) { public static Type getMethodType(final String methodDescriptor) {
@@ -227,20 +242,26 @@ public class Type {
} }
/** /**
* Returns the Java method type corresponding to the given argument and return types. * Returns the Java method type corresponding to the given argument and
* return types.
* *
* @param returnType the return type of the method. * @param returnType
* @param argumentTypes the argument types of the method. * the return type of the method.
* @return the Java type corresponding to the given argument and return types. * @param argumentTypes
* the argument types of the method.
* @return the Java type corresponding to the given argument and return
* types.
*/ */
public static Type getMethodType(final Type returnType, final Type... argumentTypes) { public static Type getMethodType(final Type returnType,
final Type... argumentTypes) {
return getType(getMethodDescriptor(returnType, argumentTypes)); return getType(getMethodDescriptor(returnType, argumentTypes));
} }
/** /**
* Returns the Java type corresponding to the given class. * Returns the Java type corresponding to the given class.
* *
* @param c a class. * @param c
* a class.
* @return the Java type corresponding to the given class. * @return the Java type corresponding to the given class.
*/ */
public static Type getType(final Class<?> c) { public static Type getType(final Class<?> c) {
@@ -261,7 +282,7 @@ public class Type {
return DOUBLE_TYPE; return DOUBLE_TYPE;
} else if (c == Float.TYPE) { } else if (c == Float.TYPE) {
return FLOAT_TYPE; return FLOAT_TYPE;
} else /* if (c == Long.TYPE) */ { } else /* if (c == Long.TYPE) */{
return LONG_TYPE; return LONG_TYPE;
} }
} else { } else {
@@ -272,7 +293,8 @@ public class Type {
/** /**
* Returns the Java method type corresponding to the given constructor. * Returns the Java method type corresponding to the given constructor.
* *
* @param c a {@link Constructor Constructor} object. * @param c
* a {@link Constructor Constructor} object.
* @return the Java method type corresponding to the given constructor. * @return the Java method type corresponding to the given constructor.
*/ */
public static Type getType(final Constructor<?> c) { public static Type getType(final Constructor<?> c) {
@@ -282,7 +304,8 @@ public class Type {
/** /**
* Returns the Java method type corresponding to the given method. * Returns the Java method type corresponding to the given method.
* *
* @param m a {@link Method Method} object. * @param m
* a {@link Method Method} object.
* @return the Java method type corresponding to the given method. * @return the Java method type corresponding to the given method.
*/ */
public static Type getType(final Method m) { public static Type getType(final Method m) {
@@ -290,10 +313,13 @@ public class Type {
} }
/** /**
* Returns the Java types corresponding to the argument types of the given method descriptor. * Returns the Java types corresponding to the argument types of the given
* method descriptor.
* *
* @param methodDescriptor a method descriptor. * @param methodDescriptor
* @return the Java types corresponding to the argument types of the given method descriptor. * a method descriptor.
* @return the Java types corresponding to the argument types of the given
* method descriptor.
*/ */
public static Type[] getArgumentTypes(final String methodDescriptor) { public static Type[] getArgumentTypes(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray(); char[] buf = methodDescriptor.toCharArray();
@@ -323,10 +349,13 @@ public class Type {
} }
/** /**
* Returns the Java types corresponding to the argument types of the given method. * Returns the Java types corresponding to the argument types of the given
* method.
* *
* @param method a method. * @param method
* @return the Java types corresponding to the argument types of the given method. * a method.
* @return the Java types corresponding to the argument types of the given
* method.
*/ */
public static Type[] getArgumentTypes(final Method method) { public static Type[] getArgumentTypes(final Method method) {
Class<?>[] classes = method.getParameterTypes(); Class<?>[] classes = method.getParameterTypes();
@@ -338,10 +367,13 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the return type of the given method descriptor. * Returns the Java type corresponding to the return type of the given
* method descriptor.
* *
* @param methodDescriptor a method descriptor. * @param methodDescriptor
* @return the Java type corresponding to the return type of the given method descriptor. * a method descriptor.
* @return the Java type corresponding to the return type of the given
* method descriptor.
*/ */
public static Type getReturnType(final String methodDescriptor) { public static Type getReturnType(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray(); char[] buf = methodDescriptor.toCharArray();
@@ -349,10 +381,13 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the return type of the given method. * Returns the Java type corresponding to the return type of the given
* method.
* *
* @param method a method. * @param method
* @return the Java type corresponding to the return type of the given method. * a method.
* @return the Java type corresponding to the return type of the given
* method.
*/ */
public static Type getReturnType(final Method method) { public static Type getReturnType(final Method method) {
return getType(method.getReturnType()); return getType(method.getReturnType());
@@ -361,11 +396,13 @@ public class Type {
/** /**
* Computes the size of the arguments and of the return value of a method. * Computes the size of the arguments and of the return value of a method.
* *
* @param desc the descriptor of a method. * @param desc
* @return the size of the arguments of the method (plus one for the implicit this argument), * the descriptor of a method.
* argSize, and the size of its return value, retSize, packed into a single int i = * @return the size of the arguments of the method (plus one for the
* <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to <tt>i >> 2</tt>, and * implicit this argument), argSize, and the size of its return
* retSize to <tt>i & 0x03</tt>). * value, retSize, packed into a single int i =
* <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to
* <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
*/ */
public static int getArgumentsAndReturnSizes(final String desc) { public static int getArgumentsAndReturnSizes(final String desc) {
int n = 1; int n = 1;
@@ -374,7 +411,8 @@ public class Type {
char car = desc.charAt(c++); char car = desc.charAt(c++);
if (car == ')') { if (car == ')') {
car = desc.charAt(c); car = desc.charAt(c);
return n << 2 | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1)); return n << 2
| (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
} else if (car == 'L') { } else if (car == 'L') {
while (desc.charAt(c++) != ';') { while (desc.charAt(c++) != ';') {
} }
@@ -395,11 +433,14 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the given type descriptor. For method descriptors, buf * Returns the Java type corresponding to the given type descriptor. For
* is supposed to contain nothing more than the descriptor itself. * method descriptors, buf is supposed to contain nothing more than the
* descriptor itself.
* *
* @param buf a buffer containing a type descriptor. * @param buf
* @param off the offset of this descriptor in the previous buffer. * a buffer containing a type descriptor.
* @param off
* the offset of this descriptor in the previous buffer.
* @return the Java type corresponding to the given type descriptor. * @return the Java type corresponding to the given type descriptor.
*/ */
private static Type getType(final char[] buf, final int off) { private static Type getType(final char[] buf, final int off) {
@@ -454,18 +495,19 @@ public class Type {
/** /**
* Returns the sort of this Java type. * Returns the sort of this Java type.
* *
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, {@link #BYTE BYTE}, * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR},
* {@link #SHORT SHORT}, {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG}, * {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT},
* {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or * {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE},
* {@link #METHOD METHOD}. * {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD
* METHOD}.
*/ */
public int getSort() { public int getSort() {
return sort; return sort;
} }
/** /**
* Returns the number of dimensions of this array type. This method should only be used for an * Returns the number of dimensions of this array type. This method should
* array type. * only be used for an array type.
* *
* @return the number of dimensions of this array type. * @return the number of dimensions of this array type.
*/ */
@@ -478,8 +520,8 @@ public class Type {
} }
/** /**
* Returns the type of the elements of this array type. This method should only be used for an * Returns the type of the elements of this array type. This method should
* array type. * only be used for an array type.
* *
* @return Returns the type of the elements of this array type. * @return Returns the type of the elements of this array type.
*/ */
@@ -488,8 +530,8 @@ public class Type {
} }
/** /**
* Returns the binary name of the class corresponding to this type. This method must not be used * Returns the binary name of the class corresponding to this type. This
* on method types. * method must not be used on method types.
* *
* @return the binary name of the class corresponding to this type. * @return the binary name of the class corresponding to this type.
*/ */
@@ -527,9 +569,10 @@ public class Type {
} }
/** /**
* Returns the internal name of the class corresponding to this object or array type. The * Returns the internal name of the class corresponding to this object or
* internal name of a class is its fully qualified name (as returned by Class.getName(), where * array type. The internal name of a class is its fully qualified name (as
* '.' are replaced by '/'. This method should only be used for an object or array type. * returned by Class.getName(), where '.' are replaced by '/'. This method
* should only be used for an object or array type.
* *
* @return the internal name of the class corresponding to this object type. * @return the internal name of the class corresponding to this object type.
*/ */
@@ -538,8 +581,8 @@ public class Type {
} }
/** /**
* Returns the argument types of methods of this type. This method should only be used for * Returns the argument types of methods of this type. This method should
* method types. * only be used for method types.
* *
* @return the argument types of methods of this type. * @return the argument types of methods of this type.
*/ */
@@ -548,8 +591,8 @@ public class Type {
} }
/** /**
* Returns the return type of methods of this type. This method should only be used for method * Returns the return type of methods of this type. This method should only
* types. * be used for method types.
* *
* @return the return type of methods of this type. * @return the return type of methods of this type.
*/ */
@@ -558,13 +601,14 @@ public class Type {
} }
/** /**
* Returns the size of the arguments and of the return value of methods of this type. This * Returns the size of the arguments and of the return value of methods of
* method should only be used for method types. * this type. This method should only be used for method types.
* *
* @return the size of the arguments (plus one for the implicit this argument), argSize, and the * @return the size of the arguments (plus one for the implicit this
* size of the return value, retSize, packed into a single int i = * argument), argSize, and the size of the return value, retSize,
* <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to <tt>i >> 2</tt>, and * packed into a single int i = <tt>(argSize << 2) | retSize</tt>
* retSize to <tt>i & 0x03</tt>). * (argSize is therefore equal to <tt>i >> 2</tt>, and retSize to
* <tt>i & 0x03</tt>).
*/ */
public int getArgumentsAndReturnSizes() { public int getArgumentsAndReturnSizes() {
return getArgumentsAndReturnSizes(getDescriptor()); return getArgumentsAndReturnSizes(getDescriptor());
@@ -586,13 +630,18 @@ public class Type {
} }
/** /**
* Returns the descriptor corresponding to the given argument and return types. * Returns the descriptor corresponding to the given argument and return
* types.
* *
* @param returnType the return type of the method. * @param returnType
* @param argumentTypes the argument types of the method. * the return type of the method.
* @return the descriptor corresponding to the given argument and return types. * @param argumentTypes
* the argument types of the method.
* @return the descriptor corresponding to the given argument and return
* types.
*/ */
public static String getMethodDescriptor(final Type returnType, final Type... argumentTypes) { public static String getMethodDescriptor(final Type returnType,
final Type... argumentTypes) {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
buf.append('('); buf.append('(');
for (int i = 0; i < argumentTypes.length; ++i) { for (int i = 0; i < argumentTypes.length; ++i) {
@@ -604,9 +653,11 @@ public class Type {
} }
/** /**
* Appends the descriptor corresponding to this Java type to the given string buffer. * Appends the descriptor corresponding to this Java type to the given
* string buffer.
* *
* @param buf the string buffer to which the descriptor must be appended. * @param buf
* the string buffer to which the descriptor must be appended.
*/ */
private void getDescriptor(final StringBuffer buf) { private void getDescriptor(final StringBuffer buf) {
if (this.buf == null) { if (this.buf == null) {
@@ -628,10 +679,12 @@ public class Type {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the internal name of the given class. The internal name of a class is its fully * Returns the internal name of the given class. The internal name of a
* qualified name, as returned by Class.getName(), where '.' are replaced by '/'. * class is its fully qualified name, as returned by Class.getName(), where
* '.' are replaced by '/'.
* *
* @param c an object or array class. * @param c
* an object or array class.
* @return the internal name of the given class. * @return the internal name of the given class.
*/ */
public static String getInternalName(final Class<?> c) { public static String getInternalName(final Class<?> c) {
@@ -641,7 +694,8 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given Java type. * Returns the descriptor corresponding to the given Java type.
* *
* @param c an object class, a primitive class or an array class. * @param c
* an object class, a primitive class or an array class.
* @return the descriptor corresponding to the given class. * @return the descriptor corresponding to the given class.
*/ */
public static String getDescriptor(final Class<?> c) { public static String getDescriptor(final Class<?> c) {
@@ -653,7 +707,8 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given constructor. * Returns the descriptor corresponding to the given constructor.
* *
* @param c a {@link Constructor Constructor} object. * @param c
* a {@link Constructor Constructor} object.
* @return the descriptor of the given constructor. * @return the descriptor of the given constructor.
*/ */
public static String getConstructorDescriptor(final Constructor<?> c) { public static String getConstructorDescriptor(final Constructor<?> c) {
@@ -669,7 +724,8 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given method. * Returns the descriptor corresponding to the given method.
* *
* @param m a {@link Method Method} object. * @param m
* a {@link Method Method} object.
* @return the descriptor of the given method. * @return the descriptor of the given method.
*/ */
public static String getMethodDescriptor(final Method m) { public static String getMethodDescriptor(final Method m) {
@@ -687,8 +743,10 @@ public class Type {
/** /**
* Appends the descriptor of the given class to the given string buffer. * Appends the descriptor of the given class to the given string buffer.
* *
* @param buf the string buffer to which the descriptor must be appended. * @param buf
* @param c the class whose descriptor must be computed. * the string buffer to which the descriptor must be appended.
* @param c
* the class whose descriptor must be computed.
*/ */
private static void getDescriptor(final StringBuffer buf, final Class<?> c) { private static void getDescriptor(final StringBuffer buf, final Class<?> c) {
Class<?> d = c; Class<?> d = c;
@@ -711,7 +769,7 @@ public class Type {
car = 'D'; car = 'D';
} else if (d == Float.TYPE) { } else if (d == Float.TYPE) {
car = 'F'; car = 'F';
} else /* if (d == Long.TYPE) */ { } else /* if (d == Long.TYPE) */{
car = 'J'; car = 'J';
} }
buf.append(car); buf.append(car);
@@ -738,10 +796,11 @@ public class Type {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the size of values of this type. This method must not be used for method types. * Returns the size of values of this type. This method must not be used for
* method types.
* *
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and <tt>double</tt>, 0 for * @return the size of values of this type, i.e., 2 for <tt>long</tt> and
* <tt>void</tt> and 1 otherwise. * <tt>double</tt>, 0 for <tt>void</tt> and 1 otherwise.
*/ */
public int getSize() { public int getSize() {
// the size is in byte 0 of 'off' for primitive types (buf == null) // the size is in byte 0 of 'off' for primitive types (buf == null)
@@ -749,15 +808,16 @@ public class Type {
} }
/** /**
* Returns a JVM instruction opcode adapted to this Java type. This method must not be used for * Returns a JVM instruction opcode adapted to this Java type. This method
* method types. * must not be used for method types.
* *
* @param opcode a JVM instruction opcode. This opcode must be one of ILOAD, ISTORE, IALOAD, * @param opcode
* IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL, ISHR, IUSHR, IAND, IOR, IXOR and * a JVM instruction opcode. This opcode must be one of ILOAD,
* IRETURN. * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG,
* @return an opcode that is similar to the given opcode, but adapted to this Java type. For * ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
* example, if this type is <tt>float</tt> and <tt>opcode</tt> is IRETURN, this method * @return an opcode that is similar to the given opcode, but adapted to
* returns FRETURN. * this Java type. For example, if this type is <tt>float</tt> and
* <tt>opcode</tt> is IRETURN, this method returns FRETURN.
*/ */
public int getOpcode(final int opcode) { public int getOpcode(final int opcode) {
if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) { if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
@@ -778,7 +838,8 @@ public class Type {
/** /**
* Tests if the given object is equal to this type. * Tests if the given object is equal to this type.
* *
* @param o the object to be compared to this type. * @param o
* the object to be compared to this type.
* @return <tt>true</tt> if the given object is equal to this type. * @return <tt>true</tt> if the given object is equal to this type.
*/ */
@Override @Override

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -33,17 +41,17 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
/** /**
* A {@link org.objectweb.asm.MethodVisitor} to insert before, after and around advices in methods * A {@link org.objectweb.asm.MethodVisitor} to insert before, after and around
* and constructors. * advices in methods and constructors.
* <p> * <p>
* The behavior for constructors is like this: * The behavior for constructors is like this:
* <ol> * <ol>
* *
* <li>as long as the INVOKESPECIAL for the object initialization has not been reached, every * <li>as long as the INVOKESPECIAL for the object initialization has not been
* bytecode instruction is dispatched in the ctor code visitor</li> * reached, every bytecode instruction is dispatched in the ctor code visitor</li>
* *
* <li>when this one is reached, it is only added in the ctor code visitor and a JP invoke is * <li>when this one is reached, it is only added in the ctor code visitor and a
* added</li> * JP invoke is added</li>
* *
* <li>after that, only the other code visitor receives the instructions</li> * <li>after that, only the other code visitor receives the instructions</li>
* *
@@ -73,15 +81,20 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
/** /**
* Creates a new {@link AdviceAdapter}. * Creates a new {@link AdviceAdapter}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param mv the method visitor to which this adapter delegates calls. * of {@link Opcodes#ASM4}.
* @param access the method's access flags (see {@link Opcodes}). * @param mv
* @param name the method's name. * the method visitor to which this adapter delegates calls.
* @param desc the method's descriptor (see {@link Type Type}). * @param access
* the method's access flags (see {@link Opcodes}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
*/ */
protected AdviceAdapter(final int api, final MethodVisitor mv, final int access, protected AdviceAdapter(final int api, final MethodVisitor mv,
final String name, final String desc) { final int access, final String name, final String desc) {
super(api, mv, access, name, desc); super(api, mv, access, name, desc);
methodAccess = access; methodAccess = access;
methodDesc = desc; methodDesc = desc;
@@ -326,8 +339,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitFieldInsn(final int opcode, final String owner, final String name, public void visitFieldInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
mv.visitFieldInsn(opcode, owner, name, desc); mv.visitFieldInsn(opcode, owner, name, desc);
if (constructor) { if (constructor) {
char c = desc.charAt(0); char c = desc.charAt(0);
@@ -401,8 +414,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, final String name, public void visitMethodInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
mv.visitMethodInsn(opcode, owner, name, desc); mv.visitMethodInsn(opcode, owner, name, desc);
if (constructor) { if (constructor) {
Type[] types = Type.getArgumentTypes(desc); Type[] types = Type.getArgumentTypes(desc);
@@ -442,7 +455,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
if (constructor) { if (constructor) {
Type[] types = Type.getArgumentTypes(desc); Type[] types = Type.getArgumentTypes(desc);
@@ -498,7 +512,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
final Label[] labels) {
mv.visitLookupSwitchInsn(dflt, keys, labels); mv.visitLookupSwitchInsn(dflt, keys, labels);
if (constructor) { if (constructor) {
popValue(); popValue();
@@ -507,8 +522,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitTableSwitchInsn(final int min, final int max, final Label dflt, public void visitTableSwitchInsn(final int min, final int max,
final Label... labels) { final Label dflt, final Label... labels) {
mv.visitTableSwitchInsn(min, max, dflt, labels); mv.visitTableSwitchInsn(min, max, dflt, labels);
if (constructor) { if (constructor) {
popValue(); popValue();
@@ -517,7 +532,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { public void visitTryCatchBlock(Label start, Label end, Label handler,
String type) {
super.visitTryCatchBlock(start, end, handler, type); super.visitTryCatchBlock(start, end, handler, type);
if (constructor && !branches.containsKey(handler)) { if (constructor && !branches.containsKey(handler)) {
List<Object> stackFrame = new ArrayList<Object>(); List<Object> stackFrame = new ArrayList<Object>();
@@ -553,18 +569,20 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
/** /**
* Called at the beginning of the method or after super class class call in the constructor. * Called at the beginning of the method or after super class class call in
* <br> * the constructor. <br>
* <br> * <br>
* *
* <i>Custom code can use or change all the local variables, but should not change state of the * <i>Custom code can use or change all the local variables, but should not
* stack.</i> * change state of the stack.</i>
*/ */
protected void onMethodEnter() {} protected void onMethodEnter() {
}
/** /**
* Called before explicit exit from the method using either return or throw. Top element on the * Called before explicit exit from the method using either return or throw.
* stack contains the return value or exception instance. For example: * Top element on the stack contains the return value or exception instance.
* For example:
* *
* <pre> * <pre>
* public void onMethodExit(int opcode) { * public void onMethodExit(int opcode) {
@@ -592,13 +610,16 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
* <br> * <br>
* <br> * <br>
* *
* <i>Custom code can use or change all the local variables, but should not change state of the * <i>Custom code can use or change all the local variables, but should not
* stack.</i> * change state of the stack.</i>
* *
* @param opcode one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN, DRETURN or ATHROW * @param opcode
* one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN, DRETURN
* or ATHROW
* *
*/ */
protected void onMethodExit(int opcode) {} protected void onMethodExit(int opcode) {
}
// TODO onException, onMethodCall // TODO onException, onMethodCall
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -34,55 +42,65 @@ import org.objectweb.asm.Type;
/** /**
* A {@link MethodVisitor} that keeps track of stack map frame changes between * A {@link MethodVisitor} that keeps track of stack map frame changes between
* {@link #visitFrame(int, int, Object[], int, Object[]) visitFrame} calls. This adapter must be * {@link #visitFrame(int, int, Object[], int, Object[]) visitFrame} calls. This
* used with the {@link org.objectweb.asm.ClassReader#EXPAND_FRAMES} option. Each visit<i>X</i> * adapter must be used with the
* instruction delegates to the next visitor in the chain, if any, and then simulates the effect of * {@link org.objectweb.asm.ClassReader#EXPAND_FRAMES} option. Each
* this instruction on the stack map frame, represented by {@link #locals} and {@link #stack}. The * visit<i>X</i> instruction delegates to the next visitor in the chain, if any,
* next visitor in the chain can get the state of the stack map frame <i>before</i> each instruction * and then simulates the effect of this instruction on the stack map frame,
* by reading the value of these fields in its visit<i>X</i> methods (this requires a reference to * represented by {@link #locals} and {@link #stack}. The next visitor in the
* the AnalyzerAdapter that is before it in the chain). If this adapter is used with a class that * chain can get the state of the stack map frame <i>before</i> each instruction
* does not contain stack map table attributes (i.e., pre Java 6 classes) then this adapter may not * by reading the value of these fields in its visit<i>X</i> methods (this
* be able to compute the stack map frame for each instruction. In this case no exception is thrown * requires a reference to the AnalyzerAdapter that is before it in the chain).
* but the {@link #locals} and {@link #stack} fields will be null for these instructions. * If this adapter is used with a class that does not contain stack map table
* attributes (i.e., pre Java 6 classes) then this adapter may not be able to
* compute the stack map frame for each instruction. In this case no exception
* is thrown but the {@link #locals} and {@link #stack} fields will be null for
* these instructions.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class AnalyzerAdapter extends MethodVisitor { public class AnalyzerAdapter extends MethodVisitor {
/** /**
* <code>List</code> of the local variable slots for current execution frame. Primitive types * <code>List</code> of the local variable slots for current execution
* are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, * frame. Primitive types are represented by {@link Opcodes#TOP},
* {@link Opcodes#LONG}, {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by two elements, the * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
* second one being TOP). Reference types are represented by String objects (representing * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by
* internal names), and uninitialized types by Label objects (this label designates the NEW * two elements, the second one being TOP). Reference types are represented
* instruction that created this uninitialized value). This field is <tt>null</tt> for * by String objects (representing internal names), and uninitialized types
* unreachable instructions. * by Label objects (this label designates the NEW instruction that created
* this uninitialized value). This field is <tt>null</tt> for unreachable
* instructions.
*/ */
public List<Object> locals; public List<Object> locals;
/** /**
* <code>List</code> of the operand stack slots for current execution frame. Primitive types are * <code>List</code> of the operand stack slots for current execution frame.
* represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, * Primitive types are represented by {@link Opcodes#TOP},
* {@link Opcodes#LONG}, {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by two elements, the * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
* second one being TOP). Reference types are represented by String objects (representing * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by
* internal names), and uninitialized types by Label objects (this label designates the NEW * two elements, the second one being TOP). Reference types are represented
* instruction that created this uninitialized value). This field is <tt>null</tt> for * by String objects (representing internal names), and uninitialized types
* unreachable instructions. * by Label objects (this label designates the NEW instruction that created
* this uninitialized value). This field is <tt>null</tt> for unreachable
* instructions.
*/ */
public List<Object> stack; public List<Object> stack;
/** /**
* The labels that designate the next instruction to be visited. May be <tt>null</tt>. * The labels that designate the next instruction to be visited. May be
* <tt>null</tt>.
*/ */
private List<Label> labels; private List<Label> labels;
/** /**
* Information about uninitialized types in the current execution frame. This map associates * Information about uninitialized types in the current execution frame.
* internal names to Label objects. Each label designates a NEW instruction that created the * This map associates internal names to Label objects. Each label
* currently uninitialized types, and the associated internal name represents the NEW operand, * designates a NEW instruction that created the currently uninitialized
* i.e. the final, initialized type value. * types, and the associated internal name represents the NEW operand, i.e.
* the final, initialized type value.
*/ */
public Map<Object, Object> uninitializedTypes; public Map<Object, Object> uninitializedTypes;
@@ -102,34 +120,49 @@ public class AnalyzerAdapter extends MethodVisitor {
private String owner; private String owner;
/** /**
* Creates a new {@link AnalyzerAdapter}. <i>Subclasses must not use this constructor</i>. * Creates a new {@link AnalyzerAdapter}. <i>Subclasses must not use this
* Instead, they must use the * constructor</i>. Instead, they must use the
* {@link #AnalyzerAdapter(int, String, int, String, String, MethodVisitor)} version. * {@link #AnalyzerAdapter(int, String, int, String, String, MethodVisitor)}
* version.
* *
* @param owner the owner's class name. * @param owner
* @param access the method's access flags (see {@link Opcodes}). * the owner's class name.
* @param name the method's name. * @param access
* @param desc the method's descriptor (see {@link Type Type}). * the method's access flags (see {@link Opcodes}).
* @param mv the method visitor to which this adapter delegates calls. May be <tt>null</tt>. * @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
* @param mv
* the method visitor to which this adapter delegates calls. May
* be <tt>null</tt>.
*/ */
public AnalyzerAdapter(final String owner, final int access, final String name, public AnalyzerAdapter(final String owner, final int access,
final String desc, final MethodVisitor mv) { final String name, final String desc, final MethodVisitor mv) {
this(Opcodes.ASM4, owner, access, name, desc, mv); this(Opcodes.ASM4, owner, access, name, desc, mv);
} }
/** /**
* Creates a new {@link AnalyzerAdapter}. * Creates a new {@link AnalyzerAdapter}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param owner the owner's class name. * of {@link Opcodes#ASM4}.
* @param access the method's access flags (see {@link Opcodes}). * @param owner
* @param name the method's name. * the owner's class name.
* @param desc the method's descriptor (see {@link Type Type}). * @param access
* @param mv the method visitor to which this adapter delegates calls. May be <tt>null</tt>. * the method's access flags (see {@link Opcodes}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
* @param mv
* the method visitor to which this adapter delegates calls. May
* be <tt>null</tt>.
*/ */
protected AnalyzerAdapter(final int api, final String owner, final int access, protected AnalyzerAdapter(final int api, final String owner,
final String name, final String desc, final MethodVisitor mv) { final int access, final String name, final String desc,
final MethodVisitor mv) {
super(api, mv); super(api, mv);
this.owner = owner; this.owner = owner;
locals = new ArrayList<Object>(); locals = new ArrayList<Object>();
@@ -176,8 +209,8 @@ public class AnalyzerAdapter extends MethodVisitor {
} }
@Override @Override
public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, public void visitFrame(final int type, final int nLocal,
final Object[] stack) { final Object[] local, final int nStack, final Object[] stack) {
if (type != Opcodes.F_NEW) { // uncompressed frame if (type != Opcodes.F_NEW) { // uncompressed frame
throw new IllegalStateException( throw new IllegalStateException(
"ClassReader.accept() should be called with EXPAND_FRAMES flag"); "ClassReader.accept() should be called with EXPAND_FRAMES flag");
@@ -216,7 +249,8 @@ public class AnalyzerAdapter extends MethodVisitor {
mv.visitInsn(opcode); mv.visitInsn(opcode);
} }
execute(opcode, 0, null); execute(opcode, 0, null);
if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) { if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
|| opcode == Opcodes.ATHROW) {
this.locals = null; this.locals = null;
this.stack = null; this.stack = null;
} }
@@ -260,8 +294,8 @@ public class AnalyzerAdapter extends MethodVisitor {
} }
@Override @Override
public void visitFieldInsn(final int opcode, final String owner, final String name, public void visitFieldInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
if (mv != null) { if (mv != null) {
mv.visitFieldInsn(opcode, owner, name, desc); mv.visitFieldInsn(opcode, owner, name, desc);
} }
@@ -269,8 +303,8 @@ public class AnalyzerAdapter extends MethodVisitor {
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, final String name, public void visitMethodInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
if (mv != null) { if (mv != null) {
mv.visitMethodInsn(opcode, owner, name, desc); mv.visitMethodInsn(opcode, owner, name, desc);
} }
@@ -305,7 +339,8 @@ public class AnalyzerAdapter extends MethodVisitor {
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
if (mv != null) { if (mv != null) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
} }
@@ -388,8 +423,8 @@ public class AnalyzerAdapter extends MethodVisitor {
} }
@Override @Override
public void visitTableSwitchInsn(final int min, final int max, final Label dflt, public void visitTableSwitchInsn(final int min, final int max,
final Label... labels) { final Label dflt, final Label... labels) {
if (mv != null) { if (mv != null) {
mv.visitTableSwitchInsn(min, max, dflt, labels); mv.visitTableSwitchInsn(min, max, dflt, labels);
} }
@@ -399,7 +434,8 @@ public class AnalyzerAdapter extends MethodVisitor {
} }
@Override @Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
final Label[] labels) {
if (mv != null) { if (mv != null) {
mv.visitLookupSwitchInsn(dflt, keys, labels); mv.visitLookupSwitchInsn(dflt, keys, labels);
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -103,8 +111,8 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitFieldInsn(final int opcode, final String owner, final String name, public void visitFieldInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
minSize += 3; minSize += 3;
maxSize += 3; maxSize += 3;
if (mv != null) { if (mv != null) {
@@ -113,8 +121,8 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, final String name, public void visitMethodInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
if (opcode == INVOKEINTERFACE) { if (opcode == INVOKEINTERFACE) {
minSize += 5; minSize += 5;
maxSize += 5; maxSize += 5;
@@ -128,7 +136,8 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
minSize += 5; minSize += 5;
maxSize += 5; maxSize += 5;
if (mv != null) { if (mv != null) {
@@ -178,8 +187,8 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitTableSwitchInsn(final int min, final int max, final Label dflt, public void visitTableSwitchInsn(final int min, final int max,
final Label... labels) { final Label dflt, final Label... labels) {
minSize += 13 + labels.length * 4; minSize += 13 + labels.length * 4;
maxSize += 16 + labels.length * 4; maxSize += 16 + labels.length * 4;
if (mv != null) { if (mv != null) {
@@ -188,7 +197,8 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
final Label[] labels) {
minSize += 9 + keys.length * 8; minSize += 9 + keys.length * 8;
maxSize += 12 + keys.length * 8; maxSize += 12 + keys.length * 8;
if (mv != null) { if (mv != null) {

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -29,7 +37,8 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
/** /**
* A {@link MethodVisitor} providing a more detailed API to generate and transform instructions. * A {@link MethodVisitor} providing a more detailed API to generate and
* transform instructions.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -38,10 +47,12 @@ public class InstructionAdapter extends MethodVisitor {
public final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;"); public final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
/** /**
* Creates a new {@link InstructionAdapter}. <i>Subclasses must not use this constructor</i>. * Creates a new {@link InstructionAdapter}. <i>Subclasses must not use this
* Instead, they must use the {@link #InstructionAdapter(int, MethodVisitor)} version. * constructor</i>. Instead, they must use the
* {@link #InstructionAdapter(int, MethodVisitor)} version.
* *
* @param mv the method visitor to which this adapter delegates calls. * @param mv
* the method visitor to which this adapter delegates calls.
*/ */
public InstructionAdapter(final MethodVisitor mv) { public InstructionAdapter(final MethodVisitor mv) {
this(Opcodes.ASM4, mv); this(Opcodes.ASM4, mv);
@@ -50,9 +61,11 @@ public class InstructionAdapter extends MethodVisitor {
/** /**
* Creates a new {@link InstructionAdapter}. * Creates a new {@link InstructionAdapter}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param mv the method visitor to which this adapter delegates calls. * of {@link Opcodes#ASM4}.
* @param mv
* the method visitor to which this adapter delegates calls.
*/ */
protected InstructionAdapter(final int api, final MethodVisitor mv) { protected InstructionAdapter(final int api, final MethodVisitor mv) {
super(api, mv); super(api, mv);
@@ -474,8 +487,8 @@ public class InstructionAdapter extends MethodVisitor {
} }
@Override @Override
public void visitFieldInsn(final int opcode, final String owner, final String name, public void visitFieldInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
switch (opcode) { switch (opcode) {
case Opcodes.GETSTATIC: case Opcodes.GETSTATIC:
getstatic(owner, name, desc); getstatic(owner, name, desc);
@@ -495,8 +508,8 @@ public class InstructionAdapter extends MethodVisitor {
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, final String name, public void visitMethodInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
switch (opcode) { switch (opcode) {
case Opcodes.INVOKESPECIAL: case Opcodes.INVOKESPECIAL:
invokespecial(owner, name, desc); invokespecial(owner, name, desc);
@@ -516,7 +529,8 @@ public class InstructionAdapter extends MethodVisitor {
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
invokedynamic(name, desc, bsm, bsmArgs); invokedynamic(name, desc, bsm, bsmArgs);
} }
@@ -630,13 +644,14 @@ public class InstructionAdapter extends MethodVisitor {
} }
@Override @Override
public void visitTableSwitchInsn(final int min, final int max, final Label dflt, public void visitTableSwitchInsn(final int min, final int max,
final Label... labels) { final Label dflt, final Label... labels) {
tableswitch(min, max, dflt, labels); tableswitch(min, max, dflt, labels);
} }
@Override @Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
final Label[] labels) {
lookupswitch(dflt, keys, labels); lookupswitch(dflt, keys, labels);
} }
@@ -936,11 +951,13 @@ public class InstructionAdapter extends MethodVisitor {
mv.visitVarInsn(Opcodes.RET, var); mv.visitVarInsn(Opcodes.RET, var);
} }
public void tableswitch(final int min, final int max, final Label dflt, final Label... labels) { public void tableswitch(final int min, final int max, final Label dflt,
final Label... labels) {
mv.visitTableSwitchInsn(min, max, dflt, labels); mv.visitTableSwitchInsn(min, max, dflt, labels);
} }
public void lookupswitch(final Label dflt, final int[] keys, final Label[] labels) { public void lookupswitch(final Label dflt, final int[] keys,
final Label[] labels) {
mv.visitLookupSwitchInsn(dflt, keys, labels); mv.visitLookupSwitchInsn(dflt, keys, labels);
} }
@@ -948,39 +965,48 @@ public class InstructionAdapter extends MethodVisitor {
mv.visitInsn(t.getOpcode(Opcodes.IRETURN)); mv.visitInsn(t.getOpcode(Opcodes.IRETURN));
} }
public void getstatic(final String owner, final String name, final String desc) { public void getstatic(final String owner, final String name,
final String desc) {
mv.visitFieldInsn(Opcodes.GETSTATIC, owner, name, desc); mv.visitFieldInsn(Opcodes.GETSTATIC, owner, name, desc);
} }
public void putstatic(final String owner, final String name, final String desc) { public void putstatic(final String owner, final String name,
final String desc) {
mv.visitFieldInsn(Opcodes.PUTSTATIC, owner, name, desc); mv.visitFieldInsn(Opcodes.PUTSTATIC, owner, name, desc);
} }
public void getfield(final String owner, final String name, final String desc) { public void getfield(final String owner, final String name,
final String desc) {
mv.visitFieldInsn(Opcodes.GETFIELD, owner, name, desc); mv.visitFieldInsn(Opcodes.GETFIELD, owner, name, desc);
} }
public void putfield(final String owner, final String name, final String desc) { public void putfield(final String owner, final String name,
final String desc) {
mv.visitFieldInsn(Opcodes.PUTFIELD, owner, name, desc); mv.visitFieldInsn(Opcodes.PUTFIELD, owner, name, desc);
} }
public void invokevirtual(final String owner, final String name, final String desc) { public void invokevirtual(final String owner, final String name,
final String desc) {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc);
} }
public void invokespecial(final String owner, final String name, final String desc) { public void invokespecial(final String owner, final String name,
final String desc) {
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, desc); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, desc);
} }
public void invokestatic(final String owner, final String name, final String desc) { public void invokestatic(final String owner, final String name,
final String desc) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc); mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc);
} }
public void invokeinterface(final String owner, final String name, final String desc) { public void invokeinterface(final String owner, final String name,
final String desc) {
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, name, desc); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, name, desc);
} }
public void invokedynamic(String name, String desc, Handle bsm, Object[] bsmArgs) { public void invokedynamic(String name, String desc, Handle bsm,
Object[] bsmArgs) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -47,8 +55,8 @@ import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode; import org.objectweb.asm.tree.TryCatchBlockNode;
/** /**
* A {@link org.objectweb.asm.MethodVisitor} that removes JSR instructions and inlines the * A {@link org.objectweb.asm.MethodVisitor} that removes JSR instructions and
* referenced subroutines. * inlines the referenced subroutines.
* *
* <b>Explanation of how it works</b> TODO * <b>Explanation of how it works</b> TODO
* *
@@ -64,61 +72,82 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
private final Map<LabelNode, BitSet> subroutineHeads = new HashMap<LabelNode, BitSet>(); private final Map<LabelNode, BitSet> subroutineHeads = new HashMap<LabelNode, BitSet>();
/** /**
* This subroutine instance denotes the line of execution that is not contained within any * This subroutine instance denotes the line of execution that is not
* subroutine; i.e., the "subroutine" that is executing when a method first begins. * contained within any subroutine; i.e., the "subroutine" that is executing
* when a method first begins.
*/ */
private final BitSet mainSubroutine = new BitSet(); private final BitSet mainSubroutine = new BitSet();
/** /**
* This BitSet contains the index of every instruction that belongs to more than one subroutine. * This BitSet contains the index of every instruction that belongs to more
* This should not happen often. * than one subroutine. This should not happen often.
*/ */
final BitSet dualCitizens = new BitSet(); final BitSet dualCitizens = new BitSet();
/** /**
* Creates a new JSRInliner. <i>Subclasses must not use this constructor</i>. Instead, they must * Creates a new JSRInliner. <i>Subclasses must not use this
* use the {@link #JSRInlinerAdapter(int, MethodVisitor, int, String, String, String, String[])} * constructor</i>. Instead, they must use the
* {@link #JSRInlinerAdapter(int, MethodVisitor, int, String, String, String, String[])}
* version. * version.
* *
* @param mv the <code>MethodVisitor</code> to send the resulting inlined method code to (use * @param mv
* <code>null</code> for none). * the <code>MethodVisitor</code> to send the resulting inlined
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates * method code to (use <code>null</code> for none).
* if the method is synthetic and/or deprecated. * @param access
* @param name the method's name. * the method's access flags (see {@link Opcodes}). This
* @param desc the method's descriptor (see {@link Type}). * parameter also indicates if the method is synthetic and/or
* @param signature the method's signature. May be <tt>null</tt>. * deprecated.
* @param exceptions the internal names of the method's exception classes (see * @param name
* {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>. * the method's name.
* @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public JSRInlinerAdapter(final MethodVisitor mv, final int access, final String name, public JSRInlinerAdapter(final MethodVisitor mv, final int access,
final String desc, final String signature, final String[] exceptions) { final String name, final String desc, final String signature,
final String[] exceptions) {
this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions); this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions);
} }
/** /**
* Creates a new JSRInliner. * Creates a new JSRInliner.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param mv the <code>MethodVisitor</code> to send the resulting inlined method code to (use * of {@link Opcodes#ASM4}.
* <code>null</code> for none). * @param mv
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates * the <code>MethodVisitor</code> to send the resulting inlined
* if the method is synthetic and/or deprecated. * method code to (use <code>null</code> for none).
* @param name the method's name. * @param access
* @param desc the method's descriptor (see {@link Type}). * the method's access flags (see {@link Opcodes}). This
* @param signature the method's signature. May be <tt>null</tt>. * parameter also indicates if the method is synthetic and/or
* @param exceptions the internal names of the method's exception classes (see * deprecated.
* {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>. * @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
protected JSRInlinerAdapter(final int api, final MethodVisitor mv, final int access, protected JSRInlinerAdapter(final int api, final MethodVisitor mv,
final String name, final String desc, final String signature, final int access, final String name, final String desc,
final String[] exceptions) { final String signature, final String[] exceptions) {
super(api, access, name, desc, signature, exceptions); super(api, access, name, desc, signature, exceptions);
this.mv = mv; this.mv = mv;
} }
/** /**
* Detects a JSR instruction and sets a flag to indicate we will need to do inlining. * Detects a JSR instruction and sets a flag to indicate we will need to do
* inlining.
*/ */
@Override @Override
public void visitJumpInsn(final int opcode, final Label lbl) { public void visitJumpInsn(final int opcode, final Label lbl) {
@@ -130,8 +159,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* If any JSRs were seen, triggers the inlining process. Otherwise, forwards the byte codes * If any JSRs were seen, triggers the inlining process. Otherwise, forwards
* untouched. * the byte codes untouched.
*/ */
@Override @Override
public void visitEnd() { public void visitEnd() {
@@ -155,8 +184,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Walks the method and determines which internal subroutine(s), if any, each instruction is a * Walks the method and determines which internal subroutine(s), if any,
* method of. * each instruction is a method of.
*/ */
private void markSubroutines() { private void markSubroutines() {
BitSet anyvisited = new BitSet(); BitSet anyvisited = new BitSet();
@@ -167,8 +196,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
// Go through the head of each subroutine and find any nodes reachable // Go through the head of each subroutine and find any nodes reachable
// to that subroutine without following any JSR links. // to that subroutine without following any JSR links.
for (Iterator<Map.Entry<LabelNode, BitSet>> it = subroutineHeads.entrySet().iterator(); it for (Iterator<Map.Entry<LabelNode, BitSet>> it = subroutineHeads
.hasNext();) { .entrySet().iterator(); it.hasNext();) {
Map.Entry<LabelNode, BitSet> entry = it.next(); Map.Entry<LabelNode, BitSet> entry = it.next();
LabelNode lab = entry.getKey(); LabelNode lab = entry.getKey();
BitSet sub = entry.getValue(); BitSet sub = entry.getValue();
@@ -178,18 +207,23 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Performs a depth first search walking the normal byte code path starting at * Performs a depth first search walking the normal byte code path starting
* <code>index</code>, and adding each instruction encountered into the subroutine * at <code>index</code>, and adding each instruction encountered into the
* <code>sub</code>. After this walk is complete, iterates over the exception handlers to ensure * subroutine <code>sub</code>. After this walk is complete, iterates over
* that we also include those byte codes which are reachable through an exception that may be * the exception handlers to ensure that we also include those byte codes
* thrown during the execution of the subroutine. Invoked from <code>markSubroutines()</code>. * which are reachable through an exception that may be thrown during the
* execution of the subroutine. Invoked from <code>markSubroutines()</code>.
* *
* @param sub the subroutine whose instructions must be computed. * @param sub
* @param index an instruction of this subroutine. * the subroutine whose instructions must be computed.
* @param anyvisited indexes of the already visited instructions, i.e. marked as part of this * @param index
* subroutine or any previously computed subroutine. * an instruction of this subroutine.
* @param anyvisited
* indexes of the already visited instructions, i.e. marked as
* part of this subroutine or any previously computed subroutine.
*/ */
private void markSubroutineWalk(final BitSet sub, final int index, final BitSet anyvisited) { private void markSubroutineWalk(final BitSet sub, final int index,
final BitSet anyvisited) {
if (LOGGING) { if (LOGGING) {
log("markSubroutineWalk: sub=" + sub + " index=" + index); log("markSubroutineWalk: sub=" + sub + " index=" + index);
} }
@@ -201,7 +235,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
boolean loop = true; boolean loop = true;
while (loop) { while (loop) {
loop = false; loop = false;
for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it.hasNext();) { for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it
.hasNext();) {
TryCatchBlockNode trycatch = it.next(); TryCatchBlockNode trycatch = it.next();
if (LOGGING) { if (LOGGING) {
@@ -220,8 +255,9 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
int nextbit = sub.nextSetBit(startindex); int nextbit = sub.nextSetBit(startindex);
if (nextbit != -1 && nextbit < endindex) { if (nextbit != -1 && nextbit < endindex) {
if (LOGGING) { if (LOGGING) {
log("Adding exception handler: " + startindex + '-' + endindex + " due to " log("Adding exception handler: " + startindex + '-'
+ nextbit + " handler " + handlerindex); + endindex + " due to " + nextbit + " handler "
+ handlerindex);
} }
markSubroutineWalkDFS(sub, handlerindex, anyvisited); markSubroutineWalkDFS(sub, handlerindex, anyvisited);
loop = true; loop = true;
@@ -231,15 +267,20 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Performs a simple DFS of the instructions, assigning each to the subroutine <code>sub</code>. * Performs a simple DFS of the instructions, assigning each to the
* Starts from <code>index</code>. Invoked only by <code>markSubroutineWalk()</code>. * subroutine <code>sub</code>. Starts from <code>index</code>. Invoked only
* by <code>markSubroutineWalk()</code>.
* *
* @param sub the subroutine whose instructions must be computed. * @param sub
* @param index an instruction of this subroutine. * the subroutine whose instructions must be computed.
* @param anyvisited indexes of the already visited instructions, i.e. marked as part of this * @param index
* subroutine or any previously computed subroutine. * an instruction of this subroutine.
* @param anyvisited
* indexes of the already visited instructions, i.e. marked as
* part of this subroutine or any previously computed subroutine.
*/ */
private void markSubroutineWalkDFS(final BitSet sub, int index, final BitSet anyvisited) { private void markSubroutineWalkDFS(final BitSet sub, int index,
final BitSet anyvisited) {
while (true) { while (true) {
AbstractInsnNode node = instructions.get(index); AbstractInsnNode node = instructions.get(index);
@@ -258,7 +299,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
anyvisited.set(index); anyvisited.set(index);
if (node.getType() == AbstractInsnNode.JUMP_INSN && node.getOpcode() != JSR) { if (node.getType() == AbstractInsnNode.JUMP_INSN
&& node.getOpcode() != JSR) {
// we do not follow recursively called subroutines here; but any // we do not follow recursively called subroutines here; but any
// other sort of branch we do follow // other sort of branch we do follow
JumpInsnNode jnode = (JumpInsnNode) node; JumpInsnNode jnode = (JumpInsnNode) node;
@@ -301,8 +343,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
case RETURN: case RETURN:
case ATHROW: case ATHROW:
/* /*
* note: this either returns from this subroutine, or a parent subroutine which * note: this either returns from this subroutine, or a parent
* invoked it * subroutine which invoked it
*/ */
return; return;
} }
@@ -325,8 +367,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Creates the new instructions, inlining each instantiation of each subroutine until the code * Creates the new instructions, inlining each instantiation of each
* is fully elaborated. * subroutine until the code is fully elaborated.
*/ */
private void emitCode() { private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<Instantiation>(); LinkedList<Instantiation> worklist = new LinkedList<Instantiation>();
@@ -341,7 +383,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>(); List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
while (!worklist.isEmpty()) { while (!worklist.isEmpty()) {
Instantiation inst = worklist.removeFirst(); Instantiation inst = worklist.removeFirst();
emitSubroutine(inst, worklist, newInstructions, newTryCatchBlocks, newLocalVariables); emitSubroutine(inst, worklist, newInstructions, newTryCatchBlocks,
newLocalVariables);
} }
instructions = newInstructions; instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks; tryCatchBlocks = newTryCatchBlocks;
@@ -349,18 +392,25 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Emits one instantiation of one subroutine, specified by <code>instant</code>. May add new * Emits one instantiation of one subroutine, specified by
* instantiations that are invoked by this one to the <code>worklist</code> parameter, and new * <code>instant</code>. May add new instantiations that are invoked by this
* try/catch blocks to <code>newTryCatchBlocks</code>. * one to the <code>worklist</code> parameter, and new try/catch blocks to
* <code>newTryCatchBlocks</code>.
* *
* @param instant the instantiation that must be performed. * @param instant
* @param worklist list of the instantiations that remain to be done. * the instantiation that must be performed.
* @param newInstructions the instruction list to which the instantiated code must be appended. * @param worklist
* @param newTryCatchBlocks the exception handler list to which the instantiated handlers must * list of the instantiations that remain to be done.
* be appended. * @param newInstructions
* the instruction list to which the instantiated code must be
* appended.
* @param newTryCatchBlocks
* the exception handler list to which the instantiated handlers
* must be appended.
*/ */
private void emitSubroutine(final Instantiation instant, final List<Instantiation> worklist, private void emitSubroutine(final Instantiation instant,
final InsnList newInstructions, final List<TryCatchBlockNode> newTryCatchBlocks, final List<Instantiation> worklist, final InsnList newInstructions,
final List<TryCatchBlockNode> newTryCatchBlocks,
final List<LocalVariableNode> newLocalVariables) { final List<LocalVariableNode> newLocalVariables) {
LabelNode duplbl = null; LabelNode duplbl = null;
@@ -426,8 +476,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
// This is only possible if the mainSubroutine owns a RET // This is only possible if the mainSubroutine owns a RET
// instruction, which should never happen for verifiable // instruction, which should never happen for verifiable
// code. // code.
throw new RuntimeException( throw new RuntimeException("Instruction #" + i
"Instruction #" + i + " is a RET not owned by any subroutine"); + " is a RET not owned by any subroutine");
} }
newInstructions.add(new JumpInsnNode(GOTO, retlabel)); newInstructions.add(new JumpInsnNode(GOTO, retlabel));
} else if (insn.getOpcode() == JSR) { } else if (insn.getOpcode() == JSR) {
@@ -458,13 +508,14 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
// Emit try/catch blocks that are relevant to this method. // Emit try/catch blocks that are relevant to this method.
for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it.hasNext();) { for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it
.hasNext();) {
TryCatchBlockNode trycatch = it.next(); TryCatchBlockNode trycatch = it.next();
if (LOGGING) { if (LOGGING) {
// TODO use of default toString(). // TODO use of default toString().
log("try catch block original labels=" + trycatch.start + '-' + trycatch.end + "->" log("try catch block original labels=" + trycatch.start + '-'
+ trycatch.handler); + trycatch.end + "->" + trycatch.handler);
} }
final LabelNode start = instant.rangeLabel(trycatch.start); final LabelNode start = instant.rangeLabel(trycatch.start);
@@ -482,17 +533,20 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
if (LOGGING) { if (LOGGING) {
// TODO use of default toString(). // TODO use of default toString().
log(" try catch block new labels=" + start + '-' + end + "->" + handler); log(" try catch block new labels=" + start + '-' + end + "->"
+ handler);
} }
if (start == null || end == null || handler == null) { if (start == null || end == null || handler == null) {
throw new RuntimeException("Internal error!"); throw new RuntimeException("Internal error!");
} }
newTryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, trycatch.type)); newTryCatchBlocks.add(new TryCatchBlockNode(start, end, handler,
trycatch.type));
} }
for (Iterator<LocalVariableNode> it = localVariables.iterator(); it.hasNext();) { for (Iterator<LocalVariableNode> it = localVariables.iterator(); it
.hasNext();) {
LocalVariableNode lvnode = it.next(); LocalVariableNode lvnode = it.next();
if (LOGGING) { if (LOGGING) {
log("local var " + lvnode.name); log("local var " + lvnode.name);
@@ -505,8 +559,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
continue; continue;
} }
newLocalVariables.add(new LocalVariableNode(lvnode.name, lvnode.desc, lvnode.signature, newLocalVariables.add(new LocalVariableNode(lvnode.name,
start, end, lvnode.index)); lvnode.desc, lvnode.signature, start, end, lvnode.index));
} }
} }
@@ -515,16 +569,18 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* A class that represents an instantiation of a subroutine. Each instantiation has an associate * A class that represents an instantiation of a subroutine. Each
* "stack" --- which is a listing of those instantiations that were active when this particular * instantiation has an associate "stack" --- which is a listing of those
* instance of this subroutine was invoked. Each instantiation also has a map from the original * instantiations that were active when this particular instance of this
* labels of the program to the labels appropriate for this instantiation, and finally a label * subroutine was invoked. Each instantiation also has a map from the
* to return to. * original labels of the program to the labels appropriate for this
* instantiation, and finally a label to return to.
*/ */
private class Instantiation extends AbstractMap<LabelNode, LabelNode> { private class Instantiation extends AbstractMap<LabelNode, LabelNode> {
/** /**
* Previous instantiations; the stack must be statically predictable to be inlinable. * Previous instantiations; the stack must be statically predictable to
* be inlinable.
*/ */
final Instantiation previous; final Instantiation previous;
@@ -534,13 +590,15 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
public final BitSet subroutine; public final BitSet subroutine;
/** /**
* This table maps Labels from the original source to Labels pointing at code specific to * This table maps Labels from the original source to Labels pointing at
* this instantiation, for use in remapping try/catch blocks,as well as gotos. * code specific to this instantiation, for use in remapping try/catch
* blocks,as well as gotos.
* *
* Note that in the presence of dual citizens instructions, that is, instructions which * Note that in the presence of dual citizens instructions, that is,
* belong to more than one subroutine due to the merging of control flow without a RET * instructions which belong to more than one subroutine due to the
* instruction, we will map the target label of a GOTO to the label used by the * merging of control flow without a RET instruction, we will map the
* instantiation lowest on the stack. This avoids code duplication during inlining in most * target label of a GOTO to the label used by the instantiation lowest
* on the stack. This avoids code duplication during inlining in most
* cases. * cases.
* *
* @see #findOwner(int) * @see #findOwner(int)
@@ -602,23 +660,27 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Returns the "owner" of a particular instruction relative to this instantiation: the owner * Returns the "owner" of a particular instruction relative to this
* referes to the Instantiation which will emit the version of this instruction that we will * instantiation: the owner referes to the Instantiation which will emit
* execute. * the version of this instruction that we will execute.
* *
* Typically, the return value is either <code>this</code> or <code>null</code>. * Typically, the return value is either <code>this</code> or
* <code>this</code> indicates that this instantiation will generate the version of this * <code>null</code>. <code>this</code> indicates that this
* instruction that we will execute, and <code>null</code> indicates that this instantiation * instantiation will generate the version of this instruction that we
* will execute, and <code>null</code> indicates that this instantiation
* never executes the given instruction. * never executes the given instruction.
* *
* Sometimes, however, an instruction can belong to multiple subroutines; this is called a * Sometimes, however, an instruction can belong to multiple
* "dual citizen" instruction (though it may belong to more than 2 subroutines), and occurs * subroutines; this is called a "dual citizen" instruction (though it
* when multiple subroutines branch to common points of control. In this case, the owner is * may belong to more than 2 subroutines), and occurs when multiple
* the subroutine that appears lowest on the stack, and which also owns the instruction in * subroutines branch to common points of control. In this case, the
* question. * owner is the subroutine that appears lowest on the stack, and which
* also owns the instruction in question.
* *
* @param i the index of the instruction in the original code * @param i
* @return the "owner" of a particular instruction relative to this instantiation. * the index of the instruction in the original code
* @return the "owner" of a particular instruction relative to this
* instantiation.
*/ */
public Instantiation findOwner(final int i) { public Instantiation findOwner(final int i) {
if (!subroutine.get(i)) { if (!subroutine.get(i)) {
@@ -637,11 +699,13 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Looks up the label <code>l</code> in the <code>gotoTable</code>, thus translating it from * Looks up the label <code>l</code> in the <code>gotoTable</code>, thus
* a Label in the original code, to a Label in the inlined code that is appropriate for use * translating it from a Label in the original code, to a Label in the
* by an instruction that branched to the original label. * inlined code that is appropriate for use by an instruction that
* branched to the original label.
* *
* @param l The label we will be translating * @param l
* The label we will be translating
* @return a label for use by a branch instruction in the inlined code * @return a label for use by a branch instruction in the inlined code
* @see #rangeLabel * @see #rangeLabel
*/ */
@@ -653,12 +717,15 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Looks up the label <code>l</code> in the <code>rangeTable</code>, thus translating it * Looks up the label <code>l</code> in the <code>rangeTable</code>,
* from a Label in the original code, to a Label in the inlined code that is appropriate for * thus translating it from a Label in the original code, to a Label in
* use by an try/catch or variable use annotation. * the inlined code that is appropriate for use by an try/catch or
* variable use annotation.
* *
* @param l The label we will be translating * @param l
* @return a label for use by a try/catch or variable annotation in the original code * The label we will be translating
* @return a label for use by a try/catch or variable annotation in the
* original code
* @see #rangeTable * @see #rangeTable
*/ */
public LabelNode rangeLabel(final LabelNode l) { public LabelNode rangeLabel(final LabelNode l) {

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -27,11 +35,12 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
/** /**
* A {@link MethodVisitor} that renumbers local variables in their order of appearance. This adapter * A {@link MethodVisitor} that renumbers local variables in their order of
* allows one to easily add new local variables to a method. It may be used by inheriting from this * appearance. This adapter allows one to easily add new local variables to a
* class, but the preferred way of using it is via delegation: the next visitor in the chain can * method. It may be used by inheriting from this class, but the preferred way
* indeed add new locals when needed by calling {@link #newLocal} on this adapter (this requires a * of using it is via delegation: the next visitor in the chain can indeed add
* reference back to this {@link LocalVariablesSorter}). * new locals when needed by calling {@link #newLocal} on this adapter (this
* requires a reference back to this {@link LocalVariablesSorter}).
* *
* @author Chris Nokleberg * @author Chris Nokleberg
* @author Eugene Kuleshov * @author Eugene Kuleshov
@@ -39,12 +48,13 @@ import org.objectweb.asm.Type;
*/ */
public class LocalVariablesSorter extends MethodVisitor { public class LocalVariablesSorter extends MethodVisitor {
private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object"); private static final Type OBJECT_TYPE = Type
.getObjectType("java/lang/Object");
/** /**
* Mapping from old to new local variable indexes. A local variable at index i of size 1 is * Mapping from old to new local variable indexes. A local variable at index
* remapped to 'mapping[2*i]', while a local variable at index i of size 2 is remapped to * i of size 1 is remapped to 'mapping[2*i]', while a local variable at
* 'mapping[2*i+1]'. * index i of size 2 is remapped to 'mapping[2*i+1]'.
*/ */
private int[] mapping = new int[40]; private int[] mapping = new int[40];
@@ -69,29 +79,37 @@ public class LocalVariablesSorter extends MethodVisitor {
private boolean changed; private boolean changed;
/** /**
* Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use this constructor</i>. * Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use
* Instead, they must use the {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} * this constructor</i>. Instead, they must use the
* version. * {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version.
* *
* @param access access flags of the adapted method. * @param access
* @param desc the method's descriptor (see {@link Type Type}). * access flags of the adapted method.
* @param mv the method visitor to which this adapter delegates calls. * @param desc
* the method's descriptor (see {@link Type Type}).
* @param mv
* the method visitor to which this adapter delegates calls.
*/ */
public LocalVariablesSorter(final int access, final String desc, final MethodVisitor mv) { public LocalVariablesSorter(final int access, final String desc,
final MethodVisitor mv) {
this(Opcodes.ASM4, access, desc, mv); this(Opcodes.ASM4, access, desc, mv);
} }
/** /**
* Creates a new {@link LocalVariablesSorter}. * Creates a new {@link LocalVariablesSorter}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param access access flags of the adapted method. * of {@link Opcodes#ASM4}.
* @param desc the method's descriptor (see {@link Type Type}). * @param access
* @param mv the method visitor to which this adapter delegates calls. * access flags of the adapted method.
* @param desc
* the method's descriptor (see {@link Type Type}).
* @param mv
* the method visitor to which this adapter delegates calls.
*/ */
protected LocalVariablesSorter(final int api, final int access, final String desc, protected LocalVariablesSorter(final int api, final int access,
final MethodVisitor mv) { final String desc, final MethodVisitor mv) {
super(api, mv); super(api, mv);
Type[] args = Type.getArgumentTypes(desc); Type[] args = Type.getArgumentTypes(desc);
nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0; nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
@@ -146,15 +164,16 @@ public class LocalVariablesSorter extends MethodVisitor {
} }
@Override @Override
public void visitLocalVariable(final String name, final String desc, final String signature, public void visitLocalVariable(final String name, final String desc,
final Label start, final Label end, final int index) { final String signature, final Label start, final Label end,
final int index) {
int newIndex = remap(index, Type.getType(desc)); int newIndex = remap(index, Type.getType(desc));
mv.visitLocalVariable(name, desc, signature, start, end, newIndex); mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
} }
@Override @Override
public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, public void visitFrame(final int type, final int nLocal,
final Object[] stack) { final Object[] local, final int nStack, final Object[] stack) {
if (type != Opcodes.F_NEW) { // uncompressed frame if (type != Opcodes.F_NEW) { // uncompressed frame
throw new IllegalStateException( throw new IllegalStateException(
"ClassReader.accept() should be called with EXPAND_FRAMES flag"); "ClassReader.accept() should be called with EXPAND_FRAMES flag");
@@ -226,7 +245,8 @@ public class LocalVariablesSorter extends MethodVisitor {
/** /**
* Creates a new local variable of the given type. * Creates a new local variable of the given type.
* *
* @param type the type of the local variable to be created. * @param type
* the type of the local variable to be created.
* @return the identifier of the newly created local variable. * @return the identifier of the newly created local variable.
*/ */
public int newLocal(final Type type) { public int newLocal(final Type type) {
@@ -264,30 +284,39 @@ public class LocalVariablesSorter extends MethodVisitor {
} }
/** /**
* Notifies subclasses that a new stack map frame is being visited. The array argument contains * Notifies subclasses that a new stack map frame is being visited. The
* the stack map frame types corresponding to the local variables added with {@link #newLocal}. * array argument contains the stack map frame types corresponding to the
* This method can update these types in place for the stack map frame being visited. The * local variables added with {@link #newLocal}. This method can update
* default implementation of this method does nothing, i.e. a local variable added with * these types in place for the stack map frame being visited. The default
* {@link #newLocal} will have the same type in all stack map frames. But this behavior is not * implementation of this method does nothing, i.e. a local variable added
* always the desired one, for instance if a local variable is added in the middle of a * with {@link #newLocal} will have the same type in all stack map frames.
* try/catch block: the frame for the exception handler should have a TOP type for this new * But this behavior is not always the desired one, for instance if a local
* local. * variable is added in the middle of a try/catch block: the frame for the
* exception handler should have a TOP type for this new local.
* *
* @param newLocals the stack map frame types corresponding to the local variables added with * @param newLocals
* {@link #newLocal} (and null for the others). The format of this array is the same as * the stack map frame types corresponding to the local variables
* in {@link MethodVisitor#visitFrame}, except that long and double types use two slots. * added with {@link #newLocal} (and null for the others). The
* The types for the current stack map frame must be updated in place in this array. * format of this array is the same as in
* {@link MethodVisitor#visitFrame}, except that long and double
* types use two slots. The types for the current stack map frame
* must be updated in place in this array.
*/ */
protected void updateNewLocals(Object[] newLocals) {} protected void updateNewLocals(Object[] newLocals) {
}
/** /**
* Notifies subclasses that a local variable has been added or remapped. The default * Notifies subclasses that a local variable has been added or remapped. The
* implementation of this method does nothing. * default implementation of this method does nothing.
* *
* @param local a local variable identifier, as returned by {@link #newLocal newLocal()}. * @param local
* @param type the type of the value being stored in the local variable. * a local variable identifier, as returned by {@link #newLocal
* newLocal()}.
* @param type
* the type of the value being stored in the local variable.
*/ */
protected void setLocalType(final int local, final Type type) {} protected void setLocalType(final int local, final Type type) {
}
private void setFrameLocal(final int local, final Object type) { private void setFrameLocal(final int local, final Object type) {
int l = newLocals.length; int l = newLocals.length;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -66,8 +74,10 @@ public class Method {
/** /**
* Creates a new {@link Method}. * Creates a new {@link Method}.
* *
* @param name the method's name. * @param name
* @param desc the method's descriptor. * the method's name.
* @param desc
* the method's descriptor.
*/ */
public Method(final String name, final String desc) { public Method(final String name, final String desc) {
this.name = name; this.name = name;
@@ -77,19 +87,25 @@ public class Method {
/** /**
* Creates a new {@link Method}. * Creates a new {@link Method}.
* *
* @param name the method's name. * @param name
* @param returnType the method's return type. * the method's name.
* @param argumentTypes the method's argument types. * @param returnType
* the method's return type.
* @param argumentTypes
* the method's argument types.
*/ */
public Method(final String name, final Type returnType, final Type[] argumentTypes) { public Method(final String name, final Type returnType,
final Type[] argumentTypes) {
this(name, Type.getMethodDescriptor(returnType, argumentTypes)); this(name, Type.getMethodDescriptor(returnType, argumentTypes));
} }
/** /**
* Creates a new {@link Method}. * Creates a new {@link Method}.
* *
* @param m a java.lang.reflect method descriptor * @param m
* @return a {@link Method} corresponding to the given Java method declaration. * a java.lang.reflect method descriptor
* @return a {@link Method} corresponding to the given Java method
* declaration.
*/ */
public static Method getMethod(java.lang.reflect.Method m) { public static Method getMethod(java.lang.reflect.Method m) {
return new Method(m.getName(), Type.getMethodDescriptor(m)); return new Method(m.getName(), Type.getMethodDescriptor(m));
@@ -98,43 +114,60 @@ public class Method {
/** /**
* Creates a new {@link Method}. * Creates a new {@link Method}.
* *
* @param c a java.lang.reflect constructor descriptor * @param c
* @return a {@link Method} corresponding to the given Java constructor declaration. * a java.lang.reflect constructor descriptor
* @return a {@link Method} corresponding to the given Java constructor
* declaration.
*/ */
public static Method getMethod(java.lang.reflect.Constructor<?> c) { public static Method getMethod(java.lang.reflect.Constructor<?> c) {
return new Method("<init>", Type.getConstructorDescriptor(c)); return new Method("<init>", Type.getConstructorDescriptor(c));
} }
/** /**
* Returns a {@link Method} corresponding to the given Java method declaration. * Returns a {@link Method} corresponding to the given Java method
* declaration.
* *
* @param method a Java method declaration, without argument names, of the form "returnType name * @param method
* (argumentType1, ... argumentTypeN)", where the types are in plain Java (e.g. "int", * a Java method declaration, without argument names, of the form
* "float", "java.util.List", ...). Classes of the java.lang package can be specified by * "returnType name (argumentType1, ... argumentTypeN)", where
* their unqualified name; all other classes names must be fully qualified. * the types are in plain Java (e.g. "int", "float",
* @return a {@link Method} corresponding to the given Java method declaration. * "java.util.List", ...). Classes of the java.lang package can
* @throws IllegalArgumentException if <code>method</code> could not get parsed. * be specified by their unqualified name; all other classes
* names must be fully qualified.
* @return a {@link Method} corresponding to the given Java method
* declaration.
* @throws IllegalArgumentException
* if <code>method</code> could not get parsed.
*/ */
public static Method getMethod(final String method) throws IllegalArgumentException { public static Method getMethod(final String method)
throws IllegalArgumentException {
return getMethod(method, false); return getMethod(method, false);
} }
/** /**
* Returns a {@link Method} corresponding to the given Java method declaration. * Returns a {@link Method} corresponding to the given Java method
* declaration.
* *
* @param method a Java method declaration, without argument names, of the form "returnType name * @param method
* (argumentType1, ... argumentTypeN)", where the types are in plain Java (e.g. "int", * a Java method declaration, without argument names, of the form
* "float", "java.util.List", ...). Classes of the java.lang package may be specified by * "returnType name (argumentType1, ... argumentTypeN)", where
* their unqualified name, depending on the defaultPackage argument; all other classes * the types are in plain Java (e.g. "int", "float",
* names must be fully qualified. * "java.util.List", ...). Classes of the java.lang package may
* @param defaultPackage true if unqualified class names belong to the default package, or false * be specified by their unqualified name, depending on the
* if they correspond to java.lang classes. For instance "Object" means "Object" if this * defaultPackage argument; all other classes names must be fully
* option is true, or "java.lang.Object" otherwise. * qualified.
* @return a {@link Method} corresponding to the given Java method declaration. * @param defaultPackage
* @throws IllegalArgumentException if <code>method</code> could not get parsed. * true if unqualified class names belong to the default package,
* or false if they correspond to java.lang classes. For instance
* "Object" means "Object" if this option is true, or
* "java.lang.Object" otherwise.
* @return a {@link Method} corresponding to the given Java method
* declaration.
* @throws IllegalArgumentException
* if <code>method</code> could not get parsed.
*/ */
public static Method getMethod(final String method, final boolean defaultPackage) public static Method getMethod(final String method,
throws IllegalArgumentException { final boolean defaultPackage) throws IllegalArgumentException {
int space = method.indexOf(' '); int space = method.indexOf(' ');
int start = method.indexOf('(', space) + 1; int start = method.indexOf('(', space) + 1;
int end = method.indexOf(')', start); int end = method.indexOf(')', start);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -29,7 +37,8 @@ import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter; import org.objectweb.asm.signature.SignatureWriter;
/** /**
* A class responsible for remapping types and names. Subclasses can override the following methods: * A class responsible for remapping types and names. Subclasses can override
* the following methods:
* *
* <ul> * <ul>
* <li>{@link #map(String)} - map type</li> * <li>{@link #map(String)} - map type</li>
@@ -128,8 +137,8 @@ public abstract class Remapper {
} }
if (value instanceof Handle) { if (value instanceof Handle) {
Handle h = (Handle) value; Handle h = (Handle) value;
return new Handle(h.getTag(), mapType(h.getOwner()), return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(
mapMethodName(h.getOwner(), h.getName(), h.getDesc()), h.getOwner(), h.getName(), h.getDesc()),
mapMethodDesc(h.getDesc())); mapMethodDesc(h.getDesc()));
} }
return value; return value;
@@ -137,8 +146,10 @@ public abstract class Remapper {
/** /**
* *
* @param typeSignature true if signature is a FieldTypeSignature, such as the signature * @param typeSignature
* parameter of the ClassVisitor.visitField or MethodVisitor.visitLocalVariable methods * true if signature is a FieldTypeSignature, such as the
* signature parameter of the ClassVisitor.visitField or
* MethodVisitor.visitLocalVariable methods
*/ */
public String mapSignature(String signature, boolean typeSignature) { public String mapSignature(String signature, boolean typeSignature) {
if (signature == null) { if (signature == null) {
@@ -155,16 +166,20 @@ public abstract class Remapper {
return w.toString(); return w.toString();
} }
protected SignatureVisitor createRemappingSignatureAdapter(SignatureVisitor v) { protected SignatureVisitor createRemappingSignatureAdapter(
SignatureVisitor v) {
return new RemappingSignatureAdapter(v, this); return new RemappingSignatureAdapter(v, this);
} }
/** /**
* Map method name to the new name. Subclasses can override. * Map method name to the new name. Subclasses can override.
* *
* @param owner owner of the method. * @param owner
* @param name name of the method. * owner of the method.
* @param desc descriptor of the method. * @param name
* name of the method.
* @param desc
* descriptor of the method.
* @return new name of the method * @return new name of the method
*/ */
public String mapMethodName(String owner, String name, String desc) { public String mapMethodName(String owner, String name, String desc) {
@@ -174,8 +189,10 @@ public abstract class Remapper {
/** /**
* Map invokedynamic method name to the new name. Subclasses can override. * Map invokedynamic method name to the new name. Subclasses can override.
* *
* @param name name of the invokedynamic. * @param name
* @param desc descriptor of the invokedynamic. * name of the invokedynamic.
* @param desc
* descriptor of the invokedynamic.
* @return new invokdynamic name. * @return new invokdynamic name.
*/ */
public String mapInvokeDynamicMethodName(String name, String desc) { public String mapInvokeDynamicMethodName(String name, String desc) {
@@ -185,9 +202,12 @@ public abstract class Remapper {
/** /**
* Map field name to the new name. Subclasses can override. * Map field name to the new name. Subclasses can override.
* *
* @param owner owner of the field. * @param owner
* @param name name of the field * owner of the field.
* @param desc descriptor of the field * @param name
* name of the field
* @param desc
* descriptor of the field
* @return new name of the field. * @return new name of the field.
*/ */
public String mapFieldName(String owner, String name, String desc) { public String mapFieldName(String owner, String name, String desc) {

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -34,12 +42,13 @@ public class RemappingAnnotationAdapter extends AnnotationVisitor {
protected final Remapper remapper; protected final Remapper remapper;
public RemappingAnnotationAdapter(final AnnotationVisitor av, final Remapper remapper) { public RemappingAnnotationAdapter(final AnnotationVisitor av,
final Remapper remapper) {
this(Opcodes.ASM4, av, remapper); this(Opcodes.ASM4, av, remapper);
} }
protected RemappingAnnotationAdapter(final int api, final AnnotationVisitor av, protected RemappingAnnotationAdapter(final int api,
final Remapper remapper) { final AnnotationVisitor av, final Remapper remapper) {
super(api, av); super(api, av);
this.remapper = remapper; this.remapper = remapper;
} }
@@ -57,12 +66,14 @@ public class RemappingAnnotationAdapter extends AnnotationVisitor {
@Override @Override
public AnnotationVisitor visitAnnotation(String name, String desc) { public AnnotationVisitor visitAnnotation(String name, String desc) {
AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc)); AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc));
return v == null ? null : (v == av ? this : new RemappingAnnotationAdapter(v, remapper)); return v == null ? null : (v == av ? this
: new RemappingAnnotationAdapter(v, remapper));
} }
@Override @Override
public AnnotationVisitor visitArray(String name) { public AnnotationVisitor visitArray(String name) {
AnnotationVisitor v = av.visitArray(name); AnnotationVisitor v = av.visitArray(name);
return v == null ? null : (v == av ? this : new RemappingAnnotationAdapter(v, remapper)); return v == null ? null : (v == av ? this
: new RemappingAnnotationAdapter(v, remapper));
} }
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -43,17 +51,18 @@ public class RemappingClassAdapter extends ClassVisitor {
this(Opcodes.ASM4, cv, remapper); this(Opcodes.ASM4, cv, remapper);
} }
protected RemappingClassAdapter(final int api, final ClassVisitor cv, final Remapper remapper) { protected RemappingClassAdapter(final int api, final ClassVisitor cv,
final Remapper remapper) {
super(api, cv); super(api, cv);
this.remapper = remapper; this.remapper = remapper;
} }
@Override @Override
public void visit(int version, int access, String name, String signature, String superName, public void visit(int version, int access, String name, String signature,
String[] interfaces) { String superName, String[] interfaces) {
this.className = name; this.className = name;
super.visit(version, access, remapper.mapType(name), super.visit(version, access, remapper.mapType(name), remapper
remapper.mapSignature(signature, false), remapper.mapType(superName), .mapSignature(signature, false), remapper.mapType(superName),
interfaces == null ? null : remapper.mapTypes(interfaces)); interfaces == null ? null : remapper.mapTypes(interfaces));
} }
@@ -65,35 +74,39 @@ public class RemappingClassAdapter extends ClassVisitor {
} }
@Override @Override
public FieldVisitor visitField(int access, String name, String desc, String signature, public FieldVisitor visitField(int access, String name, String desc,
Object value) { String signature, Object value) {
FieldVisitor fv = super.visitField(access, remapper.mapFieldName(className, name, desc), FieldVisitor fv = super.visitField(access,
remapper.mapFieldName(className, name, desc),
remapper.mapDesc(desc), remapper.mapSignature(signature, true), remapper.mapDesc(desc), remapper.mapSignature(signature, true),
remapper.mapValue(value)); remapper.mapValue(value));
return fv == null ? null : createRemappingFieldAdapter(fv); return fv == null ? null : createRemappingFieldAdapter(fv);
} }
@Override @Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, public MethodVisitor visitMethod(int access, String name, String desc,
String[] exceptions) { String signature, String[] exceptions) {
String newDesc = remapper.mapMethodDesc(desc); String newDesc = remapper.mapMethodDesc(desc);
MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(className, name, desc), MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(
newDesc, remapper.mapSignature(signature, false), className, name, desc), newDesc, remapper.mapSignature(
signature, false),
exceptions == null ? null : remapper.mapTypes(exceptions)); exceptions == null ? null : remapper.mapTypes(exceptions));
return mv == null ? null : createRemappingMethodAdapter(access, newDesc, mv); return mv == null ? null : createRemappingMethodAdapter(access,
newDesc, mv);
} }
@Override @Override
public void visitInnerClass(String name, String outerName, String innerName, int access) { public void visitInnerClass(String name, String outerName,
String innerName, int access) {
// TODO should innerName be changed? // TODO should innerName be changed?
super.visitInnerClass(remapper.mapType(name), super.visitInnerClass(remapper.mapType(name), outerName == null ? null
outerName == null ? null : remapper.mapType(outerName), innerName, access); : remapper.mapType(outerName), innerName, access);
} }
@Override @Override
public void visitOuterClass(String owner, String name, String desc) { public void visitOuterClass(String owner, String name, String desc) {
super.visitOuterClass(remapper.mapType(owner), super.visitOuterClass(remapper.mapType(owner), name == null ? null
name == null ? null : remapper.mapMethodName(owner, name, desc), : remapper.mapMethodName(owner, name, desc),
desc == null ? null : remapper.mapMethodDesc(desc)); desc == null ? null : remapper.mapMethodDesc(desc));
} }
@@ -101,12 +114,13 @@ public class RemappingClassAdapter extends ClassVisitor {
return new RemappingFieldAdapter(fv, remapper); return new RemappingFieldAdapter(fv, remapper);
} }
protected MethodVisitor createRemappingMethodAdapter(int access, String newDesc, protected MethodVisitor createRemappingMethodAdapter(int access,
MethodVisitor mv) { String newDesc, MethodVisitor mv) {
return new RemappingMethodAdapter(access, newDesc, mv, remapper); return new RemappingMethodAdapter(access, newDesc, mv, remapper);
} }
protected AnnotationVisitor createRemappingAnnotationAdapter(AnnotationVisitor av) { protected AnnotationVisitor createRemappingAnnotationAdapter(
AnnotationVisitor av) {
return new RemappingAnnotationAdapter(av, remapper); return new RemappingAnnotationAdapter(av, remapper);
} }
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -39,14 +47,16 @@ public class RemappingFieldAdapter extends FieldVisitor {
this(Opcodes.ASM4, fv, remapper); this(Opcodes.ASM4, fv, remapper);
} }
protected RemappingFieldAdapter(final int api, final FieldVisitor fv, final Remapper remapper) { protected RemappingFieldAdapter(final int api, final FieldVisitor fv,
final Remapper remapper) {
super(api, fv); super(api, fv);
this.remapper = remapper; this.remapper = remapper;
} }
@Override @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc), visible); AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc),
visible);
return av == null ? null : new RemappingAnnotationAdapter(av, remapper); return av == null ? null : new RemappingAnnotationAdapter(av, remapper);
} }
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -37,13 +45,13 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
protected final Remapper remapper; protected final Remapper remapper;
public RemappingMethodAdapter(final int access, final String desc, final MethodVisitor mv, public RemappingMethodAdapter(final int access, final String desc,
final Remapper remapper) { final MethodVisitor mv, final Remapper remapper) {
this(Opcodes.ASM4, access, desc, mv, remapper); this(Opcodes.ASM4, access, desc, mv, remapper);
} }
protected RemappingMethodAdapter(final int api, final int access, final String desc, protected RemappingMethodAdapter(final int api, final int access,
final MethodVisitor mv, final Remapper remapper) { final String desc, final MethodVisitor mv, final Remapper remapper) {
super(api, access, desc, mv); super(api, access, desc, mv);
this.remapper = remapper; this.remapper = remapper;
} }
@@ -56,19 +64,22 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
@Override @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = mv.visitAnnotation(remapper.mapDesc(desc), visible); AnnotationVisitor av = mv.visitAnnotation(remapper.mapDesc(desc),
visible);
return av == null ? av : new RemappingAnnotationAdapter(av, remapper); return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
} }
@Override @Override
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { public AnnotationVisitor visitParameterAnnotation(int parameter,
AnnotationVisitor av = String desc, boolean visible) {
mv.visitParameterAnnotation(parameter, remapper.mapDesc(desc), visible); AnnotationVisitor av = mv.visitParameterAnnotation(parameter,
remapper.mapDesc(desc), visible);
return av == null ? av : new RemappingAnnotationAdapter(av, remapper); return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
} }
@Override @Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { public void visitFrame(int type, int nLocal, Object[] local, int nStack,
Object[] stack) {
super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack, super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack,
remapEntries(nStack, stack)); remapEntries(nStack, stack));
} }
@@ -82,7 +93,8 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
} }
do { do {
Object t = entries[i]; Object t = entries[i];
newEntries[i++] = t instanceof String ? remapper.mapType((String) t) : t; newEntries[i++] = t instanceof String ? remapper
.mapType((String) t) : t;
} while (i < n); } while (i < n);
return newEntries; return newEntries;
} }
@@ -91,24 +103,31 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
} }
@Override @Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) { public void visitFieldInsn(int opcode, String owner, String name,
String desc) {
super.visitFieldInsn(opcode, remapper.mapType(owner), super.visitFieldInsn(opcode, remapper.mapType(owner),
remapper.mapFieldName(owner, name, desc), remapper.mapDesc(desc)); remapper.mapFieldName(owner, name, desc),
remapper.mapDesc(desc));
} }
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name,
String desc) {
super.visitMethodInsn(opcode, remapper.mapType(owner), super.visitMethodInsn(opcode, remapper.mapType(owner),
remapper.mapMethodName(owner, name, desc), remapper.mapMethodDesc(desc)); remapper.mapMethodName(owner, name, desc),
remapper.mapMethodDesc(desc));
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
for (int i = 0; i < bsmArgs.length; i++) { for (int i = 0; i < bsmArgs.length; i++) {
bsmArgs[i] = remapper.mapValue(bsmArgs[i]); bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
} }
super.visitInvokeDynamicInsn(remapper.mapInvokeDynamicMethodName(name, desc), super.visitInvokeDynamicInsn(
remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm), bsmArgs); remapper.mapInvokeDynamicMethodName(name, desc),
remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm),
bsmArgs);
} }
@Override @Override
@@ -127,13 +146,15 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
} }
@Override @Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { public void visitTryCatchBlock(Label start, Label end, Label handler,
super.visitTryCatchBlock(start, end, handler, type == null ? null : remapper.mapType(type)); String type) {
super.visitTryCatchBlock(start, end, handler, type == null ? null
: remapper.mapType(type));
} }
@Override @Override
public void visitLocalVariable(String name, String desc, String signature, Label start, public void visitLocalVariable(String name, String desc, String signature,
Label end, int index) { Label start, Label end, int index) {
super.visitLocalVariable(name, remapper.mapDesc(desc), super.visitLocalVariable(name, remapper.mapDesc(desc),
remapper.mapSignature(signature, true), start, end, index); remapper.mapSignature(signature, true), start, end, index);
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -38,12 +46,13 @@ public class RemappingSignatureAdapter extends SignatureVisitor {
private String className; private String className;
public RemappingSignatureAdapter(final SignatureVisitor v, final Remapper remapper) { public RemappingSignatureAdapter(final SignatureVisitor v,
final Remapper remapper) {
this(Opcodes.ASM4, v, remapper); this(Opcodes.ASM4, v, remapper);
} }
protected RemappingSignatureAdapter(final int api, final SignatureVisitor v, protected RemappingSignatureAdapter(final int api,
final Remapper remapper) { final SignatureVisitor v, final Remapper remapper) {
super(api); super(api);
this.v = v; this.v = v;
this.remapper = remapper; this.remapper = remapper;
@@ -60,8 +69,8 @@ public class RemappingSignatureAdapter extends SignatureVisitor {
String remappedOuter = remapper.mapType(className) + '$'; String remappedOuter = remapper.mapType(className) + '$';
className = className + '$' + name; className = className + '$' + name;
String remappedName = remapper.mapType(className); String remappedName = remapper.mapType(className);
int index = remappedName.startsWith(remappedOuter) ? remappedOuter.length() int index = remappedName.startsWith(remappedOuter) ? remappedOuter
: remappedName.lastIndexOf('$') + 1; .length() : remappedName.lastIndexOf('$') + 1;
v.visitInnerClassType(remappedName.substring(index)); v.visitInnerClassType(remappedName.substring(index));
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -36,8 +44,8 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
/** /**
* A {@link ClassVisitor} that adds a serial version unique identifier to a class if missing. Here * A {@link ClassVisitor} that adds a serial version unique identifier to a
* is typical usage of this class: * class if missing. Here is typical usage of this class:
* *
* <pre> * <pre>
* ClassWriter cw = new ClassWriter(...); * ClassWriter cw = new ClassWriter(...);
@@ -46,8 +54,8 @@ import java.util.Collection;
* new ClassReader(orginalClass).accept(ca, false); * new ClassReader(orginalClass).accept(ca, false);
* </pre> * </pre>
* <p> * <p>
* The SVUID algorithm can be found * The SVUID algorithm can be found <a href=
* <a href= "http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html" * "http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html"
* >http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html</a>: * >http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html</a>:
* *
* <pre> * <pre>
@@ -105,7 +113,8 @@ import java.util.Collection;
public class SerialVersionUIDAdder extends ClassVisitor { public class SerialVersionUIDAdder extends ClassVisitor {
/** /**
* Collection of fields. (except private static and private transient fields) * Collection of fields. (except private static and private transient
* fields)
*/ */
private final Collection<Item> svuidFields; private final Collection<Item> svuidFields;
/** /**
@@ -142,10 +151,12 @@ public class SerialVersionUIDAdder extends ClassVisitor {
private boolean hasStaticInitializer; private boolean hasStaticInitializer;
/** /**
* Creates a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use this constructor</i>. * Creates a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use
* Instead, they must use the {@link #SerialVersionUIDAdder(int, ClassVisitor)} version. * this constructor</i>. Instead, they must use the
* {@link #SerialVersionUIDAdder(int, ClassVisitor)} version.
* *
* @param cv a {@link ClassVisitor} to which this visitor will delegate calls. * @param cv a {@link ClassVisitor} to which this visitor will delegate
* calls.
*/ */
public SerialVersionUIDAdder(final ClassVisitor cv) { public SerialVersionUIDAdder(final ClassVisitor cv) {
this(Opcodes.ASM4, cv); this(Opcodes.ASM4, cv);
@@ -154,9 +165,10 @@ public class SerialVersionUIDAdder extends ClassVisitor {
/** /**
* Creates a new {@link SerialVersionUIDAdder}. * Creates a new {@link SerialVersionUIDAdder}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api the ASM API version implemented by this visitor. Must be one
* {@link Opcodes#ASM4}. * of {@link Opcodes#ASM4}.
* @param cv a {@link ClassVisitor} to which this visitor will delegate calls. * @param cv a {@link ClassVisitor} to which this visitor will delegate
* calls.
*/ */
protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) { protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) {
super(api, cv); super(api, cv);
@@ -177,25 +189,27 @@ public class SerialVersionUIDAdder extends ClassVisitor {
* @param dotted a <code>boolean</code> value * @param dotted a <code>boolean</code> value
* @throws IOException if an error occurs * @throws IOException if an error occurs
*/ */
private static void writeItems(final Collection<Item> itemCollection, final DataOutput dos, private static void writeItems(final Collection<Item> itemCollection,
final boolean dotted) throws IOException { final DataOutput dos, final boolean dotted) throws IOException {
int size = itemCollection.size(); int size = itemCollection.size();
Item[] items = itemCollection.toArray(new Item[size]); Item[] items = itemCollection.toArray(new Item[size]);
Arrays.sort(items); Arrays.sort(items);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
dos.writeUTF(items[i].name); dos.writeUTF(items[i].name);
dos.writeInt(items[i].access); dos.writeInt(items[i].access);
dos.writeUTF(dotted ? items[i].desc.replace('/', '.') : items[i].desc); dos.writeUTF(dotted ? items[i].desc.replace('/', '.')
: items[i].desc);
} }
} }
/* /*
* Visit class header and get class name, access , and interfaces information (step 1,2, and 3) * Visit class header and get class name, access , and interfaces
* for SVUID computation. * information (step 1,2, and 3) for SVUID computation.
*/ */
@Override @Override
public void visit(final int version, final int access, final String name, public void visit(final int version, final int access, final String name,
final String signature, final String superName, final String[] interfaces) { final String signature, final String superName,
final String[] interfaces) {
computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0; computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;
if (computeSVUID) { if (computeSVUID) {
@@ -208,23 +222,27 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/* /*
* Visit the methods and get constructor and method information (step 5 and 7). Also determine * Visit the methods and get constructor and method information (step 5 and
* if there is a class initializer (step 6). * 7). Also determine if there is a class initializer (step 6).
*/ */
@Override @Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, public MethodVisitor visitMethod(final int access, final String name,
final String signature, final String[] exceptions) { final String desc, final String signature, final String[] exceptions) {
if (computeSVUID) { if (computeSVUID) {
if ("<clinit>".equals(name)) { if ("<clinit>".equals(name)) {
hasStaticInitializer = true; hasStaticInitializer = true;
} }
/* /*
* Remembers non private constructors and methods for SVUID computation For constructor * Remembers non private constructors and methods for SVUID
* and method modifiers, only the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, * computation For constructor and method modifiers, only the
* ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags are used. * ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
* ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags
* are used.
*/ */
int mods = access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED int mods = access
| Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
| Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
| Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED
| Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT); | Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT);
// all non private methods // all non private methods
@@ -241,12 +259,12 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/* /*
* Gets class field information for step 4 of the algorithm. Also determines if the class * Gets class field information for step 4 of the algorithm. Also determines
* already has a SVUID. * if the class already has a SVUID.
*/ */
@Override @Override
public FieldVisitor visitField(final int access, final String name, final String desc, public FieldVisitor visitField(final int access, final String name,
final String signature, final Object value) { final String desc, final String signature, final Object value) {
if (computeSVUID) { if (computeSVUID) {
if ("serialVersionUID".equals(name)) { if ("serialVersionUID".equals(name)) {
// since the class already has SVUID, we won't be computing it. // since the class already has SVUID, we won't be computing it.
@@ -254,15 +272,17 @@ public class SerialVersionUIDAdder extends ClassVisitor {
hasSVUID = true; hasSVUID = true;
} }
/* /*
* Remember field for SVUID computation For field modifiers, only the ACC_PUBLIC, * Remember field for SVUID computation For field modifiers, only
* ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT * the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC,
* flags are used when computing serialVersionUID values. * ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when
* computing serialVersionUID values.
*/ */
if ((access & Opcodes.ACC_PRIVATE) == 0 if ((access & Opcodes.ACC_PRIVATE) == 0
|| (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) { || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) {
int mods = access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE int mods = access
| Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
| Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT); | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
| Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT);
svuidFields.add(new Item(name, mods, desc)); svuidFields.add(new Item(name, mods, desc));
} }
} }
@@ -271,14 +291,15 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/** /**
* Handle a bizarre special case. Nested classes (static classes declared inside another class) * Handle a bizarre special case. Nested classes (static classes declared
* that are protected have their access bit set to public in their class files to deal with some * inside another class) that are protected have their access bit set to
* odd reflection situation. Our SVUID computation must do as the JVM does and ignore access * public in their class files to deal with some odd reflection situation.
* bits in the class file in favor of the access bits InnerClass attribute. * Our SVUID computation must do as the JVM does and ignore access bits in
* the class file in favor of the access bits InnerClass attribute.
*/ */
@Override @Override
public void visitInnerClass(final String aname, final String outerName, final String innerName, public void visitInnerClass(final String aname, final String outerName,
final int attr_access) { final String innerName, final int attr_access) {
if ((name != null) && name.equals(aname)) { if ((name != null) && name.equals(aname)) {
this.access = attr_access; this.access = attr_access;
} }
@@ -299,7 +320,8 @@ public class SerialVersionUIDAdder extends ClassVisitor {
try { try {
addSVUID(computeSVUID()); addSVUID(computeSVUID());
} catch (Throwable e) { } catch (Throwable e) {
throw new RuntimeException("Error while computing SVUID for " + name, e); throw new RuntimeException("Error while computing SVUID for "
+ name, e);
} }
} }
@@ -307,8 +329,8 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/** /**
* Returns true if the class already has a SVUID field. The result of this method is only valid * Returns true if the class already has a SVUID field. The result of this
* when visitEnd is or has been called. * method is only valid when visitEnd is or has been called.
* *
* @return true if the class already has a SVUID field. * @return true if the class already has a SVUID field.
*/ */
@@ -317,8 +339,8 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
protected void addSVUID(long svuid) { protected void addSVUID(long svuid) {
FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL
"serialVersionUID", "J", null, svuid); + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid);
if (null != fv) { if (null != fv) {
fv.visitEnd(); fv.visitEnd();
} }
@@ -347,11 +369,13 @@ public class SerialVersionUIDAdder extends ClassVisitor {
/* /*
* 2. The class modifiers written as a 32-bit integer. * 2. The class modifiers written as a 32-bit integer.
*/ */
dos.writeInt(access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_INTERFACE dos.writeInt(access
| Opcodes.ACC_ABSTRACT)); & (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL
| Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT));
/* /*
* 3. The name of each interface sorted by name written using UTF encoding. * 3. The name of each interface sorted by name written using UTF
* encoding.
*/ */
Arrays.sort(interfaces); Arrays.sort(interfaces);
for (String anInterface : interfaces) { for (String anInterface : interfaces) {
@@ -359,22 +383,24 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/* /*
* 4. For each field of the class sorted by field name (except private static and * 4. For each field of the class sorted by field name (except
* private transient fields): * private static and private transient fields):
* *
* 1. The name of the field in UTF encoding. 2. The modifiers of the field written as a * 1. The name of the field in UTF encoding. 2. The modifiers of the
* 32-bit integer. 3. The descriptor of the field in UTF encoding * field written as a 32-bit integer. 3. The descriptor of the field
* in UTF encoding
* *
* Note that field signatures are not dot separated. Method and constructor signatures * Note that field signatures are not dot separated. Method and
* are dot separated. Go figure... * constructor signatures are dot separated. Go figure...
*/ */
writeItems(svuidFields, dos, false); writeItems(svuidFields, dos, false);
/* /*
* 5. If a class initializer exists, write out the following: 1. The name of the method, * 5. If a class initializer exists, write out the following: 1. The
* <clinit>, in UTF encoding. 2. The modifier of the method, * name of the method, <clinit>, in UTF encoding. 2. The modifier of
* java.lang.reflect.Modifier.STATIC, written as a 32-bit integer. 3. The descriptor of * the method, java.lang.reflect.Modifier.STATIC, written as a
* the method, ()V, in UTF encoding. * 32-bit integer. 3. The descriptor of the method, ()V, in UTF
* encoding.
*/ */
if (hasStaticInitializer) { if (hasStaticInitializer) {
dos.writeUTF("<clinit>"); dos.writeUTF("<clinit>");
@@ -383,37 +409,42 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} // if.. } // if..
/* /*
* 6. For each non-private constructor sorted by method name and signature: 1. The name * 6. For each non-private constructor sorted by method name and
* of the method, <init>, in UTF encoding. 2. The modifiers of the method written as a * signature: 1. The name of the method, <init>, in UTF encoding. 2.
* 32-bit integer. 3. The descriptor of the method in UTF encoding. * The modifiers of the method written as a 32-bit integer. 3. The
* descriptor of the method in UTF encoding.
*/ */
writeItems(svuidConstructors, dos, true); writeItems(svuidConstructors, dos, true);
/* /*
* 7. For each non-private method sorted by method name and signature: 1. The name of * 7. For each non-private method sorted by method name and
* the method in UTF encoding. 2. The modifiers of the method written as a 32-bit * signature: 1. The name of the method in UTF encoding. 2. The
* integer. 3. The descriptor of the method in UTF encoding. * modifiers of the method written as a 32-bit integer. 3. The
* descriptor of the method in UTF encoding.
*/ */
writeItems(svuidMethods, dos, true); writeItems(svuidMethods, dos, true);
dos.flush(); dos.flush();
/* /*
* 8. The SHA-1 algorithm is executed on the stream of bytes produced by * 8. The SHA-1 algorithm is executed on the stream of bytes
* DataOutputStream and produces five 32-bit values sha[0..4]. * produced by DataOutputStream and produces five 32-bit values
* sha[0..4].
*/ */
byte[] hashBytes = computeSHAdigest(bos.toByteArray()); byte[] hashBytes = computeSHAdigest(bos.toByteArray());
/* /*
* 9. The hash value is assembled from the first and second 32-bit values of the SHA-1 * 9. The hash value is assembled from the first and second 32-bit
* message digest. If the result of the message digest, the five 32-bit words H0 H1 H2 * values of the SHA-1 message digest. If the result of the message
* H3 H4, is in an array of five int values named sha, the hash value would be computed * digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of
* as follows: * five int values named sha, the hash value would be computed as
* follows:
* *
* long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF) << 8 | ((sha[0] >>> * long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF)
* 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) << 24 | ((sha[1] >>> 24) & 0xFF) << 32 | * << 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) <<
* ((sha[1] >>> 16) & 0xFF) << 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & * 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) & 0xFF) <<
* 0xFF) << 56; * 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & 0xFF) <<
* 56;
*/ */
for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
svuid = (svuid << 8) | (hashBytes[i] & 0xFF); svuid = (svuid << 8) | (hashBytes[i] & 0xFF);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -44,21 +52,23 @@ public class StaticInitMerger extends ClassVisitor {
this(Opcodes.ASM4, prefix, cv); this(Opcodes.ASM4, prefix, cv);
} }
protected StaticInitMerger(final int api, final String prefix, final ClassVisitor cv) { protected StaticInitMerger(final int api, final String prefix,
final ClassVisitor cv) {
super(api, cv); super(api, cv);
this.prefix = prefix; this.prefix = prefix;
} }
@Override @Override
public void visit(final int version, final int access, final String name, public void visit(final int version, final int access, final String name,
final String signature, final String superName, final String[] interfaces) { final String signature, final String superName,
final String[] interfaces) {
cv.visit(version, access, name, signature, superName, interfaces); cv.visit(version, access, name, signature, superName, interfaces);
this.name = name; this.name = name;
} }
@Override @Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, public MethodVisitor visitMethod(final int access, final String name,
final String signature, final String[] exceptions) { final String desc, final String signature, final String[] exceptions) {
MethodVisitor mv; MethodVisitor mv;
if ("<clinit>".equals(name)) { if ("<clinit>".equals(name)) {
int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC; int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -35,8 +43,10 @@ public interface TableSwitchGenerator {
/** /**
* Generates the code for a switch case. * Generates the code for a switch case.
* *
* @param key the switch case key. * @param key
* @param end a label that corresponds to the end of the switch statement. * the switch case key.
* @param end
* a label that corresponds to the end of the switch statement.
*/ */
void generateCase(int key, Label end); void generateCase(int key, Label end);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
@@ -31,27 +39,30 @@ import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode; import org.objectweb.asm.tree.TryCatchBlockNode;
/** /**
* A {@link MethodVisitor} adapter to sort the exception handlers. The handlers are sorted in a * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers
* method innermost-to-outermost. This allows the programmer to add handlers without worrying about * are sorted in a method innermost-to-outermost. This allows the programmer to
* ordering them correctly with respect to existing, in-code handlers. * add handlers without worrying about ordering them correctly with respect to
* existing, in-code handlers.
* *
* Behavior is only defined for properly-nested handlers. If any "try" blocks overlap (something * Behavior is only defined for properly-nested handlers. If any "try" blocks
* that isn't possible in Java code) then this may not do what you want. In fact, this adapter just * overlap (something that isn't possible in Java code) then this may not do
* sorts by the length of the "try" block, taking advantage of the fact that a given try block must * what you want. In fact, this adapter just sorts by the length of the "try"
* be larger than any block it contains). * block, taking advantage of the fact that a given try block must be larger
* than any block it contains).
* *
* @author Adrian Sampson * @author Adrian Sampson
*/ */
public class TryCatchBlockSorter extends MethodNode { public class TryCatchBlockSorter extends MethodNode {
public TryCatchBlockSorter(final MethodVisitor mv, final int access, final String name, public TryCatchBlockSorter(final MethodVisitor mv, final int access,
final String desc, final String signature, final String[] exceptions) { final String name, final String desc, final String signature,
final String[] exceptions) {
this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions); this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions);
} }
protected TryCatchBlockSorter(final int api, final MethodVisitor mv, final int access, protected TryCatchBlockSorter(final int api, final MethodVisitor mv,
final String name, final String desc, final String signature, final int access, final String name, final String desc,
final String[] exceptions) { final String signature, final String[] exceptions) {
super(api, access, name, desc, signature, exceptions); super(api, access, name, desc, signature, exceptions);
this.mv = mv; this.mv = mv;
} }

View File

@@ -1,28 +1,37 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.signature; package org.objectweb.asm.signature;
/** /**
* A type signature parser to make a signature visitor visit an existing signature. * A type signature parser to make a signature visitor visit an existing
* signature.
* *
* @author Thomas Hallgren * @author Thomas Hallgren
* @author Eric Bruneton * @author Eric Bruneton
@@ -37,7 +46,8 @@ public class SignatureReader {
/** /**
* Constructs a {@link SignatureReader} for the given signature. * Constructs a {@link SignatureReader} for the given signature.
* *
* @param signature A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or * @param signature
* A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or
* <i>FieldTypeSignature</i>. * <i>FieldTypeSignature</i>.
*/ */
public SignatureReader(final String signature) { public SignatureReader(final String signature) {
@@ -45,15 +55,19 @@ public class SignatureReader {
} }
/** /**
* Makes the given visitor visit the signature of this {@link SignatureReader}. This signature * Makes the given visitor visit the signature of this
* is the one specified in the constructor (see {@link #SignatureReader(String) * {@link SignatureReader}. This signature is the one specified in the
* SignatureReader}). This method is intended to be called on a {@link SignatureReader} that was * constructor (see {@link #SignatureReader(String) SignatureReader}). This
* created using a <i>ClassSignature</i> (such as the <code>signature</code> parameter of the * method is intended to be called on a {@link SignatureReader} that was
* {@link org.objectweb.asm.ClassVisitor#visit ClassVisitor.visit} method) or a * created using a <i>ClassSignature</i> (such as the <code>signature</code>
* <i>MethodTypeSignature</i> (such as the <code>signature</code> parameter of the * parameter of the {@link org.objectweb.asm.ClassVisitor#visit
* {@link org.objectweb.asm.ClassVisitor#visitMethod ClassVisitor.visitMethod} method). * ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the
* <code>signature</code> parameter of the
* {@link org.objectweb.asm.ClassVisitor#visitMethod
* ClassVisitor.visitMethod} method).
* *
* @param v the visitor that must visit this signature. * @param v
* the visitor that must visit this signature.
*/ */
public void accept(final SignatureVisitor v) { public void accept(final SignatureVisitor v) {
String signature = this.signature; String signature = this.signature;
@@ -99,15 +113,18 @@ public class SignatureReader {
} }
/** /**
* Makes the given visitor visit the signature of this {@link SignatureReader}. This signature * Makes the given visitor visit the signature of this
* is the one specified in the constructor (see {@link #SignatureReader(String) * {@link SignatureReader}. This signature is the one specified in the
* SignatureReader}). This method is intended to be called on a {@link SignatureReader} that was * constructor (see {@link #SignatureReader(String) SignatureReader}). This
* created using a <i>FieldTypeSignature</i>, such as the <code>signature</code> parameter of * method is intended to be called on a {@link SignatureReader} that was
* the {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField} or * created using a <i>FieldTypeSignature</i>, such as the
* {@link org.objectweb.asm.MethodVisitor#visitLocalVariable MethodVisitor.visitLocalVariable} * <code>signature</code> parameter of the
* methods. * {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField}
* or {@link org.objectweb.asm.MethodVisitor#visitLocalVariable
* MethodVisitor.visitLocalVariable} methods.
* *
* @param v the visitor that must visit this signature. * @param v
* the visitor that must visit this signature.
*/ */
public void acceptType(final SignatureVisitor v) { public void acceptType(final SignatureVisitor v) {
parseType(this.signature, 0, v); parseType(this.signature, 0, v);
@@ -116,12 +133,16 @@ public class SignatureReader {
/** /**
* Parses a field type signature and makes the given visitor visit it. * Parses a field type signature and makes the given visitor visit it.
* *
* @param signature a string containing the signature that must be parsed. * @param signature
* @param pos index of the first character of the signature to parsed. * a string containing the signature that must be parsed.
* @param v the visitor that must visit this signature. * @param pos
* index of the first character of the signature to parsed.
* @param v
* the visitor that must visit this signature.
* @return the index of the first character after the parsed signature. * @return the index of the first character after the parsed signature.
*/ */
private static int parseType(final String signature, int pos, final SignatureVisitor v) { private static int parseType(final String signature, int pos,
final SignatureVisitor v) {
char c; char c;
int start, end; int start, end;
boolean visited, inner; boolean visited, inner;
@@ -191,10 +212,12 @@ public class SignatureReader {
break; break;
case '+': case '+':
case '-': case '-':
pos = parseType(signature, pos + 1, v.visitTypeArgument(c)); pos = parseType(signature, pos + 1,
v.visitTypeArgument(c));
break; break;
default: default:
pos = parseType(signature, pos, v.visitTypeArgument('=')); pos = parseType(signature, pos,
v.visitTypeArgument('='));
break; break;
} }
} }

View File

@@ -1,41 +1,54 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.signature; package org.objectweb.asm.signature;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
/** /**
* A visitor to visit a generic signature. The methods of this interface must be called in one of * A visitor to visit a generic signature. The methods of this interface must be
* the three following orders (the last one is the only valid order for a {@link SignatureVisitor} * called in one of the three following orders (the last one is the only valid
* that is returned by a method of this interface): * order for a {@link SignatureVisitor} that is returned by a method of this
* interface):
* <ul> * <ul>
* <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt> <tt>visitClassBound</tt>? * <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt>
* <tt>visitInterfaceBound</tt>* )* ( <tt>visitSuperClass</tt> <tt>visitInterface</tt>* )</li> * <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
* <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt> <tt>visitClassBound</tt>? * <tt>visitSuperClass</tt> <tt>visitInterface</tt>* )</li>
* <tt>visitInterfaceBound</tt>* )* ( <tt>visitParameterType</tt>* <tt>visitReturnType</tt> * <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt>
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
* <tt>visitParameterType</tt>* <tt>visitReturnType</tt>
* <tt>visitExceptionType</tt>* )</li> * <tt>visitExceptionType</tt>* )</li>
* <li><i>TypeSignature</i> = <tt>visitBaseType</tt> | <tt>visitTypeVariable</tt> | * <li><i>TypeSignature</i> = <tt>visitBaseType</tt> |
* <tt>visitArrayType</tt> | ( <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* ( * <tt>visitTypeVariable</tt> | <tt>visitArrayType</tt> | (
* <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt> ) )</li> * <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* (
* <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt>
* ) )</li>
* </ul> * </ul>
* *
* @author Thomas Hallgren * @author Thomas Hallgren
@@ -59,16 +72,17 @@ public abstract class SignatureVisitor {
public final static char INSTANCEOF = '='; public final static char INSTANCEOF = '=';
/** /**
* The ASM API version implemented by this visitor. The value of this field must be one of * The ASM API version implemented by this visitor. The value of this field
* {@link Opcodes#ASM4}. * must be one of {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* Constructs a new {@link SignatureVisitor}. * Constructs a new {@link SignatureVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
*/ */
public SignatureVisitor(final int api) { public SignatureVisitor(final int api) {
this.api = api; this.api = api;
@@ -77,9 +91,11 @@ public abstract class SignatureVisitor {
/** /**
* Visits a formal type parameter. * Visits a formal type parameter.
* *
* @param name the name of the formal parameter. * @param name
* the name of the formal parameter.
*/ */
public void visitFormalTypeParameter(String name) {} public void visitFormalTypeParameter(String name) {
}
/** /**
* Visits the class bound of the last visited formal type parameter. * Visits the class bound of the last visited formal type parameter.
@@ -102,7 +118,8 @@ public abstract class SignatureVisitor {
/** /**
* Visits the type of the super class. * Visits the type of the super class.
* *
* @return a non null visitor to visit the signature of the super class type. * @return a non null visitor to visit the signature of the super class
* type.
*/ */
public SignatureVisitor visitSuperclass() { public SignatureVisitor visitSuperclass() {
return this; return this;
@@ -147,49 +164,63 @@ public abstract class SignatureVisitor {
/** /**
* Visits a signature corresponding to a primitive type. * Visits a signature corresponding to a primitive type.
* *
* @param descriptor the descriptor of the primitive type, or 'V' for <tt>void</tt> . * @param descriptor
* the descriptor of the primitive type, or 'V' for <tt>void</tt>
* .
*/ */
public void visitBaseType(char descriptor) {} public void visitBaseType(char descriptor) {
}
/** /**
* Visits a signature corresponding to a type variable. * Visits a signature corresponding to a type variable.
* *
* @param name the name of the type variable. * @param name
* the name of the type variable.
*/ */
public void visitTypeVariable(String name) {} public void visitTypeVariable(String name) {
}
/** /**
* Visits a signature corresponding to an array type. * Visits a signature corresponding to an array type.
* *
* @return a non null visitor to visit the signature of the array element type. * @return a non null visitor to visit the signature of the array element
* type.
*/ */
public SignatureVisitor visitArrayType() { public SignatureVisitor visitArrayType() {
return this; return this;
} }
/** /**
* Starts the visit of a signature corresponding to a class or interface type. * Starts the visit of a signature corresponding to a class or interface
* type.
* *
* @param name the internal name of the class or interface. * @param name
* the internal name of the class or interface.
*/ */
public void visitClassType(String name) {} public void visitClassType(String name) {
}
/** /**
* Visits an inner class. * Visits an inner class.
* *
* @param name the local name of the inner class in its enclosing class. * @param name
* the local name of the inner class in its enclosing class.
*/ */
public void visitInnerClassType(String name) {} public void visitInnerClassType(String name) {
}
/** /**
* Visits an unbounded type argument of the last visited class or inner class type. * Visits an unbounded type argument of the last visited class or inner
* class type.
*/ */
public void visitTypeArgument() {} public void visitTypeArgument() {
}
/** /**
* Visits a type argument of the last visited class or inner class type. * Visits a type argument of the last visited class or inner class type.
* *
* @param wildcard '+', '-' or '='. * @param wildcard
* '+', '-' or '='.
* @return a non null visitor to visit the signature of the type argument. * @return a non null visitor to visit the signature of the type argument.
*/ */
public SignatureVisitor visitTypeArgument(char wildcard) { public SignatureVisitor visitTypeArgument(char wildcard) {
@@ -199,5 +230,6 @@ public abstract class SignatureVisitor {
/** /**
* Ends the visit of a signature corresponding to a class or interface type. * Ends the visit of a signature corresponding to a class or interface type.
*/ */
public void visitEnd() {} public void visitEnd() {
}
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.signature; package org.objectweb.asm.signature;
@@ -47,9 +55,10 @@ public class SignatureWriter extends SignatureVisitor {
private boolean hasParameters; private boolean hasParameters;
/** /**
* Stack used to keep track of class types that have arguments. Each element of this stack is a * Stack used to keep track of class types that have arguments. Each element
* boolean encoded in one bit. The top of the stack is the lowest order bit. Pushing false = *2, * of this stack is a boolean encoded in one bit. The top of the stack is
* pushing true = *2+1, popping = /2. * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping =
* /2.
*/ */
private int argumentStack; private int argumentStack;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -27,8 +35,8 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a bytecode instruction. <i>An instruction can appear at most once in at * A node that represents a bytecode instruction. <i>An instruction can appear
* most one {@link InsnList} at a time</i>. * at most once in at most one {@link InsnList} at a time</i>.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -130,16 +138,18 @@ public abstract class AbstractInsnNode {
AbstractInsnNode next; AbstractInsnNode next;
/** /**
* Index of this instruction in the list to which it belongs. The value of this field is correct * Index of this instruction in the list to which it belongs. The value of
* only when {@link InsnList#cache} is not null. A value of -1 indicates that this instruction * this field is correct only when {@link InsnList#cache} is not null. A
* does not belong to any {@link InsnList}. * value of -1 indicates that this instruction does not belong to any
* {@link InsnList}.
*/ */
int index; int index;
/** /**
* Constructs a new {@link AbstractInsnNode}. * Constructs a new {@link AbstractInsnNode}.
* *
* @param opcode the opcode of the instruction to be constructed. * @param opcode
* the opcode of the instruction to be constructed.
*/ */
protected AbstractInsnNode(final int opcode) { protected AbstractInsnNode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;
@@ -158,25 +168,28 @@ public abstract class AbstractInsnNode {
/** /**
* Returns the type of this instruction. * Returns the type of this instruction.
* *
* @return the type of this instruction, i.e. one the constants defined in this class. * @return the type of this instruction, i.e. one the constants defined in
* this class.
*/ */
public abstract int getType(); public abstract int getType();
/** /**
* Returns the previous instruction in the list to which this instruction belongs, if any. * Returns the previous instruction in the list to which this instruction
* belongs, if any.
* *
* @return the previous instruction in the list to which this instruction belongs, if any. May * @return the previous instruction in the list to which this instruction
* be <tt>null</tt>. * belongs, if any. May be <tt>null</tt>.
*/ */
public AbstractInsnNode getPrevious() { public AbstractInsnNode getPrevious() {
return prev; return prev;
} }
/** /**
* Returns the next instruction in the list to which this instruction belongs, if any. * Returns the next instruction in the list to which this instruction
* belongs, if any.
* *
* @return the next instruction in the list to which this instruction belongs, if any. May be * @return the next instruction in the list to which this instruction
* <tt>null</tt>. * belongs, if any. May be <tt>null</tt>.
*/ */
public AbstractInsnNode getNext() { public AbstractInsnNode getNext() {
return next; return next;
@@ -185,38 +198,47 @@ public abstract class AbstractInsnNode {
/** /**
* Makes the given code visitor visit this instruction. * Makes the given code visitor visit this instruction.
* *
* @param cv a code visitor. * @param cv
* a code visitor.
*/ */
public abstract void accept(final MethodVisitor cv); public abstract void accept(final MethodVisitor cv);
/** /**
* Returns a copy of this instruction. * Returns a copy of this instruction.
* *
* @param labels a map from LabelNodes to cloned LabelNodes. * @param labels
* @return a copy of this instruction. The returned instruction does not belong to any * a map from LabelNodes to cloned LabelNodes.
* {@link InsnList}. * @return a copy of this instruction. The returned instruction does not
* belong to any {@link InsnList}.
*/ */
public abstract AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels); public abstract AbstractInsnNode clone(
final Map<LabelNode, LabelNode> labels);
/** /**
* Returns the clone of the given label. * Returns the clone of the given label.
* *
* @param label a label. * @param label
* @param map a map from LabelNodes to cloned LabelNodes. * a label.
* @param map
* a map from LabelNodes to cloned LabelNodes.
* @return the clone of the given label. * @return the clone of the given label.
*/ */
static LabelNode clone(final LabelNode label, final Map<LabelNode, LabelNode> map) { static LabelNode clone(final LabelNode label,
final Map<LabelNode, LabelNode> map) {
return map.get(label); return map.get(label);
} }
/** /**
* Returns the clones of the given labels. * Returns the clones of the given labels.
* *
* @param labels a list of labels. * @param labels
* @param map a map from LabelNodes to cloned LabelNodes. * a list of labels.
* @param map
* a map from LabelNodes to cloned LabelNodes.
* @return the clones of the given labels. * @return the clones of the given labels.
*/ */
static LabelNode[] clone(final List<LabelNode> labels, final Map<LabelNode, LabelNode> map) { static LabelNode[] clone(final List<LabelNode> labels,
final Map<LabelNode, LabelNode> map) {
LabelNode[] clones = new LabelNode[labels.size()]; LabelNode[] clones = new LabelNode[labels.size()];
for (int i = 0; i < clones.length; ++i) { for (int i = 0; i < clones.length; ++i) {
clones[i] = map.get(labels.get(i)); clones[i] = map.get(labels.get(i));

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -27,14 +35,15 @@ import java.util.List;
import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
// import cn.edu.pku.dpartner.comm.api.context.DelayLogger; //import cn.edu.pku.dpartner.comm.api.context.DelayLogger;
/** /**
* A node that represents an annotationn. * A node that represents an annotationn.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class AnnotationNode extends AnnotationVisitor { public class AnnotationNode extends AnnotationVisitor
{
/** /**
* The class descriptor of the annotation class. * The class descriptor of the annotation class.
@@ -42,34 +51,42 @@ public class AnnotationNode extends AnnotationVisitor {
public String desc; public String desc;
/** /**
* The name value pairs of this annotation. Each name value pair is stored as two consecutive * The name value pairs of this annotation. Each name value pair is stored
* elements in the list. The name is a {@link String}, and the value may be a {@link Byte}, * as two consecutive elements in the list. The name is a {@link String},
* {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}, {@link Long}, * and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
* {@link Float}, {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an two * {@link Short}, {@link Integer}, {@link Long}, {@link Float},
* elements String array (for enumeration values), a {@link AnnotationNode}, or a {@link List} * {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an
* of values of one of the preceding types. The list may be <tt>null</tt> if there is no name * two elements String array (for enumeration values), a
* value pair. * {@link AnnotationNode}, or a {@link List} of values of one of the
* preceding types. The list may be <tt>null</tt> if there is no name value
* pair.
*/ */
public List<Object> values; public List<Object> values;
/** /**
* Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this constructor</i>. * Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this
* Instead, they must use the {@link #AnnotationNode(int, String)} version. * constructor</i>. Instead, they must use the
* {@link #AnnotationNode(int, String)} version.
* *
* @param desc the class descriptor of the annotation class. * @param desc
* the class descriptor of the annotation class.
*/ */
public AnnotationNode(final String desc) { public AnnotationNode(final String desc)
{
this(Opcodes.ASM4, desc); this(Opcodes.ASM4, desc);
} }
/** /**
* Constructs a new {@link AnnotationNode}. * Constructs a new {@link AnnotationNode}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param desc the class descriptor of the annotation class. * of {@link Opcodes#ASM4}.
* @param desc
* the class descriptor of the annotation class.
*/ */
public AnnotationNode(final int api, final String desc) { public AnnotationNode(final int api, final String desc)
{
super(api); super(api);
this.desc = desc; this.desc = desc;
} }
@@ -77,9 +94,11 @@ public class AnnotationNode extends AnnotationVisitor {
/** /**
* Constructs a new {@link AnnotationNode} to visit an array value. * Constructs a new {@link AnnotationNode} to visit an array value.
* *
* @param values where the visited values must be stored. * @param values
* where the visited values must be stored.
*/ */
AnnotationNode(final List<Object> values) { AnnotationNode(final List<Object> values)
{
super(Opcodes.ASM4); super(Opcodes.ASM4);
this.values = values; this.values = values;
} }
@@ -89,11 +108,14 @@ public class AnnotationNode extends AnnotationVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public void visit(final String name, final Object value) { public void visit(final String name, final Object value)
if (values == null) { {
if (values == null)
{
values = new ArrayList<Object>(this.desc != null ? 2 : 1); values = new ArrayList<Object>(this.desc != null ? 2 : 1);
} }
if (this.desc != null) { if (this.desc != null)
{
values.add(name); values.add(name);
} }
// else // else
@@ -105,22 +127,31 @@ public class AnnotationNode extends AnnotationVisitor {
} }
@Override @Override
public void visitEnum(final String name, final String desc, final String value) { public void visitEnum(final String name, final String desc,
if (values == null) { final String value)
{
if (values == null)
{
values = new ArrayList<Object>(this.desc != null ? 2 : 1); values = new ArrayList<Object>(this.desc != null ? 2 : 1);
} }
if (this.desc != null) { if (this.desc != null)
{
values.add(name); values.add(name);
} }
values.add(new String[] {desc, value}); values.add(new String[]
{ desc, value });
} }
@Override @Override
public AnnotationVisitor visitAnnotation(final String name, final String desc) { public AnnotationVisitor visitAnnotation(final String name,
if (values == null) { final String desc)
{
if (values == null)
{
values = new ArrayList<Object>(this.desc != null ? 2 : 1); values = new ArrayList<Object>(this.desc != null ? 2 : 1);
} }
if (this.desc != null) { if (this.desc != null)
{
values.add(name); values.add(name);
} }
AnnotationNode annotation = new AnnotationNode(desc); AnnotationNode annotation = new AnnotationNode(desc);
@@ -129,11 +160,14 @@ public class AnnotationNode extends AnnotationVisitor {
} }
@Override @Override
public AnnotationVisitor visitArray(final String name) { public AnnotationVisitor visitArray(final String name)
if (values == null) { {
if (values == null)
{
values = new ArrayList<Object>(this.desc != null ? 2 : 1); values = new ArrayList<Object>(this.desc != null ? 2 : 1);
} }
if (this.desc != null) { if (this.desc != null)
{
values.add(name); values.add(name);
} }
List<Object> array = new ArrayList<Object>(); List<Object> array = new ArrayList<Object>();
@@ -142,39 +176,54 @@ public class AnnotationNode extends AnnotationVisitor {
} }
@Override @Override
public void visitEnd() {} public void visitEnd()
{
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Accept methods // Accept methods
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Checks that this annotation node is compatible with the given ASM API version. This methods * Checks that this annotation node is compatible with the given ASM API
* checks that this node, and all its nodes recursively, do not contain elements that were * version. This methods checks that this node, and all its nodes
* introduced in more recent versions of the ASM API than the given version. * recursively, do not contain elements that were introduced in more recent
* versions of the ASM API than the given version.
* *
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}. * @param api
* an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/ */
public void check(final int api) { public void check(final int api)
{
// nothing to do // nothing to do
} }
/** /**
* Makes the given visitor visit this annotation. * Makes the given visitor visit this annotation.
* *
* @param av an annotation visitor. Maybe <tt>null</tt>. * @param av
* an annotation visitor. Maybe <tt>null</tt>.
*/ */
public void accept(final AnnotationVisitor av) { public void accept(final AnnotationVisitor av)
if (av != null) { {
if (values != null) { if (av != null)
for (int i = 0; i < values.size(); i += 2) { {
if (values.get(i) == null) { if (values != null)
System.out.println("[AnnotationNode] name is null!!!!!"); {
for (int i = 0; i < values.size(); i += 2)
{
if (values.get(i) == null)
{
System.out
.println("[AnnotationNode] name is null!!!!!");
// DelayLogger.logValue(values); // DelayLogger.logValue(values);
System.out.flush(); System.out.flush();
try { try
{
Thread.sleep(2000); Thread.sleep(2000);
} catch (InterruptedException e) { }
catch (InterruptedException e)
{
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
@@ -191,26 +240,40 @@ public class AnnotationNode extends AnnotationVisitor {
/** /**
* Makes the given visitor visit a given annotation value. * Makes the given visitor visit a given annotation value.
* *
* @param av an annotation visitor. Maybe <tt>null</tt>. * @param av
* @param name the value name. * an annotation visitor. Maybe <tt>null</tt>.
* @param value the actual value. * @param name
* the value name.
* @param value
* the actual value.
*/ */
static void accept(final AnnotationVisitor av, final String name, final Object value) { static void accept(final AnnotationVisitor av, final String name,
if (av != null) { final Object value)
if (value instanceof String[]) { {
if (av != null)
{
if (value instanceof String[])
{
String[] typeconst = (String[]) value; String[] typeconst = (String[]) value;
av.visitEnum(name, typeconst[0], typeconst[1]); av.visitEnum(name, typeconst[0], typeconst[1]);
} else if (value instanceof AnnotationNode) { }
else if (value instanceof AnnotationNode)
{
AnnotationNode an = (AnnotationNode) value; AnnotationNode an = (AnnotationNode) value;
an.accept(av.visitAnnotation(name, an.desc)); an.accept(av.visitAnnotation(name, an.desc));
} else if (value instanceof List) { }
else if (value instanceof List)
{
AnnotationVisitor v = av.visitArray(name); AnnotationVisitor v = av.visitArray(name);
List<?> array = (List<?>) value; List<?> array = (List<?>) value;
for (int j = 0; j < array.size(); ++j) { for (int j = 0; j < array.size(); ++j)
{
accept(v, null, array.get(j)); accept(v, null, array.get(j));
} }
v.visitEnd(); v.visitEnd();
} else { }
else
{
av.visit(name, value); av.visit(name, value);
} }
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -45,14 +53,14 @@ public class ClassNode extends ClassVisitor {
public int version; public int version;
/** /**
* The class's access flags (see {@link org.objectweb.asm.Opcodes}). This field also indicates * The class's access flags (see {@link org.objectweb.asm.Opcodes}). This
* if the class is deprecated. * field also indicates if the class is deprecated.
*/ */
public int access; public int access;
/** /**
* The internal name of the class (see {@link org.objectweb.asm.Type#getInternalName() * The internal name of the class (see
* getInternalName}). * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
*/ */
public String name; public String name;
@@ -62,50 +70,53 @@ public class ClassNode extends ClassVisitor {
public String signature; public String signature;
/** /**
* The internal of name of the super class (see {@link org.objectweb.asm.Type#getInternalName() * The internal of name of the super class (see
* getInternalName}). For interfaces, the super class is {@link Object}. May be <tt>null</tt>, * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). For
* but only for the {@link Object} class. * interfaces, the super class is {@link Object}. May be <tt>null</tt>, but
* only for the {@link Object} class.
*/ */
public String superName; public String superName;
/** /**
* The internal names of the class's interfaces (see * The internal names of the class's interfaces (see
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). This list is a list of * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). This
* {@link String} objects. * list is a list of {@link String} objects.
*/ */
public List<String> interfaces; public List<String> interfaces;
/** /**
* The name of the source file from which this class was compiled. May be <tt>null</tt>. * The name of the source file from which this class was compiled. May be
* <tt>null</tt>.
*/ */
public String sourceFile; public String sourceFile;
/** /**
* Debug information to compute the correspondence between source and compiled elements of the * Debug information to compute the correspondence between source and
* class. May be <tt>null</tt>. * compiled elements of the class. May be <tt>null</tt>.
*/ */
public String sourceDebug; public String sourceDebug;
/** /**
* The internal name of the enclosing class of the class. May be <tt>null</tt>. * The internal name of the enclosing class of the class. May be
* <tt>null</tt>.
*/ */
public String outerClass; public String outerClass;
/** /**
* The name of the method that contains the class, or <tt>null</tt> if the class is not enclosed * The name of the method that contains the class, or <tt>null</tt> if the
* in a method. * class is not enclosed in a method.
*/ */
public String outerMethod; public String outerMethod;
/** /**
* The descriptor of the method that contains the class, or <tt>null</tt> if the class is not * The descriptor of the method that contains the class, or <tt>null</tt> if
* enclosed in a method. * the class is not enclosed in a method.
*/ */
public String outerMethodDesc; public String outerMethodDesc;
/** /**
* The runtime visible annotations of this class. This list is a list of {@link AnnotationNode} * The runtime visible annotations of this class. This list is a list of
* objects. May be <tt>null</tt>. * {@link AnnotationNode} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label visible * @label visible
@@ -122,38 +133,41 @@ public class ClassNode extends ClassVisitor {
public List<AnnotationNode> invisibleAnnotations; public List<AnnotationNode> invisibleAnnotations;
/** /**
* The non standard attributes of this class. This list is a list of {@link Attribute} objects. * The non standard attributes of this class. This list is a list of
* May be <tt>null</tt>. * {@link Attribute} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.Attribute * @associates org.objectweb.asm.Attribute
*/ */
public List<Attribute> attrs; public List<Attribute> attrs;
/** /**
* Informations about the inner classes of this class. This list is a list of * Informations about the inner classes of this class. This list is a list
* {@link InnerClassNode} objects. * of {@link InnerClassNode} objects.
* *
* @associates org.objectweb.asm.tree.InnerClassNode * @associates org.objectweb.asm.tree.InnerClassNode
*/ */
public List<InnerClassNode> innerClasses; public List<InnerClassNode> innerClasses;
/** /**
* The fields of this class. This list is a list of {@link FieldNode} objects. * The fields of this class. This list is a list of {@link FieldNode}
* objects.
* *
* @associates org.objectweb.asm.tree.FieldNode * @associates org.objectweb.asm.tree.FieldNode
*/ */
public List<FieldNode> fields; public List<FieldNode> fields;
/** /**
* The methods of this class. This list is a list of {@link MethodNode} objects. * The methods of this class. This list is a list of {@link MethodNode}
* objects.
* *
* @associates org.objectweb.asm.tree.MethodNode * @associates org.objectweb.asm.tree.MethodNode
*/ */
public List<MethodNode> methods; public List<MethodNode> methods;
/** /**
* Constructs a new {@link ClassNode}. <i>Subclasses must not use this constructor</i>. Instead, * Constructs a new {@link ClassNode}. <i>Subclasses must not use this
* they must use the {@link #ClassNode(int)} version. * constructor</i>. Instead, they must use the {@link #ClassNode(int)}
* version.
*/ */
public ClassNode() { public ClassNode() {
this(Opcodes.ASM4); this(Opcodes.ASM4);
@@ -162,8 +176,9 @@ public class ClassNode extends ClassVisitor {
/** /**
* Constructs a new {@link ClassNode}. * Constructs a new {@link ClassNode}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
*/ */
public ClassNode(final int api) { public ClassNode(final int api) {
super(api); super(api);
@@ -179,7 +194,8 @@ public class ClassNode extends ClassVisitor {
@Override @Override
public void visit(final int version, final int access, final String name, public void visit(final int version, final int access, final String name,
final String signature, final String superName, final String[] interfaces) { final String signature, final String superName,
final String[] interfaces) {
this.version = version; this.version = version;
this.access = access; this.access = access;
this.name = name; this.name = name;
@@ -197,14 +213,16 @@ public class ClassNode extends ClassVisitor {
} }
@Override @Override
public void visitOuterClass(final String owner, final String name, final String desc) { public void visitOuterClass(final String owner, final String name,
final String desc) {
outerClass = owner; outerClass = owner;
outerMethod = name; outerMethod = name;
outerMethodDesc = desc; outerMethodDesc = desc;
} }
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc); AnnotationNode an = new AnnotationNode(desc);
if (visible) { if (visible) {
if (visibleAnnotations == null) { if (visibleAnnotations == null) {
@@ -229,41 +247,46 @@ public class ClassNode extends ClassVisitor {
} }
@Override @Override
public void visitInnerClass(final String name, final String outerName, final String innerName, public void visitInnerClass(final String name, final String outerName,
final int access) { final String innerName, final int access) {
InnerClassNode icn = new InnerClassNode(name, outerName, innerName, access); InnerClassNode icn = new InnerClassNode(name, outerName, innerName,
access);
innerClasses.add(icn); innerClasses.add(icn);
} }
@Override @Override
public FieldVisitor visitField(final int access, final String name, final String desc, public FieldVisitor visitField(final int access, final String name,
final String signature, final Object value) { final String desc, final String signature, final Object value) {
FieldNode fn = new FieldNode(access, name, desc, signature, value); FieldNode fn = new FieldNode(access, name, desc, signature, value);
fields.add(fn); fields.add(fn);
return fn; return fn;
} }
@Override @Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, public MethodVisitor visitMethod(final int access, final String name,
final String signature, final String[] exceptions) { final String desc, final String signature, final String[] exceptions) {
MethodNode mn = new MethodNode(access, name, desc, signature, exceptions); MethodNode mn = new MethodNode(access, name, desc, signature,
exceptions);
methods.add(mn); methods.add(mn);
return mn; return mn;
} }
@Override @Override
public void visitEnd() {} public void visitEnd() {
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Accept method // Accept method
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Checks that this class node is compatible with the given ASM API version. This methods checks * Checks that this class node is compatible with the given ASM API version.
* that this node, and all its nodes recursively, do not contain elements that were introduced * This methods checks that this node, and all its nodes recursively, do not
* in more recent versions of the ASM API than the given version. * contain elements that were introduced in more recent versions of the ASM
* API than the given version.
* *
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}. * @param api
* an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/ */
public void check(final int api) { public void check(final int api) {
// nothing to do // nothing to do
@@ -272,7 +295,8 @@ public class ClassNode extends ClassVisitor {
/** /**
* Makes the given class visitor visit this class. * Makes the given class visitor visit this class.
* *
* @param cv a class visitor. * @param cv
* a class visitor.
*/ */
public void accept(final ClassVisitor cv) { public void accept(final ClassVisitor cv) {
// visits header // visits header

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -26,8 +34,8 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a field instruction. A field instruction is an instruction that loads or * A node that represents a field instruction. A field instruction is an
* stores the value of a field of an object. * instruction that loads or stores the value of a field of an object.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -52,15 +60,20 @@ public class FieldInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link FieldInsnNode}. * Constructs a new {@link FieldInsnNode}.
* *
* @param opcode the opcode of the type instruction to be constructed. This opcode must be * @param opcode
* GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * the opcode of the type instruction to be constructed. This
* @param owner the internal name of the field's owner class (see * opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). * @param owner
* @param name the field's name. * the internal name of the field's owner class (see
* @param desc the field's descriptor (see {@link org.objectweb.asm.Type}). * {@link org.objectweb.asm.Type#getInternalName()
* getInternalName}).
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link org.objectweb.asm.Type}).
*/ */
public FieldInsnNode(final int opcode, final String owner, final String name, public FieldInsnNode(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
super(opcode); super(opcode);
this.owner = owner; this.owner = owner;
this.name = name; this.name = name;
@@ -70,8 +83,9 @@ public class FieldInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode the new instruction opcode. This opcode must be GETSTATIC, PUTSTATIC, GETFIELD * @param opcode
* or PUTFIELD. * the new instruction opcode. This opcode must be GETSTATIC,
* PUTSTATIC, GETFIELD or PUTFIELD.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -38,8 +46,8 @@ import org.objectweb.asm.Opcodes;
public class FieldNode extends FieldVisitor { public class FieldNode extends FieldVisitor {
/** /**
* The field's access flags (see {@link org.objectweb.asm.Opcodes}). This field also indicates * The field's access flags (see {@link org.objectweb.asm.Opcodes}). This
* if the field is synthetic and/or deprecated. * field also indicates if the field is synthetic and/or deprecated.
*/ */
public int access; public int access;
@@ -59,15 +67,15 @@ public class FieldNode extends FieldVisitor {
public String signature; public String signature;
/** /**
* The field's initial value. This field, which may be <tt>null</tt> if the field does not have * The field's initial value. This field, which may be <tt>null</tt> if the
* an initial value, must be an {@link Integer}, a {@link Float}, a {@link Long}, a * field does not have an initial value, must be an {@link Integer}, a
* {@link Double} or a {@link String}. * {@link Float}, a {@link Long}, a {@link Double} or a {@link String}.
*/ */
public Object value; public Object value;
/** /**
* The runtime visible annotations of this field. This list is a list of {@link AnnotationNode} * The runtime visible annotations of this field. This list is a list of
* objects. May be <tt>null</tt>. * {@link AnnotationNode} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label visible * @label visible
@@ -84,48 +92,67 @@ public class FieldNode extends FieldVisitor {
public List<AnnotationNode> invisibleAnnotations; public List<AnnotationNode> invisibleAnnotations;
/** /**
* The non standard attributes of this field. This list is a list of {@link Attribute} objects. * The non standard attributes of this field. This list is a list of
* May be <tt>null</tt>. * {@link Attribute} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.Attribute * @associates org.objectweb.asm.Attribute
*/ */
public List<Attribute> attrs; public List<Attribute> attrs;
/** /**
* Constructs a new {@link FieldNode}. <i>Subclasses must not use this constructor</i>. Instead, * Constructs a new {@link FieldNode}. <i>Subclasses must not use this
* they must use the {@link #FieldNode(int, int, String, String, String, Object)} version. * constructor</i>. Instead, they must use the
* {@link #FieldNode(int, int, String, String, String, Object)} version.
* *
* @param access the field's access flags (see {@link org.objectweb.asm.Opcodes}). This * @param access
* parameter also indicates if the field is synthetic and/or deprecated. * the field's access flags (see
* @param name the field's name. * {@link org.objectweb.asm.Opcodes}). This parameter also
* @param desc the field's descriptor (see {@link org.objectweb.asm.Type Type}). * indicates if the field is synthetic and/or deprecated.
* @param signature the field's signature. * @param name
* @param value the field's initial value. This parameter, which may be <tt>null</tt> if the * the field's name.
* field does not have an initial value, must be an {@link Integer}, a {@link Float}, a * @param desc
* {@link Long}, a {@link Double} or a {@link String}. * the field's descriptor (see {@link org.objectweb.asm.Type
* Type}).
* @param signature
* the field's signature.
* @param value
* the field's initial value. This parameter, which may be
* <tt>null</tt> if the field does not have an initial value,
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String}.
*/ */
public FieldNode(final int access, final String name, final String desc, final String signature, public FieldNode(final int access, final String name, final String desc,
final Object value) { final String signature, final Object value) {
this(Opcodes.ASM4, access, name, desc, signature, value); this(Opcodes.ASM4, access, name, desc, signature, value);
} }
/** /**
* Constructs a new {@link FieldNode}. <i>Subclasses must not use this constructor</i>. Instead, * Constructs a new {@link FieldNode}. <i>Subclasses must not use this
* they must use the {@link #FieldNode(int, int, String, String, String, Object)} version. * constructor</i>. Instead, they must use the
* {@link #FieldNode(int, int, String, String, String, Object)} version.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param access the field's access flags (see {@link org.objectweb.asm.Opcodes}). This * of {@link Opcodes#ASM4}.
* parameter also indicates if the field is synthetic and/or deprecated. * @param access
* @param name the field's name. * the field's access flags (see
* @param desc the field's descriptor (see {@link org.objectweb.asm.Type Type}). * {@link org.objectweb.asm.Opcodes}). This parameter also
* @param signature the field's signature. * indicates if the field is synthetic and/or deprecated.
* @param value the field's initial value. This parameter, which may be <tt>null</tt> if the * @param name
* field does not have an initial value, must be an {@link Integer}, a {@link Float}, a * the field's name.
* {@link Long}, a {@link Double} or a {@link String}. * @param desc
* the field's descriptor (see {@link org.objectweb.asm.Type
* Type}).
* @param signature
* the field's signature.
* @param value
* the field's initial value. This parameter, which may be
* <tt>null</tt> if the field does not have an initial value,
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String}.
*/ */
public FieldNode(final int api, final int access, final String name, final String desc, public FieldNode(final int api, final int access, final String name,
final String signature, final Object value) { final String desc, final String signature, final Object value) {
super(api); super(api);
this.access = access; this.access = access;
this.name = name; this.name = name;
@@ -139,7 +166,8 @@ public class FieldNode extends FieldVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc); AnnotationNode an = new AnnotationNode(desc);
if (visible) { if (visible) {
if (visibleAnnotations == null) { if (visibleAnnotations == null) {
@@ -164,18 +192,21 @@ public class FieldNode extends FieldVisitor {
} }
@Override @Override
public void visitEnd() {} public void visitEnd() {
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Accept methods // Accept methods
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Checks that this field node is compatible with the given ASM API version. This methods checks * Checks that this field node is compatible with the given ASM API version.
* that this node, and all its nodes recursively, do not contain elements that were introduced * This methods checks that this node, and all its nodes recursively, do not
* in more recent versions of the ASM API than the given version. * contain elements that were introduced in more recent versions of the ASM
* API than the given version.
* *
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}. * @param api
* an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/ */
public void check(final int api) { public void check(final int api) {
// nothing to do // nothing to do
@@ -184,7 +215,8 @@ public class FieldNode extends FieldVisitor {
/** /**
* Makes the given class visitor visit this field. * Makes the given class visitor visit this field.
* *
* @param cv a class visitor. * @param cv
* a class visitor.
*/ */
public void accept(final ClassVisitor cv) { public void accept(final ClassVisitor cv) {
FieldVisitor fv = cv.visitField(access, name, desc, signature, value); FieldVisitor fv = cv.visitField(access, name, desc, signature, value);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -30,39 +38,42 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
/** /**
* A node that represents a stack map frame. These nodes are pseudo instruction nodes in order to be * A node that represents a stack map frame. These nodes are pseudo instruction
* inserted in an instruction list. In fact these nodes must(*) be inserted <i>just before</i> any * nodes in order to be inserted in an instruction list. In fact these nodes
* instruction node <b>i</b> that follows an unconditionnal branch instruction such as GOTO or * must(*) be inserted <i>just before</i> any instruction node <b>i</b> that
* THROW, that is the target of a jump instruction, or that starts an exception handler block. The * follows an unconditionnal branch instruction such as GOTO or THROW, that is
* stack map frame types must describe the values of the local variables and of the operand stack * the target of a jump instruction, or that starts an exception handler block.
* elements <i>just before</i> <b>i</b> is executed. <br> * The stack map frame types must describe the values of the local variables and
* of the operand stack elements <i>just before</i> <b>i</b> is executed. <br>
* <br> * <br>
* (*) this is mandatory only for classes whose version is greater than or equal to * (*) this is mandatory only for classes whose version is greater than or equal
* {@link Opcodes#V1_6 V1_6}. * to {@link Opcodes#V1_6 V1_6}.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class FrameNode extends AbstractInsnNode { public class FrameNode extends AbstractInsnNode {
/** /**
* The type of this frame. Must be {@link Opcodes#F_NEW} for expanded frames, or * The type of this frame. Must be {@link Opcodes#F_NEW} for expanded
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
* {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
* frames. * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
*/ */
public int type; public int type;
/** /**
* The types of the local variables of this stack map frame. Elements of this list can be * The types of the local variables of this stack map frame. Elements of
* Integer, String or LabelNode objects (for primitive, reference and uninitialized types * this list can be Integer, String or LabelNode objects (for primitive,
* respectively - see {@link MethodVisitor}). * reference and uninitialized types respectively - see
* {@link MethodVisitor}).
*/ */
public List<Object> local; public List<Object> local;
/** /**
* The types of the operand stack elements of this stack map frame. Elements of this list can be * The types of the operand stack elements of this stack map frame. Elements
* Integer, String or LabelNode objects (for primitive, reference and uninitialized types * of this list can be Integer, String or LabelNode objects (for primitive,
* respectively - see {@link MethodVisitor}). * reference and uninitialized types respectively - see
* {@link MethodVisitor}).
*/ */
public List<Object> stack; public List<Object> stack;
@@ -73,21 +84,29 @@ public class FrameNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link FrameNode}. * Constructs a new {@link FrameNode}.
* *
* @param type the type of this frame. Must be {@link Opcodes#F_NEW} for expanded frames, or * @param type
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, * the type of this frame. Must be {@link Opcodes#F_NEW} for
* {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for * expanded frames, or {@link Opcodes#F_FULL},
* compressed frames. * {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
* @param nLocal number of local variables of this stack map frame. * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
* @param local the types of the local variables of this stack map frame. Elements of this list * {@link Opcodes#F_SAME1} for compressed frames.
* can be Integer, String or LabelNode objects (for primitive, reference and * @param nLocal
* uninitialized types respectively - see {@link MethodVisitor}). * number of local variables of this stack map frame.
* @param nStack number of operand stack elements of this stack map frame. * @param local
* @param stack the types of the operand stack elements of this stack map frame. Elements of * the types of the local variables of this stack map frame.
* this list can be Integer, String or LabelNode objects (for primitive, reference and * Elements of this list can be Integer, String or LabelNode
* uninitialized types respectively - see {@link MethodVisitor}). * objects (for primitive, reference and uninitialized types
* respectively - see {@link MethodVisitor}).
* @param nStack
* number of operand stack elements of this stack map frame.
* @param stack
* the types of the operand stack elements of this stack map
* frame. Elements of this list can be Integer, String or
* LabelNode objects (for primitive, reference and uninitialized
* types respectively - see {@link MethodVisitor}).
*/ */
public FrameNode(final int type, final int nLocal, final Object[] local, final int nStack, public FrameNode(final int type, final int nLocal, final Object[] local,
final Object[] stack) { final int nStack, final Object[] stack) {
super(-1); super(-1);
this.type = type; this.type = type;
switch (type) { switch (type) {
@@ -118,14 +137,16 @@ public class FrameNode extends AbstractInsnNode {
/** /**
* Makes the given visitor visit this stack map frame. * Makes the given visitor visit this stack map frame.
* *
* @param mv a method visitor. * @param mv
* a method visitor.
*/ */
@Override @Override
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
switch (type) { switch (type) {
case Opcodes.F_NEW: case Opcodes.F_NEW:
case Opcodes.F_FULL: case Opcodes.F_FULL:
mv.visitFrame(type, local.size(), asArray(local), stack.size(), asArray(stack)); mv.visitFrame(type, local.size(), asArray(local), stack.size(),
asArray(stack));
break; break;
case Opcodes.F_APPEND: case Opcodes.F_APPEND:
mv.visitFrame(type, local.size(), asArray(local), 0, null); mv.visitFrame(type, local.size(), asArray(local), 0, null);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -46,8 +54,10 @@ public class IincInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link IincInsnNode}. * Constructs a new {@link IincInsnNode}.
* *
* @param var index of the local variable to be incremented. * @param var
* @param incr increment amount to increment the local variable by. * index of the local variable to be incremented.
* @param incr
* increment amount to increment the local variable by.
*/ */
public IincInsnNode(final int var, final int incr) { public IincInsnNode(final int var, final int incr) {
super(Opcodes.IINC); super(Opcodes.IINC);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -31,43 +39,50 @@ import org.objectweb.asm.ClassVisitor;
public class InnerClassNode { public class InnerClassNode {
/** /**
* The internal name of an inner class (see {@link org.objectweb.asm.Type#getInternalName() * The internal name of an inner class (see
* getInternalName}). * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
*/ */
public String name; public String name;
/** /**
* The internal name of the class to which the inner class belongs (see * The internal name of the class to which the inner class belongs (see
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). May be <tt>null</tt>. * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public String outerName; public String outerName;
/** /**
* The (simple) name of the inner class inside its enclosing class. May be <tt>null</tt> for * The (simple) name of the inner class inside its enclosing class. May be
* anonymous inner classes. * <tt>null</tt> for anonymous inner classes.
*/ */
public String innerName; public String innerName;
/** /**
* The access flags of the inner class as originally declared in the enclosing class. * The access flags of the inner class as originally declared in the
* enclosing class.
*/ */
public int access; public int access;
/** /**
* Constructs a new {@link InnerClassNode}. * Constructs a new {@link InnerClassNode}.
* *
* @param name the internal name of an inner class (see * @param name
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). * the internal name of an inner class (see
* @param outerName the internal name of the class to which the inner class belongs (see * {@link org.objectweb.asm.Type#getInternalName()
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). May be * getInternalName}).
* <tt>null</tt>. * @param outerName
* @param innerName the (simple) name of the inner class inside its enclosing class. May be * the internal name of the class to which the inner class
* <tt>null</tt> for anonymous inner classes. * belongs (see {@link org.objectweb.asm.Type#getInternalName()
* @param access the access flags of the inner class as originally declared in the enclosing * getInternalName}). May be <tt>null</tt>.
* class. * @param innerName
* the (simple) name of the inner class inside its enclosing
* class. May be <tt>null</tt> for anonymous inner classes.
* @param access
* the access flags of the inner class as originally declared in
* the enclosing class.
*/ */
public InnerClassNode(final String name, final String outerName, final String innerName, public InnerClassNode(final String name, final String outerName,
final int access) { final String innerName, final int access) {
this.name = name; this.name = name;
this.outerName = outerName; this.outerName = outerName;
this.innerName = innerName; this.innerName = innerName;
@@ -77,7 +92,8 @@ public class InnerClassNode {
/** /**
* Makes the given class visitor visit this inner class. * Makes the given class visitor visit this inner class.
* *
* @param cv a class visitor. * @param cv
* a class visitor.
*/ */
public void accept(final ClassVisitor cv) { public void accept(final ClassVisitor cv) {
cv.visitInnerClass(name, outerName, innerName, access); cv.visitInnerClass(name, outerName, innerName, access);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -27,8 +35,8 @@ import java.util.NoSuchElementException;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A doubly linked list of {@link AbstractInsnNode} objects. <i>This implementation is not thread * A doubly linked list of {@link AbstractInsnNode} objects. <i>This
* safe</i>. * implementation is not thread safe</i>.
*/ */
public class InsnList { public class InsnList {
@@ -48,8 +56,8 @@ public class InsnList {
private AbstractInsnNode last; private AbstractInsnNode last;
/** /**
* A cache of the instructions of this list. This cache is used to improve the performance of * A cache of the instructions of this list. This cache is used to improve
* the {@link #get} method. * the performance of the {@link #get} method.
*/ */
AbstractInsnNode[] cache; AbstractInsnNode[] cache;
@@ -65,7 +73,8 @@ public class InsnList {
/** /**
* Returns the first instruction in this list. * Returns the first instruction in this list.
* *
* @return the first instruction in this list, or <tt>null</tt> if the list is empty. * @return the first instruction in this list, or <tt>null</tt> if the list
* is empty.
*/ */
public AbstractInsnNode getFirst() { public AbstractInsnNode getFirst() {
return first; return first;
@@ -74,21 +83,24 @@ public class InsnList {
/** /**
* Returns the last instruction in this list. * Returns the last instruction in this list.
* *
* @return the last instruction in this list, or <tt>null</tt> if the list is empty. * @return the last instruction in this list, or <tt>null</tt> if the list
* is empty.
*/ */
public AbstractInsnNode getLast() { public AbstractInsnNode getLast() {
return last; return last;
} }
/** /**
* Returns the instruction whose index is given. This method builds a cache of the instructions * Returns the instruction whose index is given. This method builds a cache
* in this list to avoid scanning the whole list each time it is called. Once the cache is * of the instructions in this list to avoid scanning the whole list each
* built, this method run in constant time. This cache is invalidated by all the methods that * time it is called. Once the cache is built, this method run in constant
* modify the list. * time. This cache is invalidated by all the methods that modify the list.
* *
* @param index the index of the instruction that must be returned. * @param index
* the index of the instruction that must be returned.
* @return the instruction whose index is given. * @return the instruction whose index is given.
* @throws IndexOutOfBoundsException if (index < 0 || index >= size()). * @throws IndexOutOfBoundsException
* if (index < 0 || index >= size()).
*/ */
public AbstractInsnNode get(final int index) { public AbstractInsnNode get(final int index) {
if (index < 0 || index >= size) { if (index < 0 || index >= size) {
@@ -101,11 +113,12 @@ public class InsnList {
} }
/** /**
* Returns <tt>true</tt> if the given instruction belongs to this list. This method always scans * Returns <tt>true</tt> if the given instruction belongs to this list. This
* the instructions of this list until it finds the given instruction or reaches the end of the * method always scans the instructions of this list until it finds the
* list. * given instruction or reaches the end of the list.
* *
* @param insn an instruction. * @param insn
* an instruction.
* @return <tt>true</tt> if the given instruction belongs to this list. * @return <tt>true</tt> if the given instruction belongs to this list.
*/ */
public boolean contains(final AbstractInsnNode insn) { public boolean contains(final AbstractInsnNode insn) {
@@ -117,16 +130,18 @@ public class InsnList {
} }
/** /**
* Returns the index of the given instruction in this list. This method builds a cache of the * Returns the index of the given instruction in this list. This method
* instruction indexes to avoid scanning the whole list each time it is called. Once the cache * builds a cache of the instruction indexes to avoid scanning the whole
* is built, this method run in constant time. The cache is invalidated by all the methods that * list each time it is called. Once the cache is built, this method run in
* modify the list. * constant time. The cache is invalidated by all the methods that modify
* the list.
* *
* @param insn an instruction <i>of this list</i>. * @param insn
* @return the index of the given instruction in this list. <i>The result of this method is * an instruction <i>of this list</i>.
* undefined if the given instruction does not belong to this list</i>. Use * @return the index of the given instruction in this list. <i>The result of
* {@link #contains contains} to test if an instruction belongs to an instruction list * this method is undefined if the given instruction does not belong
* or not. * to this list</i>. Use {@link #contains contains} to test if an
* instruction belongs to an instruction list or not.
*/ */
public int indexOf(final AbstractInsnNode insn) { public int indexOf(final AbstractInsnNode insn) {
if (cache == null) { if (cache == null) {
@@ -138,7 +153,8 @@ public class InsnList {
/** /**
* Makes the given visitor visit all of the instructions in this list. * Makes the given visitor visit all of the instructions in this list.
* *
* @param mv the method visitor that must visit the instructions. * @param mv
* the method visitor that must visit the instructions.
*/ */
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
AbstractInsnNode insn = first; AbstractInsnNode insn = first;
@@ -187,8 +203,11 @@ public class InsnList {
/** /**
* Replaces an instruction of this list with another instruction. * Replaces an instruction of this list with another instruction.
* *
* @param location an instruction <i>of this list</i>. * @param location
* @param insn another instruction, <i>which must not belong to any {@link InsnList}</i>. * an instruction <i>of this list</i>.
* @param insn
* another instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/ */
public void set(final AbstractInsnNode location, final AbstractInsnNode insn) { public void set(final AbstractInsnNode location, final AbstractInsnNode insn) {
AbstractInsnNode next = location.next; AbstractInsnNode next = location.next;
@@ -220,7 +239,9 @@ public class InsnList {
/** /**
* Adds the given instruction to the end of this list. * Adds the given instruction to the end of this list.
* *
* @param insn an instruction, <i>which must not belong to any {@link InsnList}</i>. * @param insn
* an instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/ */
public void add(final AbstractInsnNode insn) { public void add(final AbstractInsnNode insn) {
++size; ++size;
@@ -239,8 +260,9 @@ public class InsnList {
/** /**
* Adds the given instructions to the end of this list. * Adds the given instructions to the end of this list.
* *
* @param insns an instruction list, which is cleared during the process. This list must be * @param insns
* different from 'this'. * an instruction list, which is cleared during the process. This
* list must be different from 'this'.
*/ */
public void add(final InsnList insns) { public void add(final InsnList insns) {
if (insns.size == 0) { if (insns.size == 0) {
@@ -263,7 +285,9 @@ public class InsnList {
/** /**
* Inserts the given instruction at the begining of this list. * Inserts the given instruction at the begining of this list.
* *
* @param insn an instruction, <i>which must not belong to any {@link InsnList}</i>. * @param insn
* an instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/ */
public void insert(final AbstractInsnNode insn) { public void insert(final AbstractInsnNode insn) {
++size; ++size;
@@ -282,8 +306,9 @@ public class InsnList {
/** /**
* Inserts the given instructions at the begining of this list. * Inserts the given instructions at the begining of this list.
* *
* @param insns an instruction list, which is cleared during the process. This list must be * @param insns
* different from 'this'. * an instruction list, which is cleared during the process. This
* list must be different from 'this'.
*/ */
public void insert(final InsnList insns) { public void insert(final InsnList insns) {
if (insns.size == 0) { if (insns.size == 0) {
@@ -306,11 +331,15 @@ public class InsnList {
/** /**
* Inserts the given instruction after the specified instruction. * Inserts the given instruction after the specified instruction.
* *
* @param location an instruction <i>of this list</i> after which insn must be inserted. * @param location
* @param insn the instruction to be inserted, <i>which must not belong to any * an instruction <i>of this list</i> after which insn must be
* {@link InsnList}</i>. * inserted.
* @param insn
* the instruction to be inserted, <i>which must not belong to
* any {@link InsnList}</i>.
*/ */
public void insert(final AbstractInsnNode location, final AbstractInsnNode insn) { public void insert(final AbstractInsnNode location,
final AbstractInsnNode insn) {
++size; ++size;
AbstractInsnNode next = location.next; AbstractInsnNode next = location.next;
if (next == null) { if (next == null) {
@@ -328,10 +357,12 @@ public class InsnList {
/** /**
* Inserts the given instructions after the specified instruction. * Inserts the given instructions after the specified instruction.
* *
* @param location an instruction <i>of this list</i> after which the instructions must be * @param location
* inserted. * an instruction <i>of this list</i> after which the
* @param insns the instruction list to be inserted, which is cleared during the process. This * instructions must be inserted.
* list must be different from 'this'. * @param insns
* the instruction list to be inserted, which is cleared during
* the process. This list must be different from 'this'.
*/ */
public void insert(final AbstractInsnNode location, final InsnList insns) { public void insert(final AbstractInsnNode location, final InsnList insns) {
if (insns.size == 0) { if (insns.size == 0) {
@@ -356,11 +387,15 @@ public class InsnList {
/** /**
* Inserts the given instruction before the specified instruction. * Inserts the given instruction before the specified instruction.
* *
* @param location an instruction <i>of this list</i> before which insn must be inserted. * @param location
* @param insn the instruction to be inserted, <i>which must not belong to any * an instruction <i>of this list</i> before which insn must be
* {@link InsnList}</i>. * inserted.
* @param insn
* the instruction to be inserted, <i>which must not belong to
* any {@link InsnList}</i>.
*/ */
public void insertBefore(final AbstractInsnNode location, final AbstractInsnNode insn) { public void insertBefore(final AbstractInsnNode location,
final AbstractInsnNode insn) {
++size; ++size;
AbstractInsnNode prev = location.prev; AbstractInsnNode prev = location.prev;
if (prev == null) { if (prev == null) {
@@ -378,12 +413,15 @@ public class InsnList {
/** /**
* Inserts the given instructions before the specified instruction. * Inserts the given instructions before the specified instruction.
* *
* @param location an instruction <i>of this list</i> before which the instructions must be * @param location
* inserted. * an instruction <i>of this list</i> before which the
* @param insns the instruction list to be inserted, which is cleared during the process. This * instructions must be inserted.
* list must be different from 'this'. * @param insns
* the instruction list to be inserted, which is cleared during
* the process. This list must be different from 'this'.
*/ */
public void insertBefore(final AbstractInsnNode location, final InsnList insns) { public void insertBefore(final AbstractInsnNode location,
final InsnList insns) {
if (insns.size == 0) { if (insns.size == 0) {
return; return;
} }
@@ -406,7 +444,8 @@ public class InsnList {
/** /**
* Removes the given instruction from this list. * Removes the given instruction from this list.
* *
* @param insn the instruction <i>of this list</i> that must be removed. * @param insn
* the instruction <i>of this list</i> that must be removed.
*/ */
public void remove(final AbstractInsnNode insn) { public void remove(final AbstractInsnNode insn) {
--size; --size;
@@ -438,8 +477,9 @@ public class InsnList {
/** /**
* Removes all of the instructions of this list. * Removes all of the instructions of this list.
* *
* @param mark if the instructions must be marked as no longer belonging to any * @param mark
* {@link InsnList}. * if the instructions must be marked as no longer belonging to
* any {@link InsnList}.
*/ */
void removeAll(final boolean mark) { void removeAll(final boolean mark) {
if (mark) { if (mark) {
@@ -466,8 +506,9 @@ public class InsnList {
} }
/** /**
* Reset all labels in the instruction list. This method should be called before reusing same * Reset all labels in the instruction list. This method should be called
* instructions list between several <code>ClassWriter</code>s. * before reusing same instructions list between several
* <code>ClassWriter</code>s.
*/ */
public void resetLabels() { public void resetLabels() {
AbstractInsnNode insn = first; AbstractInsnNode insn = first;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -35,17 +43,22 @@ public class InsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link InsnNode}. * Constructs a new {@link InsnNode}.
* *
* @param opcode the opcode of the instruction to be constructed. This opcode must be NOP, * @param opcode
* ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, * the opcode of the instruction to be constructed. This opcode
* LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, * must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
* FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE, * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
* AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
* IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
* ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
* IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
* MONITORENTER, or MONITOREXIT. * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
* or MONITOREXIT.
*/ */
public InsnNode(final int opcode) { public InsnNode(final int opcode) {
super(opcode); super(opcode);
@@ -59,7 +72,8 @@ public class InsnNode extends AbstractInsnNode {
/** /**
* Makes the given visitor visit this instruction. * Makes the given visitor visit this instruction.
* *
* @param mv a method visitor. * @param mv
* a method visitor.
*/ */
@Override @Override
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -40,9 +48,11 @@ public class IntInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link IntInsnNode}. * Constructs a new {@link IntInsnNode}.
* *
* @param opcode the opcode of the instruction to be constructed. This opcode must be BIPUSH, * @param opcode
* SIPUSH or NEWARRAY. * the opcode of the instruction to be constructed. This opcode
* @param operand the operand of the instruction to be constructed. * must be BIPUSH, SIPUSH or NEWARRAY.
* @param operand
* the operand of the instruction to be constructed.
*/ */
public IntInsnNode(final int opcode, final int operand) { public IntInsnNode(final int opcode, final int operand) {
super(opcode); super(opcode);
@@ -52,7 +62,9 @@ public class IntInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode the new instruction opcode. This opcode must be BIPUSH, SIPUSH or NEWARRAY. * @param opcode
* the new instruction opcode. This opcode must be BIPUSH, SIPUSH
* or NEWARRAY.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -57,13 +65,17 @@ public class InvokeDynamicInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link InvokeDynamicInsnNode}. * Constructs a new {@link InvokeDynamicInsnNode}.
* *
* @param name invokedynamic name. * @param name
* @param desc invokedynamic descriptor (see {@link org.objectweb.asm.Type}). * invokedynamic name.
* @param bsm the bootstrap method. * @param desc
* @param bsmArgs the boostrap constant arguments. * invokedynamic descriptor (see {@link org.objectweb.asm.Type}).
* @param bsm
* the bootstrap method.
* @param bsmArgs
* the boostrap constant arguments.
*/ */
public InvokeDynamicInsnNode(final String name, final String desc, final Handle bsm, public InvokeDynamicInsnNode(final String name, final String desc,
final Object... bsmArgs) { final Handle bsm, final Object... bsmArgs) {
super(Opcodes.INVOKEDYNAMIC); super(Opcodes.INVOKEDYNAMIC);
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -26,27 +34,31 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a jump instruction. A jump instruction is an instruction that may jump to * A node that represents a jump instruction. A jump instruction is an
* another instruction. * instruction that may jump to another instruction.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class JumpInsnNode extends AbstractInsnNode { public class JumpInsnNode extends AbstractInsnNode {
/** /**
* The operand of this instruction. This operand is a label that designates the instruction to * The operand of this instruction. This operand is a label that designates
* which this instruction may jump. * the instruction to which this instruction may jump.
*/ */
public LabelNode label; public LabelNode label;
/** /**
* Constructs a new {@link JumpInsnNode}. * Constructs a new {@link JumpInsnNode}.
* *
* @param opcode the opcode of the type instruction to be constructed. This opcode must be IFEQ, * @param opcode
* IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, * the opcode of the type instruction to be constructed. This
* IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
* @param label the operand of the instruction to be constructed. This operand is a label that * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* designates the instruction to which the jump instruction may jump. * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* @param label
* the operand of the instruction to be constructed. This operand
* is a label that designates the instruction to which the jump
* instruction may jump.
*/ */
public JumpInsnNode(final int opcode, final LabelNode label) { public JumpInsnNode(final int opcode, final LabelNode label) {
super(opcode); super(opcode);
@@ -56,9 +68,11 @@ public class JumpInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode the new instruction opcode. This opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, * @param opcode
* IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, * the new instruction opcode. This opcode must be IFEQ, IFNE,
* IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT,
* IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO,
* JSR, IFNULL or IFNONNULL.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -34,18 +42,19 @@ import org.objectweb.asm.Opcodes;
public class LdcInsnNode extends AbstractInsnNode { public class LdcInsnNode extends AbstractInsnNode {
/** /**
* The constant to be loaded on the stack. This parameter must be a non null {@link Integer}, a * The constant to be loaded on the stack. This parameter must be a non null
* {@link Float}, a {@link Long}, a {@link Double}, a {@link String} or a * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a
* {@link org.objectweb.asm.Type}. * {@link String} or a {@link org.objectweb.asm.Type}.
*/ */
public Object cst; public Object cst;
/** /**
* Constructs a new {@link LdcInsnNode}. * Constructs a new {@link LdcInsnNode}.
* *
* @param cst the constant to be loaded on the stack. This parameter must be a non null * @param cst
* {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double} or a * the constant to be loaded on the stack. This parameter must be
* {@link String}. * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String}.
*/ */
public LdcInsnNode(final Object cst) { public LdcInsnNode(final Object cst) {
super(Opcodes.LDC); super(Opcodes.LDC);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -26,15 +34,16 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a line number declaration. These nodes are pseudo instruction nodes in * A node that represents a line number declaration. These nodes are pseudo
* order to be inserted in an instruction list. * instruction nodes in order to be inserted in an instruction list.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class LineNumberNode extends AbstractInsnNode { public class LineNumberNode extends AbstractInsnNode {
/** /**
* A line number. This number refers to the source file from which the class was compiled. * A line number. This number refers to the source file from which the class
* was compiled.
*/ */
public int line; public int line;
@@ -46,9 +55,11 @@ public class LineNumberNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link LineNumberNode}. * Constructs a new {@link LineNumberNode}.
* *
* @param line a line number. This number refers to the source file from which the class was * @param line
* compiled. * a line number. This number refers to the source file from
* @param start the first instruction corresponding to this line number. * which the class was compiled.
* @param start
* the first instruction corresponding to this line number.
*/ */
public LineNumberNode(final int line, final LabelNode start) { public LineNumberNode(final int line, final LabelNode start) {
super(-1); super(-1);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -46,12 +54,14 @@ public class LocalVariableNode {
public String signature; public String signature;
/** /**
* The first instruction corresponding to the scope of this local variable (inclusive). * The first instruction corresponding to the scope of this local variable
* (inclusive).
*/ */
public LabelNode start; public LabelNode start;
/** /**
* The last instruction corresponding to the scope of this local variable (exclusive). * The last instruction corresponding to the scope of this local variable
* (exclusive).
*/ */
public LabelNode end; public LabelNode end;
@@ -63,17 +73,24 @@ public class LocalVariableNode {
/** /**
* Constructs a new {@link LocalVariableNode}. * Constructs a new {@link LocalVariableNode}.
* *
* @param name the name of a local variable. * @param name
* @param desc the type descriptor of this local variable. * the name of a local variable.
* @param signature the signature of this local variable. May be <tt>null</tt>. * @param desc
* @param start the first instruction corresponding to the scope of this local variable * the type descriptor of this local variable.
* (inclusive). * @param signature
* @param end the last instruction corresponding to the scope of this local variable * the signature of this local variable. May be <tt>null</tt>.
* (exclusive). * @param start
* @param index the local variable's index. * the first instruction corresponding to the scope of this local
* variable (inclusive).
* @param end
* the last instruction corresponding to the scope of this local
* variable (exclusive).
* @param index
* the local variable's index.
*/ */
public LocalVariableNode(final String name, final String desc, final String signature, public LocalVariableNode(final String name, final String desc,
final LabelNode start, final LabelNode end, final int index) { final String signature, final LabelNode start, final LabelNode end,
final int index) {
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;
this.signature = signature; this.signature = signature;
@@ -85,9 +102,11 @@ public class LocalVariableNode {
/** /**
* Makes the given visitor visit this local variable declaration. * Makes the given visitor visit this local variable declaration.
* *
* @param mv a method visitor. * @param mv
* a method visitor.
*/ */
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
mv.visitLocalVariable(name, desc, signature, start.getLabel(), end.getLabel(), index); mv.visitLocalVariable(name, desc, signature, start.getLabel(),
end.getLabel(), index);
} }
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -48,23 +56,29 @@ public class LookupSwitchInsnNode extends AbstractInsnNode {
public List<Integer> keys; public List<Integer> keys;
/** /**
* Beginnings of the handler blocks. This list is a list of {@link LabelNode} objects. * Beginnings of the handler blocks. This list is a list of
* {@link LabelNode} objects.
*/ */
public List<LabelNode> labels; public List<LabelNode> labels;
/** /**
* Constructs a new {@link LookupSwitchInsnNode}. * Constructs a new {@link LookupSwitchInsnNode}.
* *
* @param dflt beginning of the default handler block. * @param dflt
* @param keys the values of the keys. * beginning of the default handler block.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the * @param keys
* handler block for the <tt>keys[i]</tt> key. * the values of the keys.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>keys[i]</tt> key.
*/ */
public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) { public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys,
final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH); super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt; this.dflt = dflt;
this.keys = new ArrayList<Integer>(keys == null ? 0 : keys.length); this.keys = new ArrayList<Integer>(keys == null ? 0 : keys.length);
this.labels = new ArrayList<LabelNode>(labels == null ? 0 : labels.length); this.labels = new ArrayList<LabelNode>(labels == null ? 0
: labels.length);
if (keys != null) { if (keys != null) {
for (int i = 0; i < keys.length; ++i) { for (int i = 0; i < keys.length; ++i) {
this.keys.add(new Integer(keys[i])); this.keys.add(new Integer(keys[i]));
@@ -95,8 +109,8 @@ public class LookupSwitchInsnNode extends AbstractInsnNode {
@Override @Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
LookupSwitchInsnNode clone = LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt,
new LookupSwitchInsnNode(clone(dflt, labels), null, clone(this.labels, labels)); labels), null, clone(this.labels, labels));
clone.keys.addAll(keys); clone.keys.addAll(keys);
return clone; return clone;
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -26,8 +34,8 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a method instruction. A method instruction is an instruction that invokes * A node that represents a method instruction. A method instruction is an
* a method. * instruction that invokes a method.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -52,15 +60,21 @@ public class MethodInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link MethodInsnNode}. * Constructs a new {@link MethodInsnNode}.
* *
* @param opcode the opcode of the type instruction to be constructed. This opcode must be * @param opcode
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. * the opcode of the type instruction to be constructed. This
* @param owner the internal name of the method's owner class (see * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). * INVOKEINTERFACE.
* @param name the method's name. * @param owner
* @param desc the method's descriptor (see {@link org.objectweb.asm.Type}). * the internal name of the method's owner class (see
* {@link org.objectweb.asm.Type#getInternalName()
* getInternalName}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link org.objectweb.asm.Type}).
*/ */
public MethodInsnNode(final int opcode, final String owner, final String name, public MethodInsnNode(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
super(opcode); super(opcode);
this.owner = owner; this.owner = owner;
this.name = name; this.name = name;
@@ -70,8 +84,9 @@ public class MethodInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode the new instruction opcode. This opcode must be INVOKEVIRTUAL, INVOKESPECIAL, * @param opcode
* INVOKESTATIC or INVOKEINTERFACE. * the new instruction opcode. This opcode must be INVOKEVIRTUAL,
* INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -42,8 +50,8 @@ import org.objectweb.asm.Type;
public class MethodNode extends MethodVisitor { public class MethodNode extends MethodVisitor {
/** /**
* The method's access flags (see {@link Opcodes}). This field also indicates if the method is * The method's access flags (see {@link Opcodes}). This field also
* synthetic and/or deprecated. * indicates if the method is synthetic and/or deprecated.
*/ */
public int access; public int access;
@@ -63,14 +71,15 @@ public class MethodNode extends MethodVisitor {
public String signature; public String signature;
/** /**
* The internal names of the method's exception classes (see {@link Type#getInternalName() * The internal names of the method's exception classes (see
* getInternalName}). This list is a list of {@link String} objects. * {@link Type#getInternalName() getInternalName}). This list is a list of
* {@link String} objects.
*/ */
public List<String> exceptions; public List<String> exceptions;
/** /**
* The runtime visible annotations of this method. This list is a list of {@link AnnotationNode} * The runtime visible annotations of this method. This list is a list of
* objects. May be <tt>null</tt>. * {@link AnnotationNode} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label visible * @label visible
@@ -87,25 +96,26 @@ public class MethodNode extends MethodVisitor {
public List<AnnotationNode> invisibleAnnotations; public List<AnnotationNode> invisibleAnnotations;
/** /**
* The non standard attributes of this method. This list is a list of {@link Attribute} objects. * The non standard attributes of this method. This list is a list of
* May be <tt>null</tt>. * {@link Attribute} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.Attribute * @associates org.objectweb.asm.Attribute
*/ */
public List<Attribute> attrs; public List<Attribute> attrs;
/** /**
* The default value of this annotation interface method. This field must be a {@link Byte}, * The default value of this annotation interface method. This field must be
* {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}, {@link Long}, * a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short},
* {@link Float}, {@link Double}, {@link String} or {@link Type}, or an two elements String * {@link Integer}, {@link Long}, {@link Float}, {@link Double},
* array (for enumeration values), a {@link AnnotationNode}, or a {@link List} of values of one * {@link String} or {@link Type}, or an two elements String array (for
* of the preceding types. May be <tt>null</tt>. * enumeration values), a {@link AnnotationNode}, or a {@link List} of
* values of one of the preceding types. May be <tt>null</tt>.
*/ */
public Object annotationDefault; public Object annotationDefault;
/** /**
* The runtime visible parameter annotations of this method. These lists are lists of * The runtime visible parameter annotations of this method. These lists are
* {@link AnnotationNode} objects. May be <tt>null</tt>. * lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label invisible parameters * @label invisible parameters
@@ -113,8 +123,8 @@ public class MethodNode extends MethodVisitor {
public List<AnnotationNode>[] visibleParameterAnnotations; public List<AnnotationNode>[] visibleParameterAnnotations;
/** /**
* The runtime invisible parameter annotations of this method. These lists are lists of * The runtime invisible parameter annotations of this method. These lists
* {@link AnnotationNode} objects. May be <tt>null</tt>. * are lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label visible parameters * @label visible parameters
@@ -122,7 +132,8 @@ public class MethodNode extends MethodVisitor {
public List<AnnotationNode>[] invisibleParameterAnnotations; public List<AnnotationNode>[] invisibleParameterAnnotations;
/** /**
* The instructions of this method. This list is a list of {@link AbstractInsnNode} objects. * The instructions of this method. This list is a list of
* {@link AbstractInsnNode} objects.
* *
* @associates org.objectweb.asm.tree.AbstractInsnNode * @associates org.objectweb.asm.tree.AbstractInsnNode
* @label instructions * @label instructions
@@ -130,8 +141,8 @@ public class MethodNode extends MethodVisitor {
public InsnList instructions; public InsnList instructions;
/** /**
* The try catch blocks of this method. This list is a list of {@link TryCatchBlockNode} * The try catch blocks of this method. This list is a list of
* objects. * {@link TryCatchBlockNode} objects.
* *
* @associates org.objectweb.asm.tree.TryCatchBlockNode * @associates org.objectweb.asm.tree.TryCatchBlockNode
*/ */
@@ -148,8 +159,8 @@ public class MethodNode extends MethodVisitor {
public int maxLocals; public int maxLocals;
/** /**
* The local variables of this method. This list is a list of {@link LocalVariableNode} objects. * The local variables of this method. This list is a list of
* May be <tt>null</tt> * {@link LocalVariableNode} objects. May be <tt>null</tt>
* *
* @associates org.objectweb.asm.tree.LocalVariableNode * @associates org.objectweb.asm.tree.LocalVariableNode
*/ */
@@ -161,8 +172,9 @@ public class MethodNode extends MethodVisitor {
private boolean visited; private boolean visited;
/** /**
* Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not use this * Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not
* constructor</i>. Instead, they must use the {@link #MethodNode(int)} version. * use this constructor</i>. Instead, they must use the
* {@link #MethodNode(int)} version.
*/ */
public MethodNode() { public MethodNode() {
this(Opcodes.ASM4); this(Opcodes.ASM4);
@@ -171,8 +183,9 @@ public class MethodNode extends MethodVisitor {
/** /**
* Constructs an uninitialized {@link MethodNode}. * Constructs an uninitialized {@link MethodNode}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
*/ */
public MethodNode(final int api) { public MethodNode(final int api) {
super(api); super(api);
@@ -180,17 +193,24 @@ public class MethodNode extends MethodVisitor {
} }
/** /**
* Constructs a new {@link MethodNode}. <i>Subclasses must not use this constructor</i>. * Constructs a new {@link MethodNode}. <i>Subclasses must not use this
* Instead, they must use the {@link #MethodNode(int, int, String, String, String, String[])} * constructor</i>. Instead, they must use the
* version. * {@link #MethodNode(int, int, String, String, String, String[])} version.
* *
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates * @param access
* if the method is synthetic and/or deprecated. * the method's access flags (see {@link Opcodes}). This
* @param name the method's name. * parameter also indicates if the method is synthetic and/or
* @param desc the method's descriptor (see {@link Type}). * deprecated.
* @param signature the method's signature. May be <tt>null</tt>. * @param name
* @param exceptions the internal names of the method's exception classes (see * the method's name.
* {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>. * @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public MethodNode(final int access, final String name, final String desc, public MethodNode(final int access, final String name, final String desc,
final String signature, final String[] exceptions) { final String signature, final String[] exceptions) {
@@ -200,24 +220,33 @@ public class MethodNode extends MethodVisitor {
/** /**
* Constructs a new {@link MethodNode}. * Constructs a new {@link MethodNode}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of * @param api
* {@link Opcodes#ASM4}. * the ASM API version implemented by this visitor. Must be one
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates * of {@link Opcodes#ASM4}.
* if the method is synthetic and/or deprecated. * @param access
* @param name the method's name. * the method's access flags (see {@link Opcodes}). This
* @param desc the method's descriptor (see {@link Type}). * parameter also indicates if the method is synthetic and/or
* @param signature the method's signature. May be <tt>null</tt>. * deprecated.
* @param exceptions the internal names of the method's exception classes (see * @param name
* {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>. * the method's name.
* @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public MethodNode(final int api, final int access, final String name, final String desc, public MethodNode(final int api, final int access, final String name,
final String signature, final String[] exceptions) { final String desc, final String signature, final String[] exceptions) {
super(api); super(api);
this.access = access; this.access = access;
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;
this.signature = signature; this.signature = signature;
this.exceptions = new ArrayList<String>(exceptions == null ? 0 : exceptions.length); this.exceptions = new ArrayList<String>(exceptions == null ? 0
: exceptions.length);
boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0; boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
if (!isAbstract) { if (!isAbstract) {
this.localVariables = new ArrayList<LocalVariableNode>(5); this.localVariables = new ArrayList<LocalVariableNode>(5);
@@ -245,7 +274,8 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc); AnnotationNode an = new AnnotationNode(desc);
if (visible) { if (visible) {
if (visibleAnnotations == null) { if (visibleAnnotations == null) {
@@ -262,8 +292,8 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, public AnnotationVisitor visitParameterAnnotation(final int parameter,
final boolean visible) { final String desc, final boolean visible) {
AnnotationNode an = new AnnotationNode(desc); AnnotationNode an = new AnnotationNode(desc);
if (visible) { if (visible) {
if (visibleParameterAnnotations == null) { if (visibleParameterAnnotations == null) {
@@ -271,7 +301,8 @@ public class MethodNode extends MethodVisitor {
visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
} }
if (visibleParameterAnnotations[parameter] == null) { if (visibleParameterAnnotations[parameter] == null) {
visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1); visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
1);
} }
visibleParameterAnnotations[parameter].add(an); visibleParameterAnnotations[parameter].add(an);
} else { } else {
@@ -280,7 +311,8 @@ public class MethodNode extends MethodVisitor {
invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
} }
if (invisibleParameterAnnotations[parameter] == null) { if (invisibleParameterAnnotations[parameter] == null) {
invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1); invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
1);
} }
invisibleParameterAnnotations[parameter].add(an); invisibleParameterAnnotations[parameter].add(an);
} }
@@ -296,13 +328,15 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitCode() {} public void visitCode() {
}
@Override @Override
public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, public void visitFrame(final int type, final int nLocal,
final Object[] stack) { final Object[] local, final int nStack, final Object[] stack) {
instructions.add(new FrameNode(type, nLocal, local == null ? null : getLabelNodes(local), instructions.add(new FrameNode(type, nLocal, local == null ? null
nStack, stack == null ? null : getLabelNodes(stack))); : getLabelNodes(local), nStack, stack == null ? null
: getLabelNodes(stack)));
} }
@Override @Override
@@ -326,19 +360,20 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitFieldInsn(final int opcode, final String owner, final String name, public void visitFieldInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
instructions.add(new FieldInsnNode(opcode, owner, name, desc)); instructions.add(new FieldInsnNode(opcode, owner, name, desc));
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, final String name, public void visitMethodInsn(final int opcode, final String owner,
final String desc) { final String name, final String desc) {
instructions.add(new MethodInsnNode(opcode, owner, name, desc)); instructions.add(new MethodInsnNode(opcode, owner, name, desc));
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)); instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs));
} }
@@ -363,15 +398,17 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitTableSwitchInsn(final int min, final int max, final Label dflt, public void visitTableSwitchInsn(final int min, final int max,
final Label... labels) { final Label dflt, final Label... labels) {
instructions instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt),
.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), getLabelNodes(labels))); getLabelNodes(labels)));
} }
@Override @Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, getLabelNodes(labels))); final Label[] labels) {
instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys,
getLabelNodes(labels)));
} }
@Override @Override
@@ -380,17 +417,18 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitTryCatchBlock(final Label start, final Label end, final Label handler, public void visitTryCatchBlock(final Label start, final Label end,
final String type) { final Label handler, final String type) {
tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start), getLabelNode(end), tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start),
getLabelNode(handler), type)); getLabelNode(end), getLabelNode(handler), type));
} }
@Override @Override
public void visitLocalVariable(final String name, final String desc, final String signature, public void visitLocalVariable(final String name, final String desc,
final Label start, final Label end, final int index) { final String signature, final Label start, final Label end,
localVariables.add(new LocalVariableNode(name, desc, signature, getLabelNode(start), final int index) {
getLabelNode(end), index)); localVariables.add(new LocalVariableNode(name, desc, signature,
getLabelNode(start), getLabelNode(end), index));
} }
@Override @Override
@@ -405,14 +443,17 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitEnd() {} public void visitEnd() {
}
/** /**
* Returns the LabelNode corresponding to the given Label. Creates a new LabelNode if necessary. * Returns the LabelNode corresponding to the given Label. Creates a new
* The default implementation of this method uses the {@link Label#info} field to store * LabelNode if necessary. The default implementation of this method uses
* associations between labels and label nodes. * the {@link Label#info} field to store associations between labels and
* label nodes.
* *
* @param l a Label. * @param l
* a Label.
* @return the LabelNode corresponding to l. * @return the LabelNode corresponding to l.
*/ */
protected LabelNode getLabelNode(final Label l) { protected LabelNode getLabelNode(final Label l) {
@@ -447,11 +488,13 @@ public class MethodNode extends MethodVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Checks that this method node is compatible with the given ASM API version. This methods * Checks that this method node is compatible with the given ASM API
* checks that this node, and all its nodes recursively, do not contain elements that were * version. This methods checks that this node, and all its nodes
* introduced in more recent versions of the ASM API than the given version. * recursively, do not contain elements that were introduced in more recent
* versions of the ASM API than the given version.
* *
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}. * @param api
* an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/ */
public void check(final int api) { public void check(final int api) {
// nothing to do // nothing to do
@@ -460,12 +503,14 @@ public class MethodNode extends MethodVisitor {
/** /**
* Makes the given class visitor visit this method. * Makes the given class visitor visit this method.
* *
* @param cv a class visitor. * @param cv
* a class visitor.
*/ */
public void accept(final ClassVisitor cv) { public void accept(final ClassVisitor cv) {
String[] exceptions = new String[this.exceptions.size()]; String[] exceptions = new String[this.exceptions.size()];
this.exceptions.toArray(exceptions); this.exceptions.toArray(exceptions);
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
exceptions);
if (mv != null) { if (mv != null) {
accept(mv); accept(mv);
} }
@@ -474,7 +519,8 @@ public class MethodNode extends MethodVisitor {
/** /**
* Makes the given method visitor visit this method. * Makes the given method visitor visit this method.
* *
* @param mv a method visitor. * @param mv
* a method visitor.
*/ */
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
// visits the method attributes // visits the method attributes
@@ -496,7 +542,8 @@ public class MethodNode extends MethodVisitor {
AnnotationNode an = invisibleAnnotations.get(i); AnnotationNode an = invisibleAnnotations.get(i);
an.accept(mv.visitAnnotation(an.desc, false)); an.accept(mv.visitAnnotation(an.desc, false));
} }
n = visibleParameterAnnotations == null ? 0 : visibleParameterAnnotations.length; n = visibleParameterAnnotations == null ? 0
: visibleParameterAnnotations.length;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
List<?> l = visibleParameterAnnotations[i]; List<?> l = visibleParameterAnnotations[i];
if (l == null) { if (l == null) {
@@ -507,7 +554,8 @@ public class MethodNode extends MethodVisitor {
an.accept(mv.visitParameterAnnotation(i, an.desc, true)); an.accept(mv.visitParameterAnnotation(i, an.desc, true));
} }
} }
n = invisibleParameterAnnotations == null ? 0 : invisibleParameterAnnotations.length; n = invisibleParameterAnnotations == null ? 0
: invisibleParameterAnnotations.length;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
List<?> l = invisibleParameterAnnotations[i]; List<?> l = invisibleParameterAnnotations[i];
if (l == null) { if (l == null) {

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -46,8 +54,10 @@ public class MultiANewArrayInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link MultiANewArrayInsnNode}. * Constructs a new {@link MultiANewArrayInsnNode}.
* *
* @param desc an array type descriptor (see {@link org.objectweb.asm.Type}). * @param desc
* @param dims number of dimensions of the array to allocate. * an array type descriptor (see {@link org.objectweb.asm.Type}).
* @param dims
* number of dimensions of the array to allocate.
*/ */
public MultiANewArrayInsnNode(final String desc, final int dims) { public MultiANewArrayInsnNode(final String desc, final int dims) {
super(Opcodes.MULTIANEWARRAY); super(Opcodes.MULTIANEWARRAY);

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -53,21 +61,26 @@ public class TableSwitchInsnNode extends AbstractInsnNode {
public LabelNode dflt; public LabelNode dflt;
/** /**
* Beginnings of the handler blocks. This list is a list of {@link LabelNode} objects. * Beginnings of the handler blocks. This list is a list of
* {@link LabelNode} objects.
*/ */
public List<LabelNode> labels; public List<LabelNode> labels;
/** /**
* Constructs a new {@link TableSwitchInsnNode}. * Constructs a new {@link TableSwitchInsnNode}.
* *
* @param min the minimum key value. * @param min
* @param max the maximum key value. * the minimum key value.
* @param dflt beginning of the default handler block. * @param max
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the * the maximum key value.
* handler block for the <tt>min + i</tt> key. * @param dflt
* beginning of the default handler block.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>min + i</tt> key.
*/ */
public TableSwitchInsnNode(final int min, final int max, final LabelNode dflt, public TableSwitchInsnNode(final int min, final int max,
final LabelNode... labels) { final LabelNode dflt, final LabelNode... labels) {
super(Opcodes.TABLESWITCH); super(Opcodes.TABLESWITCH);
this.min = min; this.min = min;
this.max = max; this.max = max;
@@ -94,6 +107,7 @@ public class TableSwitchInsnNode extends AbstractInsnNode {
@Override @Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(this.labels, labels)); return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(
this.labels, labels));
} }
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -46,22 +54,27 @@ public class TryCatchBlockNode {
public LabelNode handler; public LabelNode handler;
/** /**
* Internal name of the type of exceptions handled by the handler. May be <tt>null</tt> to catch * Internal name of the type of exceptions handled by the handler. May be
* any exceptions (for "finally" blocks). * <tt>null</tt> to catch any exceptions (for "finally" blocks).
*/ */
public String type; public String type;
/** /**
* Constructs a new {@link TryCatchBlockNode}. * Constructs a new {@link TryCatchBlockNode}.
* *
* @param start beginning of the exception handler's scope (inclusive). * @param start
* @param end end of the exception handler's scope (exclusive). * beginning of the exception handler's scope (inclusive).
* @param handler beginning of the exception handler's code. * @param end
* @param type internal name of the type of exceptions handled by the handler, or <tt>null</tt> * end of the exception handler's scope (exclusive).
* to catch any exceptions (for "finally" blocks). * @param handler
* beginning of the exception handler's code.
* @param type
* internal name of the type of exceptions handled by the
* handler, or <tt>null</tt> to catch any exceptions (for
* "finally" blocks).
*/ */
public TryCatchBlockNode(final LabelNode start, final LabelNode end, final LabelNode handler, public TryCatchBlockNode(final LabelNode start, final LabelNode end,
final String type) { final LabelNode handler, final String type) {
this.start = start; this.start = start;
this.end = end; this.end = end;
this.handler = handler; this.handler = handler;
@@ -71,7 +84,8 @@ public class TryCatchBlockNode {
/** /**
* Makes the given visitor visit this try catch block. * Makes the given visitor visit this try catch block.
* *
* @param mv a method visitor. * @param mv
* a method visitor.
*/ */
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
mv.visitTryCatchBlock(start.getLabel(), end.getLabel(), mv.visitTryCatchBlock(start.getLabel(), end.getLabel(),

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -26,8 +34,8 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a type instruction. A type instruction is an instruction that takes a type * A node that represents a type instruction. A type instruction is an
* descriptor as parameter. * instruction that takes a type descriptor as parameter.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -42,10 +50,12 @@ public class TypeInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link TypeInsnNode}. * Constructs a new {@link TypeInsnNode}.
* *
* @param opcode the opcode of the type instruction to be constructed. This opcode must be NEW, * @param opcode
* ANEWARRAY, CHECKCAST or INSTANCEOF. * the opcode of the type instruction to be constructed. This
* @param desc the operand of the instruction to be constructed. This operand is an internal * opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
* name (see {@link org.objectweb.asm.Type}). * @param desc
* the operand of the instruction to be constructed. This operand
* is an internal name (see {@link org.objectweb.asm.Type}).
*/ */
public TypeInsnNode(final int opcode, final String desc) { public TypeInsnNode(final int opcode, final String desc) {
super(opcode); super(opcode);
@@ -55,8 +65,9 @@ public class TypeInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode the new instruction opcode. This opcode must be NEW, ANEWARRAY, CHECKCAST or * @param opcode
* INSTANCEOF. * the new instruction opcode. This opcode must be NEW,
* ANEWARRAY, CHECKCAST or INSTANCEOF.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree; package org.objectweb.asm.tree;
@@ -26,26 +34,30 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a local variable instruction. A local variable instruction is an * A node that represents a local variable instruction. A local variable
* instruction that loads or stores the value of a local variable. * instruction is an instruction that loads or stores the value of a local
* variable.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class VarInsnNode extends AbstractInsnNode { public class VarInsnNode extends AbstractInsnNode {
/** /**
* The operand of this instruction. This operand is the index of a local variable. * The operand of this instruction. This operand is the index of a local
* variable.
*/ */
public int var; public int var;
/** /**
* Constructs a new {@link VarInsnNode}. * Constructs a new {@link VarInsnNode}.
* *
* @param opcode the opcode of the local variable instruction to be constructed. This opcode * @param opcode
* must be ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or * the opcode of the local variable instruction to be
* RET. * constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD,
* @param var the operand of the instruction to be constructed. This operand is the index of a * ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* local variable. * @param var
* the operand of the instruction to be constructed. This operand
* is the index of a local variable.
*/ */
public VarInsnNode(final int opcode, final int var) { public VarInsnNode(final int opcode, final int var) {
super(opcode); super(opcode);
@@ -55,8 +67,10 @@ public class VarInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode the new instruction opcode. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD, * @param opcode
* ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. * the new instruction opcode. This opcode must be ILOAD, LLOAD,
* FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or
* RET.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
@@ -40,10 +48,11 @@ import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.VarInsnNode; import org.objectweb.asm.tree.VarInsnNode;
/** /**
* A semantic bytecode analyzer. <i>This class does not fully check that JSR and RET instructions * A semantic bytecode analyzer. <i>This class does not fully check that JSR and
* are valid.</i> * RET instructions are valid.</i>
* *
* @param <V> type of the Value used for the analysis. * @param <V>
* type of the Value used for the analysis.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -70,8 +79,9 @@ public class Analyzer<V extends Value> implements Opcodes {
/** /**
* Constructs a new {@link Analyzer}. * Constructs a new {@link Analyzer}.
* *
* @param interpreter the interpreter to be used to symbolically interpret the bytecode * @param interpreter
* instructions. * the interpreter to be used to symbolically interpret the
* bytecode instructions.
*/ */
public Analyzer(final Interpreter<V> interpreter) { public Analyzer(final Interpreter<V> interpreter) {
this.interpreter = interpreter; this.interpreter = interpreter;
@@ -80,15 +90,20 @@ public class Analyzer<V extends Value> implements Opcodes {
/** /**
* Analyzes the given method. * Analyzes the given method.
* *
* @param owner the internal name of the class to which the method belongs. * @param owner
* @param m the method to be analyzed. * the internal name of the class to which the method belongs.
* @return the symbolic state of the execution stack frame at each bytecode instruction of the * @param m
* method. The size of the returned array is equal to the number of instructions (and * the method to be analyzed.
* labels) of the method. A given frame is <tt>null</tt> if and only if the * @return the symbolic state of the execution stack frame at each bytecode
* corresponding instruction cannot be reached (dead code). * instruction of the method. The size of the returned array is
* @throws AnalyzerException if a problem occurs during the analysis. * equal to the number of instructions (and labels) of the method. A
* given frame is <tt>null</tt> if and only if the corresponding
* instruction cannot be reached (dead code).
* @throws AnalyzerException
* if a problem occurs during the analysis.
*/ */
public Frame<V>[] analyze(final String owner, final MethodNode m) throws AnalyzerException { public Frame<V>[] analyze(final String owner, final MethodNode m)
throws AnalyzerException {
if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) { if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
frames = (Frame<V>[]) new Frame<?>[0]; frames = (Frame<V>[]) new Frame<?>[0];
return frames; return frames;
@@ -175,7 +190,8 @@ public class Analyzer<V extends Value> implements Opcodes {
int insnOpcode = insnNode.getOpcode(); int insnOpcode = insnNode.getOpcode();
int insnType = insnNode.getType(); int insnType = insnNode.getType();
if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE if (insnType == AbstractInsnNode.LABEL
|| insnType == AbstractInsnNode.LINE
|| insnType == AbstractInsnNode.FRAME) { || insnType == AbstractInsnNode.FRAME) {
merge(insn + 1, f, subroutine); merge(insn + 1, f, subroutine);
newControlFlowEdge(insn, insn + 1); newControlFlowEdge(insn, insn + 1);
@@ -191,7 +207,8 @@ public class Analyzer<V extends Value> implements Opcodes {
} }
int jump = insns.indexOf(j.label); int jump = insns.indexOf(j.label);
if (insnOpcode == JSR) { if (insnOpcode == JSR) {
merge(jump, current, new Subroutine(j.label, m.maxLocals, j)); merge(jump, current, new Subroutine(j.label,
m.maxLocals, j));
} else { } else {
merge(jump, current, subroutine); merge(jump, current, subroutine);
} }
@@ -227,8 +244,8 @@ public class Analyzer<V extends Value> implements Opcodes {
JumpInsnNode caller = subroutine.callers.get(i); JumpInsnNode caller = subroutine.callers.get(i);
int call = insns.indexOf(caller); int call = insns.indexOf(caller);
if (frames[call] != null) { if (frames[call] != null) {
merge(call + 1, frames[call], current, subroutines[call], merge(call + 1, frames[call], current,
subroutine.access); subroutines[call], subroutine.access);
newControlFlowEdge(insn, call + 1); newControlFlowEdge(insn, call + 1);
} }
} }
@@ -239,7 +256,8 @@ public class Analyzer<V extends Value> implements Opcodes {
int var = ((VarInsnNode) insnNode).var; int var = ((VarInsnNode) insnNode).var;
subroutine.access[var] = true; subroutine.access[var] = true;
if (insnOpcode == LLOAD || insnOpcode == DLOAD if (insnOpcode == LLOAD || insnOpcode == DLOAD
|| insnOpcode == LSTORE || insnOpcode == DSTORE) { || insnOpcode == LSTORE
|| insnOpcode == DSTORE) {
subroutine.access[var + 1] = true; subroutine.access[var + 1] = true;
} }
} else if (insnNode instanceof IincInsnNode) { } else if (insnNode instanceof IincInsnNode) {
@@ -272,22 +290,23 @@ public class Analyzer<V extends Value> implements Opcodes {
} }
} }
} catch (AnalyzerException e) { } catch (AnalyzerException e) {
throw new AnalyzerException(e.node, throw new AnalyzerException(e.node, "Error at instruction "
"Error at instruction " + insn + ": " + e.getMessage(), e); + insn + ": " + e.getMessage(), e);
} catch (Exception e) { } catch (Exception e) {
throw new AnalyzerException(insnNode, throw new AnalyzerException(insnNode, "Error at instruction "
"Error at instruction " + insn + ": " + e.getMessage(), e); + insn + ": " + e.getMessage(), e);
} }
} }
return frames; return frames;
} }
private void findSubroutine(int insn, final Subroutine sub, final List<AbstractInsnNode> calls) private void findSubroutine(int insn, final Subroutine sub,
throws AnalyzerException { final List<AbstractInsnNode> calls) throws AnalyzerException {
while (true) { while (true) {
if (insn < 0 || insn >= n) { if (insn < 0 || insn >= n) {
throw new AnalyzerException(null, "Execution can fall off end of the code"); throw new AnalyzerException(null,
"Execution can fall off end of the code");
} }
if (subroutines[insn] != null) { if (subroutines[insn] != null) {
return; return;
@@ -349,13 +368,15 @@ public class Analyzer<V extends Value> implements Opcodes {
} }
/** /**
* Returns the symbolic stack frame for each instruction of the last recently analyzed method. * Returns the symbolic stack frame for each instruction of the last
* recently analyzed method.
* *
* @return the symbolic state of the execution stack frame at each bytecode instruction of the * @return the symbolic state of the execution stack frame at each bytecode
* method. The size of the returned array is equal to the number of instructions (and * instruction of the method. The size of the returned array is
* labels) of the method. A given frame is <tt>null</tt> if the corresponding * equal to the number of instructions (and labels) of the method. A
* instruction cannot be reached, or if an error occured during the analysis of the * given frame is <tt>null</tt> if the corresponding instruction
* method. * cannot be reached, or if an error occured during the analysis of
* the method.
*/ */
public Frame<V>[] getFrames() { public Frame<V>[] getFrames() {
return frames; return frames;
@@ -364,7 +385,9 @@ public class Analyzer<V extends Value> implements Opcodes {
/** /**
* Returns the exception handlers for the given instruction. * Returns the exception handlers for the given instruction.
* *
* @param insn the index of an instruction of the last recently analyzed method. * @param insn
* the index of an instruction of the last recently analyzed
* method.
* @return a list of {@link TryCatchBlockNode} objects. * @return a list of {@link TryCatchBlockNode} objects.
*/ */
public List<TryCatchBlockNode> getHandlers(final int insn) { public List<TryCatchBlockNode> getHandlers(final int insn) {
@@ -372,20 +395,27 @@ public class Analyzer<V extends Value> implements Opcodes {
} }
/** /**
* Initializes this analyzer. This method is called just before the execution of control flow * Initializes this analyzer. This method is called just before the
* analysis loop in #analyze. The default implementation of this method does nothing. * execution of control flow analysis loop in #analyze. The default
* implementation of this method does nothing.
* *
* @param owner the internal name of the class to which the method belongs. * @param owner
* @param m the method to be analyzed. * the internal name of the class to which the method belongs.
* @throws AnalyzerException if a problem occurs. * @param m
* the method to be analyzed.
* @throws AnalyzerException
* if a problem occurs.
*/ */
protected void init(String owner, MethodNode m) throws AnalyzerException {} protected void init(String owner, MethodNode m) throws AnalyzerException {
}
/** /**
* Constructs a new frame with the given size. * Constructs a new frame with the given size.
* *
* @param nLocals the maximum number of local variables of the frame. * @param nLocals
* @param nStack the maximum stack size of the frame. * the maximum number of local variables of the frame.
* @param nStack
* the maximum stack size of the frame.
* @return the created frame. * @return the created frame.
*/ */
protected Frame<V> newFrame(final int nLocals, final int nStack) { protected Frame<V> newFrame(final int nLocals, final int nStack) {
@@ -395,7 +425,8 @@ public class Analyzer<V extends Value> implements Opcodes {
/** /**
* Constructs a new frame that is identical to the given frame. * Constructs a new frame that is identical to the given frame.
* *
* @param src a frame. * @param src
* a frame.
* @return the created frame. * @return the created frame.
*/ */
protected Frame<V> newFrame(final Frame<? extends V> src) { protected Frame<V> newFrame(final Frame<? extends V> src) {
@@ -403,52 +434,67 @@ public class Analyzer<V extends Value> implements Opcodes {
} }
/** /**
* Creates a control flow graph edge. The default implementation of this method does nothing. It * Creates a control flow graph edge. The default implementation of this
* can be overriden in order to construct the control flow graph of a method (this method is * method does nothing. It can be overriden in order to construct the
* called by the {@link #analyze analyze} method during its visit of the method's code). * control flow graph of a method (this method is called by the
* {@link #analyze analyze} method during its visit of the method's code).
* *
* @param insn an instruction index. * @param insn
* @param successor index of a successor instruction. * an instruction index.
* @param successor
* index of a successor instruction.
*/ */
protected void newControlFlowEdge(final int insn, final int successor) {} protected void newControlFlowEdge(final int insn, final int successor) {
}
/** /**
* Creates a control flow graph edge corresponding to an exception handler. The default * Creates a control flow graph edge corresponding to an exception handler.
* implementation of this method does nothing. It can be overridden in order to construct the * The default implementation of this method does nothing. It can be
* control flow graph of a method (this method is called by the {@link #analyze analyze} method * overridden in order to construct the control flow graph of a method (this
* during its visit of the method's code). * method is called by the {@link #analyze analyze} method during its visit
* of the method's code).
* *
* @param insn an instruction index. * @param insn
* @param successor index of a successor instruction. * an instruction index.
* @return true if this edge must be considered in the data flow analysis performed by this * @param successor
* analyzer, or false otherwise. The default implementation of this method always * index of a successor instruction.
* returns true. * @return true if this edge must be considered in the data flow analysis
* performed by this analyzer, or false otherwise. The default
* implementation of this method always returns true.
*/ */
protected boolean newControlFlowExceptionEdge(final int insn, final int successor) { protected boolean newControlFlowExceptionEdge(final int insn,
final int successor) {
return true; return true;
} }
/** /**
* Creates a control flow graph edge corresponding to an exception handler. The default * Creates a control flow graph edge corresponding to an exception handler.
* implementation of this method delegates to {@link #newControlFlowExceptionEdge(int, int) * The default implementation of this method delegates to
* newControlFlowExceptionEdge(int, int)}. It can be overridden in order to construct the * {@link #newControlFlowExceptionEdge(int, int)
* control flow graph of a method (this method is called by the {@link #analyze analyze} method * newControlFlowExceptionEdge(int, int)}. It can be overridden in order to
* during its visit of the method's code). * construct the control flow graph of a method (this method is called by
* the {@link #analyze analyze} method during its visit of the method's
* code).
* *
* @param insn an instruction index. * @param insn
* @param tcb TryCatchBlockNode corresponding to this edge. * an instruction index.
* @return true if this edge must be considered in the data flow analysis performed by this * @param tcb
* analyzer, or false otherwise. The default implementation of this method delegates to * TryCatchBlockNode corresponding to this edge.
* {@link #newControlFlowExceptionEdge(int, int) newControlFlowExceptionEdge(int, int)}. * @return true if this edge must be considered in the data flow analysis
* performed by this analyzer, or false otherwise. The default
* implementation of this method delegates to
* {@link #newControlFlowExceptionEdge(int, int)
* newControlFlowExceptionEdge(int, int)}.
*/ */
protected boolean newControlFlowExceptionEdge(final int insn, final TryCatchBlockNode tcb) { protected boolean newControlFlowExceptionEdge(final int insn,
final TryCatchBlockNode tcb) {
return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler)); return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler));
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
private void merge(final int insn, final Frame<V> frame, final Subroutine subroutine) private void merge(final int insn, final Frame<V> frame,
throws AnalyzerException { final Subroutine subroutine) throws AnalyzerException {
Frame<V> oldFrame = frames[insn]; Frame<V> oldFrame = frames[insn];
Subroutine oldSubroutine = subroutines[insn]; Subroutine oldSubroutine = subroutines[insn];
boolean changes; boolean changes;
@@ -476,8 +522,9 @@ public class Analyzer<V extends Value> implements Opcodes {
} }
} }
private void merge(final int insn, final Frame<V> beforeJSR, final Frame<V> afterRET, private void merge(final int insn, final Frame<V> beforeJSR,
final Subroutine subroutineBeforeJSR, final boolean[] access) throws AnalyzerException { final Frame<V> afterRET, final Subroutine subroutineBeforeJSR,
final boolean[] access) throws AnalyzerException {
Frame<V> oldFrame = frames[insn]; Frame<V> oldFrame = frames[insn];
Subroutine oldSubroutine = subroutines[insn]; Subroutine oldSubroutine = subroutines[insn];
boolean changes; boolean changes;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
@@ -44,10 +52,10 @@ public class AnalyzerException extends Exception {
this.node = node; this.node = node;
} }
public AnalyzerException(final AbstractInsnNode node, final String msg, final Object expected, public AnalyzerException(final AbstractInsnNode node, final String msg,
final Value encountered) { final Object expected, final Value encountered) {
super((msg == null ? "Expected " : msg + ": expected ") + expected + ", but found " super((msg == null ? "Expected " : msg + ": expected ") + expected
+ encountered); + ", but found " + encountered);
this.node = node; this.node = node;
} }
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
@@ -41,7 +49,8 @@ import org.objectweb.asm.tree.TypeInsnNode;
* @author Eric Bruneton * @author Eric Bruneton
* @author Bing Ran * @author Bing Ran
*/ */
public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes { public class BasicInterpreter extends Interpreter<BasicValue> implements
Opcodes {
public BasicInterpreter() { public BasicInterpreter() {
super(ASM4); super(ASM4);
@@ -80,7 +89,8 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
} }
@Override @Override
public BasicValue newOperation(final AbstractInsnNode insn) throws AnalyzerException { public BasicValue newOperation(final AbstractInsnNode insn)
throws AnalyzerException {
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case ACONST_NULL: case ACONST_NULL:
return newValue(Type.getObjectType("null")); return newValue(Type.getObjectType("null"));
@@ -122,14 +132,18 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
if (sort == Type.OBJECT || sort == Type.ARRAY) { if (sort == Type.OBJECT || sort == Type.ARRAY) {
return newValue(Type.getObjectType("java/lang/Class")); return newValue(Type.getObjectType("java/lang/Class"));
} else if (sort == Type.METHOD) { } else if (sort == Type.METHOD) {
return newValue(Type.getObjectType("java/lang/invoke/MethodType")); return newValue(Type
.getObjectType("java/lang/invoke/MethodType"));
} else { } else {
throw new IllegalArgumentException("Illegal LDC constant " + cst); throw new IllegalArgumentException("Illegal LDC constant "
+ cst);
} }
} else if (cst instanceof Handle) { } else if (cst instanceof Handle) {
return newValue(Type.getObjectType("java/lang/invoke/MethodHandle")); return newValue(Type
.getObjectType("java/lang/invoke/MethodHandle"));
} else { } else {
throw new IllegalArgumentException("Illegal LDC constant " + cst); throw new IllegalArgumentException("Illegal LDC constant "
+ cst);
} }
case JSR: case JSR:
return BasicValue.RETURNADDRESS_VALUE; return BasicValue.RETURNADDRESS_VALUE;
@@ -143,14 +157,14 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
} }
@Override @Override
public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value) public BasicValue copyOperation(final AbstractInsnNode insn,
throws AnalyzerException { final BasicValue value) throws AnalyzerException {
return value; return value;
} }
@Override @Override
public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value) public BasicValue unaryOperation(final AbstractInsnNode insn,
throws AnalyzerException { final BasicValue value) throws AnalyzerException {
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case INEG: case INEG:
case IINC: case IINC:
@@ -237,8 +251,9 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
} }
@Override @Override
public BasicValue binaryOperation(final AbstractInsnNode insn, final BasicValue value1, public BasicValue binaryOperation(final AbstractInsnNode insn,
final BasicValue value2) throws AnalyzerException { final BasicValue value1, final BasicValue value2)
throws AnalyzerException {
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case IALOAD: case IALOAD:
case BALOAD: case BALOAD:
@@ -307,8 +322,9 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
} }
@Override @Override
public BasicValue ternaryOperation(final AbstractInsnNode insn, final BasicValue value1, public BasicValue ternaryOperation(final AbstractInsnNode insn,
final BasicValue value2, final BasicValue value3) throws AnalyzerException { final BasicValue value1, final BasicValue value2,
final BasicValue value3) throws AnalyzerException {
return null; return null;
} }
@@ -319,15 +335,18 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
if (opcode == MULTIANEWARRAY) { if (opcode == MULTIANEWARRAY) {
return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc)); return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
} else if (opcode == INVOKEDYNAMIC) { } else if (opcode == INVOKEDYNAMIC) {
return newValue(Type.getReturnType(((InvokeDynamicInsnNode) insn).desc)); return newValue(Type
.getReturnType(((InvokeDynamicInsnNode) insn).desc));
} else { } else {
return newValue(Type.getReturnType(((MethodInsnNode) insn).desc)); return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
} }
} }
@Override @Override
public void returnOperation(final AbstractInsnNode insn, final BasicValue value, public void returnOperation(final AbstractInsnNode insn,
final BasicValue expected) throws AnalyzerException {} final BasicValue value, final BasicValue expected)
throws AnalyzerException {
}
@Override @Override
public BasicValue merge(final BasicValue v, final BasicValue w) { public BasicValue merge(final BasicValue v, final BasicValue w) {

View File

@@ -1,31 +1,40 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
/** /**
* A {@link Value} that is represented by its type in a seven types type system. This type system * A {@link Value} that is represented by its type in a seven types type system.
* distinguishes the UNINITIALZED, INT, FLOAT, LONG, DOUBLE, REFERENCE and RETURNADDRESS types. * This type system distinguishes the UNINITIALZED, INT, FLOAT, LONG, DOUBLE,
* REFERENCE and RETURNADDRESS types.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -39,12 +48,14 @@ public class BasicValue implements Value {
public static final BasicValue LONG_VALUE = new BasicValue(Type.LONG_TYPE); public static final BasicValue LONG_VALUE = new BasicValue(Type.LONG_TYPE);
public static final BasicValue DOUBLE_VALUE = new BasicValue(Type.DOUBLE_TYPE); public static final BasicValue DOUBLE_VALUE = new BasicValue(
Type.DOUBLE_TYPE);
public static final BasicValue REFERENCE_VALUE = public static final BasicValue REFERENCE_VALUE = new BasicValue(
new BasicValue(Type.getObjectType("java/lang/Object")); Type.getObjectType("java/lang/Object"));
public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(Type.VOID_TYPE); public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(
Type.VOID_TYPE);
private final Type type; private final Type type;
@@ -61,7 +72,8 @@ public class BasicValue implements Value {
} }
public boolean isReference() { public boolean isReference() {
return type != null && (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY); return type != null
&& (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY);
} }
@Override @Override

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
@@ -30,7 +38,8 @@ import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodInsnNode;
/** /**
* An extended {@link BasicInterpreter} that checks that bytecode instructions are correctly used. * An extended {@link BasicInterpreter} that checks that bytecode instructions
* are correctly used.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Bing Ran * @author Bing Ran
@@ -46,8 +55,8 @@ public class BasicVerifier extends BasicInterpreter {
} }
@Override @Override
public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value) public BasicValue copyOperation(final AbstractInsnNode insn,
throws AnalyzerException { final BasicValue value) throws AnalyzerException {
Value expected; Value expected;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case ILOAD: case ILOAD:
@@ -68,11 +77,13 @@ public class BasicVerifier extends BasicInterpreter {
break; break;
case ALOAD: case ALOAD:
if (!value.isReference()) { if (!value.isReference()) {
throw new AnalyzerException(insn, null, "an object reference", value); throw new AnalyzerException(insn, null, "an object reference",
value);
} }
return value; return value;
case ASTORE: case ASTORE:
if (!value.isReference() && !BasicValue.RETURNADDRESS_VALUE.equals(value)) { if (!value.isReference()
&& !BasicValue.RETURNADDRESS_VALUE.equals(value)) {
throw new AnalyzerException(insn, null, throw new AnalyzerException(insn, null,
"an object reference or a return address", value); "an object reference or a return address", value);
} }
@@ -87,8 +98,8 @@ public class BasicVerifier extends BasicInterpreter {
} }
@Override @Override
public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value) public BasicValue unaryOperation(final AbstractInsnNode insn,
throws AnalyzerException { final BasicValue value) throws AnalyzerException {
BasicValue expected; BasicValue expected;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case INEG: case INEG:
@@ -134,16 +145,19 @@ public class BasicVerifier extends BasicInterpreter {
expected = BasicValue.DOUBLE_VALUE; expected = BasicValue.DOUBLE_VALUE;
break; break;
case GETFIELD: case GETFIELD:
expected = newValue(Type.getObjectType(((FieldInsnNode) insn).owner)); expected = newValue(Type
.getObjectType(((FieldInsnNode) insn).owner));
break; break;
case CHECKCAST: case CHECKCAST:
if (!value.isReference()) { if (!value.isReference()) {
throw new AnalyzerException(insn, null, "an object reference", value); throw new AnalyzerException(insn, null, "an object reference",
value);
} }
return super.unaryOperation(insn, value); return super.unaryOperation(insn, value);
case ARRAYLENGTH: case ARRAYLENGTH:
if (!isArrayValue(value)) { if (!isArrayValue(value)) {
throw new AnalyzerException(insn, null, "an array reference", value); throw new AnalyzerException(insn, null, "an array reference",
value);
} }
return super.unaryOperation(insn, value); return super.unaryOperation(insn, value);
case ARETURN: case ARETURN:
@@ -154,7 +168,8 @@ public class BasicVerifier extends BasicInterpreter {
case IFNULL: case IFNULL:
case IFNONNULL: case IFNONNULL:
if (!value.isReference()) { if (!value.isReference()) {
throw new AnalyzerException(insn, null, "an object reference", value); throw new AnalyzerException(insn, null, "an object reference",
value);
} }
return super.unaryOperation(insn, value); return super.unaryOperation(insn, value);
case PUTSTATIC: case PUTSTATIC:
@@ -170,8 +185,9 @@ public class BasicVerifier extends BasicInterpreter {
} }
@Override @Override
public BasicValue binaryOperation(final AbstractInsnNode insn, final BasicValue value1, public BasicValue binaryOperation(final AbstractInsnNode insn,
final BasicValue value2) throws AnalyzerException { final BasicValue value1, final BasicValue value2)
throws AnalyzerException {
BasicValue expected1; BasicValue expected1;
BasicValue expected2; BasicValue expected2;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
@@ -283,9 +299,11 @@ public class BasicVerifier extends BasicInterpreter {
throw new Error("Internal error."); throw new Error("Internal error.");
} }
if (!isSubTypeOf(value1, expected1)) { if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException(insn, "First argument", expected1, value1); throw new AnalyzerException(insn, "First argument", expected1,
value1);
} else if (!isSubTypeOf(value2, expected2)) { } else if (!isSubTypeOf(value2, expected2)) {
throw new AnalyzerException(insn, "Second argument", expected2, value2); throw new AnalyzerException(insn, "Second argument", expected2,
value2);
} }
if (insn.getOpcode() == AALOAD) { if (insn.getOpcode() == AALOAD) {
return getElementValue(value1); return getElementValue(value1);
@@ -295,8 +313,9 @@ public class BasicVerifier extends BasicInterpreter {
} }
@Override @Override
public BasicValue ternaryOperation(final AbstractInsnNode insn, final BasicValue value1, public BasicValue ternaryOperation(final AbstractInsnNode insn,
final BasicValue value2, final BasicValue value3) throws AnalyzerException { final BasicValue value1, final BasicValue value2,
final BasicValue value3) throws AnalyzerException {
BasicValue expected1; BasicValue expected1;
BasicValue expected3; BasicValue expected3;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
@@ -340,12 +359,14 @@ public class BasicVerifier extends BasicInterpreter {
throw new Error("Internal error."); throw new Error("Internal error.");
} }
if (!isSubTypeOf(value1, expected1)) { if (!isSubTypeOf(value1, expected1)) {
throw new AnalyzerException(insn, "First argument", throw new AnalyzerException(insn, "First argument", "a "
"a " + expected1 + " array reference", value1); + expected1 + " array reference", value1);
} else if (!BasicValue.INT_VALUE.equals(value2)) { } else if (!BasicValue.INT_VALUE.equals(value2)) {
throw new AnalyzerException(insn, "Second argument", BasicValue.INT_VALUE, value2); throw new AnalyzerException(insn, "Second argument",
BasicValue.INT_VALUE, value2);
} else if (!isSubTypeOf(value3, expected3)) { } else if (!isSubTypeOf(value3, expected3)) {
throw new AnalyzerException(insn, "Third argument", expected3, value3); throw new AnalyzerException(insn, "Third argument", expected3,
value3);
} }
return null; return null;
} }
@@ -357,7 +378,8 @@ public class BasicVerifier extends BasicInterpreter {
if (opcode == MULTIANEWARRAY) { if (opcode == MULTIANEWARRAY) {
for (int i = 0; i < values.size(); ++i) { for (int i = 0; i < values.size(); ++i) {
if (!BasicValue.INT_VALUE.equals(values.get(i))) { if (!BasicValue.INT_VALUE.equals(values.get(i))) {
throw new AnalyzerException(insn, null, BasicValue.INT_VALUE, values.get(i)); throw new AnalyzerException(insn, null,
BasicValue.INT_VALUE, values.get(i));
} }
} }
} else { } else {
@@ -366,8 +388,8 @@ public class BasicVerifier extends BasicInterpreter {
if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) { if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) {
Type owner = Type.getObjectType(((MethodInsnNode) insn).owner); Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
if (!isSubTypeOf(values.get(i++), newValue(owner))) { if (!isSubTypeOf(values.get(i++), newValue(owner))) {
throw new AnalyzerException(insn, "Method owner", newValue(owner), throw new AnalyzerException(insn, "Method owner",
values.get(0)); newValue(owner), values.get(0));
} }
} }
String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
@@ -377,7 +399,8 @@ public class BasicVerifier extends BasicInterpreter {
BasicValue expected = newValue(args[j++]); BasicValue expected = newValue(args[j++]);
BasicValue encountered = values.get(i++); BasicValue encountered = values.get(i++);
if (!isSubTypeOf(encountered, expected)) { if (!isSubTypeOf(encountered, expected)) {
throw new AnalyzerException(insn, "Argument " + j, expected, encountered); throw new AnalyzerException(insn, "Argument " + j,
expected, encountered);
} }
} }
} }
@@ -385,10 +408,12 @@ public class BasicVerifier extends BasicInterpreter {
} }
@Override @Override
public void returnOperation(final AbstractInsnNode insn, final BasicValue value, public void returnOperation(final AbstractInsnNode insn,
final BasicValue expected) throws AnalyzerException { final BasicValue value, final BasicValue expected)
throws AnalyzerException {
if (!isSubTypeOf(value, expected)) { if (!isSubTypeOf(value, expected)) {
throw new AnalyzerException(insn, "Incompatible return type", expected, value); throw new AnalyzerException(insn, "Incompatible return type",
expected, value);
} }
} }
@@ -401,7 +426,8 @@ public class BasicVerifier extends BasicInterpreter {
return BasicValue.REFERENCE_VALUE; return BasicValue.REFERENCE_VALUE;
} }
protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) { protected boolean isSubTypeOf(final BasicValue value,
final BasicValue expected) {
return value.equals(expected); return value.equals(expected);
} }
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
@@ -34,9 +42,10 @@ import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.VarInsnNode; import org.objectweb.asm.tree.VarInsnNode;
/** /**
* A symbolic execution stack frame. A stack frame contains a set of local variable slots, and an * A symbolic execution stack frame. A stack frame contains a set of local
* operand stack. Warning: long and double values are represented by <i>two</i> slots in local * variable slots, and an operand stack. Warning: long and double values are
* variables, and by <i>one</i> slot in the operand stack. * represented by <i>two</i> slots in local variables, and by <i>one</i> slot in
* the operand stack.
* *
* @param <V> type of the Value used for the analysis. * @param <V> type of the Value used for the analysis.
* *
@@ -45,7 +54,8 @@ import org.objectweb.asm.tree.VarInsnNode;
public class Frame<V extends Value> { public class Frame<V extends Value> {
/** /**
* The expected return type of the analyzed method, or <tt>null</tt> if the method returns void. * The expected return type of the analyzed method, or <tt>null</tt> if the
* method returns void.
*/ */
private V returnValue; private V returnValue;
@@ -101,8 +111,8 @@ public class Frame<V extends Value> {
/** /**
* Sets the expected return type of the analyzed method. * Sets the expected return type of the analyzed method.
* *
* @param v the expected return type of the analyzed method, or <tt>null</tt> if the method * @param v the expected return type of the analyzed method, or <tt>null</tt> if
* returns void. * the method returns void.
*/ */
public void setReturn(final V v) { public void setReturn(final V v) {
returnValue = v; returnValue = v;
@@ -140,15 +150,14 @@ public class Frame<V extends Value> {
*/ */
public void setLocal(final int i, final V value) throws IndexOutOfBoundsException { public void setLocal(final int i, final V value) throws IndexOutOfBoundsException {
if (i >= locals) { if (i >= locals) {
throw new IndexOutOfBoundsException( throw new IndexOutOfBoundsException("Trying to access an inexistant local variable " + i);
"Trying to access an inexistant local variable " + i);
} }
values[i] = value; values[i] = value;
} }
/** /**
* Returns the number of values in the operand stack of this frame. Long and double values are * Returns the number of values in the operand stack of this frame. Long and
* treated as single values. * double values are treated as single values.
* *
* @return the number of values in the operand stack of this frame. * @return the number of values in the operand stack of this frame.
*/ */
@@ -204,8 +213,7 @@ public class Frame<V extends Value> {
values[top++ + locals] = value; values[top++ + locals] = value;
} }
public void execute(final AbstractInsnNode insn, final Interpreter<V> interpreter) public void execute(final AbstractInsnNode insn, final Interpreter<V> interpreter) throws AnalyzerException {
throws AnalyzerException {
V value1, value2, value3, value4; V value1, value2, value3, value4;
List<V> values; List<V> values;
int var; int var;
@@ -637,12 +645,11 @@ public class Frame<V extends Value> {
* *
* @param frame a frame. * @param frame a frame.
* @param interpreter the interpreter used to merge values. * @param interpreter the interpreter used to merge values.
* @return <tt>true</tt> if this frame has been changed as a result of the merge operation, or * @return <tt>true</tt> if this frame has been changed as a result of the merge
* <tt>false</tt> otherwise. * operation, or <tt>false</tt> otherwise.
* @throws AnalyzerException if the frames have incompatible sizes. * @throws AnalyzerException if the frames have incompatible sizes.
*/ */
public boolean merge(final Frame<? extends V> frame, final Interpreter<V> interpreter) public boolean merge(final Frame<? extends V> frame, final Interpreter<V> interpreter) throws AnalyzerException {
throws AnalyzerException {
if (top != frame.top) { if (top != frame.top) {
throw new AnalyzerException(null, "Incompatible stack heights"); throw new AnalyzerException(null, "Incompatible stack heights");
} }
@@ -661,10 +668,10 @@ public class Frame<V extends Value> {
* Merges this frame with the given frame (case of a RET instruction). * Merges this frame with the given frame (case of a RET instruction).
* *
* @param frame a frame * @param frame a frame
* @param access the local variables that have been accessed by the subroutine to which the RET * @param access the local variables that have been accessed by the subroutine
* instruction corresponds. * to which the RET instruction corresponds.
* @return <tt>true</tt> if this frame has been changed as a result of the merge operation, or * @return <tt>true</tt> if this frame has been changed as a result of the merge
* <tt>false</tt> otherwise. * operation, or <tt>false</tt> otherwise.
*/ */
public boolean merge(final Frame<? extends V> frame, final boolean[] access) { public boolean merge(final Frame<? extends V> frame, final boolean[] access) {
boolean changes = false; boolean changes = false;

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
@@ -27,13 +35,15 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
/** /**
* A semantic bytecode interpreter. More precisely, this interpreter only manages the computation of * A semantic bytecode interpreter. More precisely, this interpreter only
* values from other values: it does not manage the transfer of values to or from the stack, and to * manages the computation of values from other values: it does not manage the
* or from the local variables. This separation allows a generic bytecode {@link Analyzer} to work * transfer of values to or from the stack, and to or from the local variables.
* with various semantic interpreters, without needing to duplicate the code to simulate the * This separation allows a generic bytecode {@link Analyzer} to work with
* transfer of values. * various semantic interpreters, without needing to duplicate the code to
* simulate the transfer of values.
* *
* @param <V> type of the Value used for the analysis. * @param <V>
* type of the Value used for the analysis.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -48,133 +58,169 @@ public abstract class Interpreter<V extends Value> {
/** /**
* Creates a new value that represents the given type. * Creates a new value that represents the given type.
* *
* Called for method parameters (including <code>this</code>), exception handler variable and * Called for method parameters (including <code>this</code>), exception
* with <code>null</code> type for variables reserved by long and double types. * handler variable and with <code>null</code> type for variables reserved
* by long and double types.
* *
* @param type a primitive or reference type, or <tt>null</tt> to represent an uninitialized * @param type
* value. * a primitive or reference type, or <tt>null</tt> to represent
* @return a value that represents the given type. The size of the returned value must be equal * an uninitialized value.
* to the size of the given type. * @return a value that represents the given type. The size of the returned
* value must be equal to the size of the given type.
*/ */
public abstract V newValue(Type type); public abstract V newValue(Type type);
/** /**
* Interprets a bytecode instruction without arguments. This method is called for the following * Interprets a bytecode instruction without arguments. This method is
* opcodes: * called for the following opcodes:
* *
* ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4,
* LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, BIPUSH, SIPUSH, LDC, JSR, * ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0,
* GETSTATIC, NEW * DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW
* *
* @param insn the bytecode instruction to be interpreted. * @param insn
* the bytecode instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException if an error occured during the interpretation. * @throws AnalyzerException
* if an error occured during the interpretation.
*/ */
public abstract V newOperation(AbstractInsnNode insn) throws AnalyzerException; public abstract V newOperation(AbstractInsnNode insn)
throws AnalyzerException;
/** /**
* Interprets a bytecode instruction that moves a value on the stack or to or from local * Interprets a bytecode instruction that moves a value on the stack or to
* variables. This method is called for the following opcodes: * or from local variables. This method is called for the following opcodes:
* *
* ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE, DUP, DUP_X1, * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE,
* DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP * ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
* *
* @param insn the bytecode instruction to be interpreted. * @param insn
* @param value the value that must be moved by the instruction. * the bytecode instruction to be interpreted.
* @return the result of the interpretation of the given instruction. The returned value must be * @param value
* <tt>equal</tt> to the given value. * the value that must be moved by the instruction.
* @throws AnalyzerException if an error occured during the interpretation. * @return the result of the interpretation of the given instruction. The
* returned value must be <tt>equal</tt> to the given value.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/ */
public abstract V copyOperation(AbstractInsnNode insn, V value) throws AnalyzerException; public abstract V copyOperation(AbstractInsnNode insn, V value)
throws AnalyzerException;
/** /**
* Interprets a bytecode instruction with a single argument. This method is called for the * Interprets a bytecode instruction with a single argument. This method is
* following opcodes: * called for the following opcodes:
* *
* INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, * INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L,
* I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, TABLESWITCH, LOOKUPSWITCH, IRETURN, * F2D, D2I, D2L, D2F, I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE,
* LRETURN, FRETURN, DRETURN, ARETURN, PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, * TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN,
* ATHROW, CHECKCAST, INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL * PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST,
* INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
* *
* @param insn the bytecode instruction to be interpreted. * @param insn
* @param value the argument of the instruction to be interpreted. * the bytecode instruction to be interpreted.
* @param value
* the argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException if an error occured during the interpretation. * @throws AnalyzerException
* if an error occured during the interpretation.
*/ */
public abstract V unaryOperation(AbstractInsnNode insn, V value) throws AnalyzerException; public abstract V unaryOperation(AbstractInsnNode insn, V value)
throws AnalyzerException;
/** /**
* Interprets a bytecode instruction with two arguments. This method is called for the following * Interprets a bytecode instruction with two arguments. This method is
* opcodes: * called for the following opcodes:
* *
* IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, LADD, FADD, DADD, ISUB, * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD,
* LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, * LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV,
* ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, * LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR,
* DCMPL, DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL,
* IF_ACMPNE, PUTFIELD * DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* IF_ACMPEQ, IF_ACMPNE, PUTFIELD
* *
* @param insn the bytecode instruction to be interpreted. * @param insn
* @param value1 the first argument of the instruction to be interpreted. * the bytecode instruction to be interpreted.
* @param value2 the second argument of the instruction to be interpreted. * @param value1
* the first argument of the instruction to be interpreted.
* @param value2
* the second argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException if an error occured during the interpretation. * @throws AnalyzerException
* if an error occured during the interpretation.
*/ */
public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2) public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
throws AnalyzerException; throws AnalyzerException;
/** /**
* Interprets a bytecode instruction with three arguments. This method is called for the * Interprets a bytecode instruction with three arguments. This method is
* following opcodes: * called for the following opcodes:
* *
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
* *
* @param insn the bytecode instruction to be interpreted. * @param insn
* @param value1 the first argument of the instruction to be interpreted. * the bytecode instruction to be interpreted.
* @param value2 the second argument of the instruction to be interpreted. * @param value1
* @param value3 the third argument of the instruction to be interpreted. * the first argument of the instruction to be interpreted.
* @param value2
* the second argument of the instruction to be interpreted.
* @param value3
* the third argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException if an error occured during the interpretation. * @throws AnalyzerException
* if an error occured during the interpretation.
*/ */
public abstract V ternaryOperation(AbstractInsnNode insn, V value1, V value2, V value3) public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
throws AnalyzerException; V value2, V value3) throws AnalyzerException;
/** /**
* Interprets a bytecode instruction with a variable number of arguments. This method is called * Interprets a bytecode instruction with a variable number of arguments.
* for the following opcodes: * This method is called for the following opcodes:
* *
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY and INVOKEDYNAMIC * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE,
* MULTIANEWARRAY and INVOKEDYNAMIC
* *
* @param insn the bytecode instruction to be interpreted. * @param insn
* @param values the arguments of the instruction to be interpreted. * the bytecode instruction to be interpreted.
* @param values
* the arguments of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction. * @return the result of the interpretation of the given instruction.
* @throws AnalyzerException if an error occured during the interpretation. * @throws AnalyzerException
* if an error occured during the interpretation.
*/ */
public abstract V naryOperation(AbstractInsnNode insn, List<? extends V> values) public abstract V naryOperation(AbstractInsnNode insn,
throws AnalyzerException; List<? extends V> values) throws AnalyzerException;
/** /**
* Interprets a bytecode return instruction. This method is called for the following opcodes: * Interprets a bytecode return instruction. This method is called for the
* following opcodes:
* *
* IRETURN, LRETURN, FRETURN, DRETURN, ARETURN * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
* *
* @param insn the bytecode instruction to be interpreted. * @param insn
* @param value the argument of the instruction to be interpreted. * the bytecode instruction to be interpreted.
* @param expected the expected return type of the analyzed method. * @param value
* @throws AnalyzerException if an error occured during the interpretation. * the argument of the instruction to be interpreted.
* @param expected
* the expected return type of the analyzed method.
* @throws AnalyzerException
* if an error occured during the interpretation.
*/ */
public abstract void returnOperation(AbstractInsnNode insn, V value, V expected) public abstract void returnOperation(AbstractInsnNode insn, V value,
throws AnalyzerException; V expected) throws AnalyzerException;
/** /**
* Merges two values. The merge operation must return a value that represents both values (for * Merges two values. The merge operation must return a value that
* instance, if the two values are two types, the merged value must be a common super type of * represents both values (for instance, if the two values are two types,
* the two types. If the two values are integer intervals, the merged value must be an interval * the merged value must be a common super type of the two types. If the two
* that contains the previous ones. Likewise for other types of values). * values are integer intervals, the merged value must be an interval that
* contains the previous ones. Likewise for other types of values).
* *
* @param v a value. * @param v
* @param w another value. * a value.
* @return the merged value. If the merged value is equal to <tt>v</tt>, this method <i>must</i> * @param w
* return <tt>v</tt>. * another value.
* @return the merged value. If the merged value is equal to <tt>v</tt>,
* this method <i>must</i> return <tt>v</tt>.
*/ */
public abstract V merge(V v, V w); public abstract V merge(V v, V w);
} }

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
@@ -26,9 +34,9 @@ import java.util.List;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
/** /**
* An extended {@link BasicVerifier} that performs more precise verifications. This verifier * An extended {@link BasicVerifier} that performs more precise verifications.
* computes exact class types, instead of using a single "object reference" type (as done in the * This verifier computes exact class types, instead of using a single "object
* {@link BasicVerifier}). * reference" type (as done in the {@link BasicVerifier}).
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Bing Ran * @author Bing Ran
@@ -68,33 +76,43 @@ public class SimpleVerifier extends BasicVerifier {
} }
/** /**
* Constructs a new {@link SimpleVerifier} to verify a specific class. This class will not be * Constructs a new {@link SimpleVerifier} to verify a specific class. This
* loaded into the JVM since it may be incorrect. * class will not be loaded into the JVM since it may be incorrect.
* *
* @param currentClass the class that is verified. * @param currentClass
* @param currentSuperClass the super class of the class that is verified. * the class that is verified.
* @param isInterface if the class that is verified is an interface. * @param currentSuperClass
* the super class of the class that is verified.
* @param isInterface
* if the class that is verified is an interface.
*/ */
public SimpleVerifier(final Type currentClass, final Type currentSuperClass, public SimpleVerifier(final Type currentClass,
final boolean isInterface) { final Type currentSuperClass, final boolean isInterface) {
this(currentClass, currentSuperClass, null, isInterface); this(currentClass, currentSuperClass, null, isInterface);
} }
/** /**
* Constructs a new {@link SimpleVerifier} to verify a specific class. This class will not be * Constructs a new {@link SimpleVerifier} to verify a specific class. This
* loaded into the JVM since it may be incorrect. * class will not be loaded into the JVM since it may be incorrect.
* *
* @param currentClass the class that is verified. * @param currentClass
* @param currentSuperClass the super class of the class that is verified. * the class that is verified.
* @param currentClassInterfaces the interfaces implemented by the class that is verified. * @param currentSuperClass
* @param isInterface if the class that is verified is an interface. * the super class of the class that is verified.
* @param currentClassInterfaces
* the interfaces implemented by the class that is verified.
* @param isInterface
* if the class that is verified is an interface.
*/ */
public SimpleVerifier(final Type currentClass, final Type currentSuperClass, public SimpleVerifier(final Type currentClass,
final Type currentSuperClass,
final List<Type> currentClassInterfaces, final boolean isInterface) { final List<Type> currentClassInterfaces, final boolean isInterface) {
this(ASM4, currentClass, currentSuperClass, currentClassInterfaces, isInterface); this(ASM4, currentClass, currentSuperClass, currentClassInterfaces,
isInterface);
} }
protected SimpleVerifier(final int api, final Type currentClass, final Type currentSuperClass, protected SimpleVerifier(final int api, final Type currentClass,
final Type currentSuperClass,
final List<Type> currentClassInterfaces, final boolean isInterface) { final List<Type> currentClassInterfaces, final boolean isInterface) {
super(api); super(api);
this.currentClass = currentClass; this.currentClass = currentClass;
@@ -104,10 +122,12 @@ public class SimpleVerifier extends BasicVerifier {
} }
/** /**
* Set the <code>ClassLoader</code> which will be used to load referenced classes. This is * Set the <code>ClassLoader</code> which will be used to load referenced
* useful if you are verifying multiple interdependent classes. * classes. This is useful if you are verifying multiple interdependent
* classes.
* *
* @param loader a <code>ClassLoader</code> to use * @param loader
* a <code>ClassLoader</code> to use
*/ */
public void setClassLoader(final ClassLoader loader) { public void setClassLoader(final ClassLoader loader) {
this.loader = loader; this.loader = loader;
@@ -149,7 +169,8 @@ public class SimpleVerifier extends BasicVerifier {
@Override @Override
protected boolean isArrayValue(final BasicValue value) { protected boolean isArrayValue(final BasicValue value) {
Type t = value.getType(); Type t = value.getType();
return t != null && ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY); return t != null
&& ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY);
} }
@Override @Override
@@ -158,7 +179,8 @@ public class SimpleVerifier extends BasicVerifier {
Type arrayType = objectArrayValue.getType(); Type arrayType = objectArrayValue.getType();
if (arrayType != null) { if (arrayType != null) {
if (arrayType.getSort() == Type.ARRAY) { if (arrayType.getSort() == Type.ARRAY) {
return newValue(Type.getType(arrayType.getDescriptor().substring(1))); return newValue(Type.getType(arrayType.getDescriptor()
.substring(1)));
} else if ("Lnull;".equals(arrayType.getDescriptor())) { } else if ("Lnull;".equals(arrayType.getDescriptor())) {
return objectArrayValue; return objectArrayValue;
} }
@@ -167,7 +189,8 @@ public class SimpleVerifier extends BasicVerifier {
} }
@Override @Override
protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) { protected boolean isSubTypeOf(final BasicValue value,
final BasicValue expected) {
Type expectedType = expected.getType(); Type expectedType = expected.getType();
Type type = value.getType(); Type type = value.getType();
switch (expectedType.getSort()) { switch (expectedType.getSort()) {
@@ -180,7 +203,8 @@ public class SimpleVerifier extends BasicVerifier {
case Type.OBJECT: case Type.OBJECT:
if ("Lnull;".equals(type.getDescriptor())) { if ("Lnull;".equals(type.getDescriptor())) {
return true; return true;
} else if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { } else if (type.getSort() == Type.OBJECT
|| type.getSort() == Type.ARRAY) {
return isAssignableFrom(expectedType, type); return isAssignableFrom(expectedType, type);
} else { } else {
return false; return false;
@@ -195,8 +219,10 @@ public class SimpleVerifier extends BasicVerifier {
if (!v.equals(w)) { if (!v.equals(w)) {
Type t = v.getType(); Type t = v.getType();
Type u = w.getType(); Type u = w.getType();
if (t != null && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) { if (t != null
if (u != null && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) { && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) {
if (u != null
&& (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) {
if ("Lnull;".equals(t.getDescriptor())) { if ("Lnull;".equals(t.getDescriptor())) {
return w; return w;
} }
@@ -253,7 +279,8 @@ public class SimpleVerifier extends BasicVerifier {
return false; return false;
} else { } else {
if (isInterface) { if (isInterface) {
return u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY; return u.getSort() == Type.OBJECT
|| u.getSort() == Type.ARRAY;
} }
return isAssignableFrom(t, getSuperClass(u)); return isAssignableFrom(t, getSuperClass(u));
} }
@@ -282,7 +309,8 @@ public class SimpleVerifier extends BasicVerifier {
protected Class<?> getClass(final Type t) { protected Class<?> getClass(final Type t) {
try { try {
if (t.getSort() == Type.ARRAY) { if (t.getSort() == Type.ARRAY) {
return Class.forName(t.getDescriptor().replace('/', '.'), false, loader); return Class.forName(t.getDescriptor().replace('/', '.'),
false, loader);
} }
return Class.forName(t.getClassName(), false, loader); return Class.forName(t.getClassName(), false, loader);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {

View File

@@ -1,23 +1,31 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA, * ASM: a very small and fast Java bytecode manipulation framework
* France Telecom All rights reserved. * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted * Redistribution and use in source and binary forms, with or without
* provided that the following conditions are met: 1. Redistributions of source code must retain the * modification, are permitted provided that the following conditions
* above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions * are met:
* in binary form must reproduce the above copyright notice, this list of conditions and the * 1. Redistributions of source code must retain the above copyright
* following disclaimer in the documentation and/or other materials provided with the distribution. * notice, this list of conditions and the following disclaimer.
* 3. Neither the name of the copyright holders nor the names of its contributors may be used to * 2. Redistributions in binary form must reproduce the above copyright
* endorse or promote products derived from this software without specific prior written permission. * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.objectweb.asm.tree.analysis; package org.objectweb.asm.tree.analysis;
@@ -79,7 +87,8 @@ class SmallSet<E> extends AbstractSet<E> implements Iterator<E> {
return e; return e;
} }
public void remove() {} public void remove() {
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Utility methods // Utility methods

Some files were not shown because too many files have changed in this diff Show More