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,15 +3,16 @@ 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);
public abstract void printResult(); public abstract void printResult();
public abstract boolean covers(AnalysisResult result); public abstract boolean covers(AnalysisResult result);
public abstract void mergeResult(AnalysisResult r); public abstract void mergeResult(AnalysisResult r);
public abstract AnalysisResult clone(); public abstract AnalysisResult clone();
} }

View File

@@ -1,7 +1,7 @@
package org.bdware.analysis; package org.bdware.analysis;
public interface AnalysisTarget { public interface AnalysisTarget {
public boolean inList(); public boolean inList();
public void setInList(boolean b); public void setInList(boolean b);
} }

View File

@@ -6,44 +6,44 @@ import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
public class BasicBlock { public class BasicBlock {
public List<AbstractInsnNode> list; public List<AbstractInsnNode> list;
public int blockID; public int blockID;
public int lineNum = -1; public int lineNum = -1;
public int insnCount; public int insnCount;
public BasicBlock(int id) { public BasicBlock(int id) {
list = new ArrayList<>(); list = new ArrayList<>();
blockID = id; blockID = id;
} }
public void add(AbstractInsnNode insn) { public void add(AbstractInsnNode insn) {
list.add(insn); list.add(insn);
} }
public int size() { public int size() {
return list.size(); return list.size();
} }
public List<AbstractInsnNode> getInsn() { public List<AbstractInsnNode> getInsn() {
return list; return list;
} }
boolean inList = false; boolean inList = false;
public AbstractInsnNode lastInsn() { public AbstractInsnNode lastInsn() {
return list.get(list.size() - 1); return list.get(list.size() - 1);
} }
public void setLineNum(int line) { public void setLineNum(int line) {
lineNum = line; lineNum = line;
} }
public boolean inList() { public boolean inList() {
return inList; return inList;
} }
public void setInList(boolean b) { public void setInList(boolean b) {
inList = b; inList = b;
} }
} }

View File

@@ -6,53 +6,53 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public abstract class BreadthFirstSearch<R extends AnalysisResult, T extends AnalysisTarget> { public abstract class BreadthFirstSearch<R extends AnalysisResult, T extends AnalysisTarget> {
public Map<T, AnalysisResult> results; public Map<T, AnalysisResult> results;
protected List<T> toAnalysis; protected List<T> toAnalysis;
public abstract R execute(T t); public abstract R execute(T t);
public abstract Collection<T> getSuc(T t); public abstract Collection<T> getSuc(T t);
public BreadthFirstSearch() { public BreadthFirstSearch() {
results = new HashMap<T, AnalysisResult>(); results = new HashMap<T, AnalysisResult>();
} }
public Map<T, AnalysisResult> analysis() { public Map<T, AnalysisResult> analysis() {
results.clear(); results.clear();
T current = null; T 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);
AnalysisResult preResult = results.get(current); AnalysisResult preResult = results.get(current);
AnalysisResult sucResult = execute(current); AnalysisResult sucResult = execute(current);
if (preResult == null || !preResult.covers(sucResult)) { if (preResult == null || !preResult.covers(sucResult)) {
AnalysisResult cloneResult = sucResult.clone(); AnalysisResult cloneResult = sucResult.clone();
if (cloneResult != null) { if (cloneResult != null) {
results.put(current, cloneResult); results.put(current, cloneResult);
} }
Collection<T> sucs = getSuc(current); Collection<T> sucs = getSuc(current);
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);
next.setInList(true); next.setInList(true);
} }
} }
} }
} }
return results; return results;
} }
public int getListLength() { public int getListLength() {
return toAnalysis.size(); return toAnalysis.size();
} }
public void setToAnalysis(List<T> l) { public void setToAnalysis(List<T> l) {
toAnalysis = l; toAnalysis = l;
} }
} }

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,75 +199,77 @@ 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.
* @param desc the field's descriptor (see {@link Type Type}). * @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) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* 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
* @param owner the internal name of the method's owner class (see * INVOKEINTERFACE.
* {@link Type#getInternalName() getInternalName}). * @param owner the internal name of the method's owner class (see
* @param name the method's name. * {@link Type#getInternalName() getInternalName}).
* @param desc the method's descriptor (see {@link Type Type}). * @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) {
currBlock.add(currInsn); currBlock.add(currInsn);
@@ -282,16 +288,16 @@ public abstract class CFGraph {
/** /**
* Visits an invokedynamic instruction. * Visits an invokedynamic instruction.
* *
* @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,45 +349,47 @@ 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) {
* // ... * // ...
* } else if (cst instanceof Float) { * } else if (cst instanceof Float) {
* // ... * // ...
* } else if (cst instanceof Long) { * } else if (cst instanceof Long) {
* // ... * // ...
* } else if (cst instanceof Double) { * } else if (cst instanceof Double) {
* // ... * // ...
* } else if (cst instanceof String) { * } else if (cst instanceof String) {
* // ... * // ...
* } else if (cst instanceof Type) { * } else if (cst instanceof Type) {
* int sort = ((Type) cst).getSort(); * int sort = ((Type) cst).getSort();
* if (sort == Type.OBJECT) { * if (sort == Type.OBJECT) {
* // ... * // ...
* } else if (sort == Type.ARRAY) { * } else if (sort == Type.ARRAY) {
* // ... * // ...
* } else if (sort == Type.METHOD) { * } else if (sort == Type.METHOD) {
* // ... * // ...
* } else { * } else {
* // throw an exception * // throw an exception
* } * }
* } else if (cst instanceof Handle) { * } else if (cst instanceof Handle) {
* // ... * // ...
* } else { * } else {
* // throw an exception * // throw an exception
* } * }
* </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}
* version is 51.0. * for MethodType and MethodHandle constants, for classes whose
* version is 51.0.
*/ */
public void visitLdcInsn(Object cst) { public void visitLdcInsn(Object cst) {
currBlock.add(currInsn); currBlock.add(currInsn);
@@ -387,7 +398,7 @@ public abstract class CFGraph {
/** /**
* Visits an IINC instruction. * Visits an IINC instruction.
* *
* @param var index of the local variable to be incremented. * @param var index of the local variable to be incremented.
* @param increment amount to increment the local variable by. * @param increment amount to increment the local variable by.
*/ */
public void visitIincInsn(int var, int increment) { public void visitIincInsn(int var, int increment) {
@@ -400,11 +411,11 @@ public abstract class CFGraph {
/** /**
* Visits a TABLESWITCH instruction. * Visits a TABLESWITCH instruction.
* *
* @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);
@@ -415,10 +426,10 @@ public abstract class CFGraph {
/** /**
* Visits a LOOKUPSWITCH instruction. * Visits a LOOKUPSWITCH instruction.
* *
* @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);
@@ -439,31 +450,33 @@ public abstract class CFGraph {
/** /**
* Visits a local variable declaration. * Visits a local variable declaration.
* *
* @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
* @param index the local variable's index. * local variable (exclusive).
* @throws IllegalArgumentException if one of the labels has not already been visited by * @param index the local variable's index.
* this visitor (by the {@link #visitLabel visitLabel} method). * @throws IllegalArgumentException if one of the labels has not already been
* 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

@@ -1,10 +1,10 @@
package org.bdware.analysis; package org.bdware.analysis;
public interface CFType { public interface CFType {
public static final int kInstrCanBranch = 1; // conditional or unconditional branch public static final int kInstrCanBranch = 1; // conditional or unconditional branch
public static final int kInstrCanContinue = 1 << 1; // flow can continue to next statement public static final int kInstrCanContinue = 1 << 1; // flow can continue to next statement
public static final int kInstrCanSwitch = 1 << 2; // switch public static final int kInstrCanSwitch = 1 << 2; // switch
public static final int kInstrCanThrow = 1 << 3; // could cause an exception to be thrown public static final int kInstrCanThrow = 1 << 3; // could cause an exception to be thrown
public static final int kInstrCanReturn = 1 << 4; // returns, no additional statements public static final int kInstrCanReturn = 1 << 4; // returns, no additional statements
public static final int kInstrInvoke = 1 << 5; // a flavor of invoke public static final int kInstrInvoke = 1 << 5; // a flavor of invoke
} }

View File

@@ -8,127 +8,131 @@ 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;
public class FrontCF { public class FrontCF {
String methodName; String methodName;
public List<FrontBB> blocks; public List<FrontBB> blocks;
public List<FrontEdge> edges; public List<FrontEdge> edges;
public String ret; public String ret;
public String finalRet; public String finalRet;
transient InsnPrinter printer; transient InsnPrinter printer;
transient ArrayPs ps; transient ArrayPs ps;
static class ArrayPs extends PrintStream { static class ArrayPs extends PrintStream {
List<String> content; List<String> content;
public ArrayPs() throws FileNotFoundException { public ArrayPs() throws FileNotFoundException {
super("/dev/null"); super("/dev/null");
} }
public void println(String str) { public void println(String str) {
if (content != null) if (content != null)
content.add(str); content.add(str);
} }
} }
public FrontCF(CFGraph graph) { public FrontCF(CFGraph graph) {
blocks = new ArrayList<>(); blocks = new ArrayList<>();
edges = new ArrayList<>(); edges = new ArrayList<>();
try { try {
ps = new ArrayPs(); ps = new ArrayPs();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} }
printer = new InsnPrinter(Opcodes.ASM4, ps); printer = new InsnPrinter(Opcodes.ASM4, ps);
printer.setLabelOrder(graph.getLabelOrder()); printer.setLabelOrder(graph.getLabelOrder());
} }
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;
} }
public static class EdgeLabel { public static class EdgeLabel {
String label; String label;
} }
public static class FrontEdge { public static class FrontEdge {
String from, to; String from, to;
EdgeLabel label; EdgeLabel label;
} }
public void addBB(BasicBlock bb, String original, List<Integer> ids, TaintCFG cfg) { public void addBB(BasicBlock bb, String original, List<Integer> ids, TaintCFG cfg) {
FrontBB fb = new FrontBB(); FrontBB fb = new FrontBB();
blocks.add(fb); blocks.add(fb);
fb.name = "B" + bb.blockID; fb.name = "B" + bb.blockID;
List<AbstractInsnNode> insnList = bb.getInsn(); List<AbstractInsnNode> insnList = bb.getInsn();
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());
} }
fb.blockDep = sb.toString(); fb.blockDep = sb.toString();
} }
if (insnList != null && insnList.size() > 0) { if (insnList != null && insnList.size() > 0) {
AbstractInsnNode lastStmt = insnList.get(insnList.size() - 1); AbstractInsnNode lastStmt = insnList.get(insnList.size() - 1);
if (lastStmt.getOpcode() >= 0) { if (lastStmt.getOpcode() >= 0) {
OpInfo info = OpInfo.ops[lastStmt.getOpcode()]; OpInfo info = OpInfo.ops[lastStmt.getOpcode()];
if (info.canBranch() || info.canSwitch()) { if (info.canBranch() || info.canSwitch()) {
fb.type = "Branch"; fb.type = "Branch";
} }
} }
fb.stmts = new ArrayList<String>(); fb.stmts = new ArrayList<String>();
ps.content = fb.stmts; ps.content = fb.stmts;
for (AbstractInsnNode node : insnList) { for (AbstractInsnNode node : insnList) {
node.accept(printer); node.accept(printer);
} }
} }
} }
public void addEdge(BasicBlock bb, BasicBlock suc) { public void addEdge(BasicBlock bb, BasicBlock suc) {
FrontEdge edge = new FrontEdge(); FrontEdge edge = new FrontEdge();
List<AbstractInsnNode> insnList = bb.getInsn(); List<AbstractInsnNode> insnList = bb.getInsn();
edge.label = new EdgeLabel(); edge.label = new EdgeLabel();
edge.label.label = "e"; edge.label.label = "e";
AbstractInsnNode lastStmt = insnList.get(insnList.size() - 1); AbstractInsnNode lastStmt = insnList.get(insnList.size() - 1);
boolean ignore = false; boolean ignore = false;
if (lastStmt.getOpcode() >= 0) { if (lastStmt.getOpcode() >= 0) {
OpInfo info = OpInfo.ops[lastStmt.getOpcode()]; OpInfo info = OpInfo.ops[lastStmt.getOpcode()];
if (info.canBranch() && info.toString().startsWith("if")) { if (info.canBranch() && info.toString().startsWith("if")) {
if (suc.blockID == bb.blockID + 1) if (suc.blockID == bb.blockID + 1)
edge.label.label = "false"; edge.label.label = "false";
else else
edge.label.label = "true"; edge.label.label = "true";
} }
if (info.canThrow() && info.toString().startsWith("invoke")) { if (info.canThrow() && info.toString().startsWith("invoke")) {
if (suc.blockID != bb.blockID + 1) { if (suc.blockID != bb.blockID + 1) {
ignore = true; ignore = true;
} }
} }
} }
edge.from = "B" + bb.blockID; edge.from = "B" + bb.blockID;
edge.to = "B" + suc.blockID; edge.to = "B" + suc.blockID;
if (!ignore) if (!ignore)
edges.add(edge); edges.add(edge);
} }
} }

View File

@@ -10,275 +10,288 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
public class InsnPrinter extends MethodVisitor { public class InsnPrinter extends MethodVisitor {
PrintStream ps; PrintStream ps;
private Map<Label, Integer> labelOrder; private Map<Label, Integer> labelOrder;
public InsnPrinter(int api, PrintStream ps) { public InsnPrinter(int api, PrintStream ps) {
super(api); super(api);
this.ps = ps; this.ps = ps;
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Normal instructions // Normal instructions
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* 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,
public void visitInsn(int opcode) { * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
ps.println(OpInfo.ops[opcode].toString()); * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or
} * MONITOREXIT.
*/
public void visitInsn(int opcode) {
ps.println(OpInfo.ops[opcode].toString());
}
/** /**
* 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) { */
ps.println(OpInfo.ops[opcode].toString() + " " + operand); public void visitIntInsn(int opcode, int 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);
} }
/** /**
* 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) { */
ps.println(OpInfo.ops[opcode].toString() + " " + type); public void visitTypeInsn(int opcode, String type) {
ps.println(OpInfo.ops[opcode].toString() + " " + type);
} }
/** /**
* 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}).
*/ */
public void visitFieldInsn(int opcode, String owner, String name, String desc) { public void visitFieldInsn(int opcode, String owner, String name, String desc) {
ps.println(OpInfo.ops[opcode].toString() + " " + owner + " " + name + " " + desc); ps.println(OpInfo.ops[opcode].toString() + " " + 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 *
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. * @param opcode 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 the internal name of the method's owner class (see
* @param desc the method's descriptor (see {@link Type Type}). * {@link Type#getInternalName() getInternalName}).
*/ * @param name the method's name.
public void visitMethodInsn(int opcode, String owner, String name, String desc) { * @param desc the method's descriptor (see {@link Type Type}).
ps.println(OpInfo.ops[opcode].toString() + " " + owner + " " + name + " " + desc); */
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
ps.println(OpInfo.ops[opcode].toString() + " " + owner + " " + name + " " + desc);
} }
/** /**
* Visits an invokedynamic instruction. * Visits an invokedynamic instruction.
* *
* @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) { */
ps.println(OpInfo.INVOKEDYNAMIC.toString() + " " + name + " " + desc + " HANDLE:" public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
+ bsm.toString() + " " + objs2Str(bsmArgs)); ps.println(OpInfo.INVOKEDYNAMIC.toString() + " " + name + " " + desc + " HANDLE:" + bsm.toString() + " "
+ objs2Str(bsmArgs));
} }
private String objs2Str(Object[] bsmArgs) { private String objs2Str(Object[] bsmArgs) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Object obj : bsmArgs) for (Object obj : bsmArgs)
sb.append(obj.toString()).append(" "); sb.append(obj.toString()).append(" ");
return sb.toString(); return sb.toString();
} }
/** /**
* 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
public void visitJumpInsn(int opcode, Label label) { * instruction may jump.
ps.println(OpInfo.ops[opcode].toString() + getLabelStr(label)); */
public void visitJumpInsn(int opcode, Label label) {
ps.println(OpInfo.ops[opcode].toString() + getLabelStr(label));
} }
/** /**
* 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.
private String getLabelStr(Label label) { */
return "L" + labelOrder.get(label); private String getLabelStr(Label label) {
} return "L" + labelOrder.get(label);
}
public void visitLabel(Label label) { public void visitLabel(Label label) {
ps.println("=" + getLabelStr(label) + "="); ps.println("=" + getLabelStr(label) + "=");
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Special instructions // Special instructions
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* 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> *
* if (cst instanceof Integer) { * <pre>
* // ... * if (cst instanceof Integer) {
* } else if (cst instanceof Float) { * // ...
* // ... * } else if (cst instanceof Float) {
* } else if (cst instanceof Long) { * // ...
* // ... * } else if (cst instanceof Long) {
* } else if (cst instanceof Double) { * // ...
* // ... * } else if (cst instanceof Double) {
* } else if (cst instanceof String) { * // ...
* // ... * } else if (cst instanceof String) {
* } else if (cst instanceof Type) { * // ...
* int sort = ((Type) cst).getSort(); * } else if (cst instanceof Type) {
* if (sort == Type.OBJECT) { * int sort = ((Type) cst).getSort();
* // ... * if (sort == Type.OBJECT) {
* } else if (sort == Type.ARRAY) { * // ...
* // ... * } else if (sort == Type.ARRAY) {
* } else if (sort == Type.METHOD) { * // ...
* // ... * } else if (sort == Type.METHOD) {
* } else { * // ...
* // throw an exception * } else {
* } * // throw an exception
* } else if (cst instanceof Handle) { * }
* // ... * } else if (cst instanceof Handle) {
* } else { * // ...
* // throw an exception * } else {
* } * // throw an exception
* </pre> * }
* * </pre>
* @param cst the constant to be loaded on the stack. This parameter must be a non null *
* {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, * @param cst the constant to be loaded on the stack. This parameter must be a
* a {@link Type} of OBJECT or ARRAY sort for <tt>.class</tt> constants, for classes * 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}
public void visitLdcInsn(Object cst) { * for MethodType and MethodHandle constants, for classes whose
ps.println("ldc " + cst); * version is 51.0.
} */
public void visitLdcInsn(Object cst) {
ps.println("ldc " + cst);
}
/** /**
* Visits an IINC instruction. * Visits an IINC instruction.
* *
* @param var index of the local variable to be incremented. * @param var index of the local variable to be incremented.
* @param increment amount to increment the local variable by. * @param increment amount to increment the local variable by.
*/ */
public void visitIincInsn(int var, int increment) { public void visitIincInsn(int var, int increment) {
ps.println("iinc " + var + " " + increment); ps.println("iinc " + var + " " + increment);
} }
/** /**
* Visits a TABLESWITCH instruction. * Visits a TABLESWITCH instruction.
* *
* @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));
} }
private String convertLabels(Label[] labels) { private String convertLabels(Label[] labels) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Label l : labels) for (Label l : labels)
sb.append(getLabelStr(l)).append(" "); sb.append(getLabelStr(l)).append(" ");
return sb.toString(); return sb.toString();
} }
/** /**
* Visits a LOOKUPSWITCH instruction. * Visits a LOOKUPSWITCH instruction.
* *
* @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));
} }
/** /**
* Visits a MULTIANEWARRAY instruction. * Visits a MULTIANEWARRAY instruction.
* *
* @param desc an array type descriptor (see {@link Type Type}). * @param desc an array type descriptor (see {@link Type Type}).
* @param dims number of dimensions of the array to allocate. * @param dims number of dimensions of the array to allocate.
*/ */
public void visitMultiANewArrayInsn(String desc, int dims) { public void visitMultiANewArrayInsn(String desc, int dims) {
ps.println(OpInfo.MULTIANEWARRAY + " " + desc + " " + dims); ps.println(OpInfo.MULTIANEWARRAY + " " + desc + " " + dims);
} }
public void setLabelOrder(Map<Label, Integer> labelOrder) { public void setLabelOrder(Map<Label, Integer> labelOrder) {
this.labelOrder = labelOrder; this.labelOrder = labelOrder;
} }
} }

View File

@@ -1,257 +1,256 @@
package org.bdware.analysis; package org.bdware.analysis;
public enum OpInfo implements CFType { public enum OpInfo implements CFType {
NOP(0x00, "nop", kInstrCanContinue, 0), // -- NOP(0x00, "nop", kInstrCanContinue, 0), // --
ACONST_NULL(0x01, "aconst_null", kInstrCanContinue, 1), // -- ACONST_NULL(0x01, "aconst_null", kInstrCanContinue, 1), // --
ICONST_M1(0x02, "iconst_m1", kInstrCanContinue, 1), // -- ICONST_M1(0x02, "iconst_m1", kInstrCanContinue, 1), // --
ICONST_0(0x03, "iconst_0", kInstrCanContinue, 1), // -- ICONST_0(0x03, "iconst_0", kInstrCanContinue, 1), // --
ICONST_1(0x04, "iconst_1", kInstrCanContinue, 1), // -- ICONST_1(0x04, "iconst_1", kInstrCanContinue, 1), // --
ICONST_2(0x05, "iconst_2", kInstrCanContinue, 1), // -- ICONST_2(0x05, "iconst_2", kInstrCanContinue, 1), // --
ICONST_3(0x06, "iconst_3", kInstrCanContinue, 1), // -- ICONST_3(0x06, "iconst_3", kInstrCanContinue, 1), // --
ICONST_4(0x07, "iconst_4", kInstrCanContinue, 1), // -- ICONST_4(0x07, "iconst_4", kInstrCanContinue, 1), // --
ICONST_5(0x08, "iconst_5", kInstrCanContinue, 1), // -- ICONST_5(0x08, "iconst_5", kInstrCanContinue, 1), // --
LCONST_0(0x09, "lconst_0", kInstrCanContinue, 2), // -- LCONST_0(0x09, "lconst_0", kInstrCanContinue, 2), // --
LCONST_1(0x0a, "lconst_1", kInstrCanContinue, 2), // -- LCONST_1(0x0a, "lconst_1", kInstrCanContinue, 2), // --
FCONST_0(0x0b, "fconst_0", kInstrCanContinue, 1), // -- FCONST_0(0x0b, "fconst_0", kInstrCanContinue, 1), // --
FCONST_1(0x0c, "fconst_1", kInstrCanContinue, 1), // -- FCONST_1(0x0c, "fconst_1", kInstrCanContinue, 1), // --
FCONST_2(0x0d, "fconst_2", kInstrCanContinue, 1), // -- FCONST_2(0x0d, "fconst_2", kInstrCanContinue, 1), // --
DCONST_0(0x0e, "dconst_0", kInstrCanContinue, 2), // -- DCONST_0(0x0e, "dconst_0", kInstrCanContinue, 2), // --
DCONST_1(0x0f, "dconst_1", kInstrCanContinue, 2), // -- DCONST_1(0x0f, "dconst_1", kInstrCanContinue, 2), // --
BIPUSH(0x10, "bipush", kInstrCanContinue, 1), // -- BIPUSH(0x10, "bipush", kInstrCanContinue, 1), // --
SIPUSH(0x11, "sipush", kInstrCanContinue, 1), // -- SIPUSH(0x11, "sipush", kInstrCanContinue, 1), // --
LDC(0x12, "ldc", kInstrCanContinue, 1), // -- LDC(0x12, "ldc", kInstrCanContinue, 1), // --
LDC_W(0x13, "ldc_w", kInstrCanContinue, 1), // -- LDC_W(0x13, "ldc_w", kInstrCanContinue, 1), // --
LDC2_W(0x14, "ldc2_w", kInstrCanContinue, 2), // -- LDC2_W(0x14, "ldc2_w", kInstrCanContinue, 2), // --
ILOAD(0x15, "iload", kInstrCanContinue, 1), // -- ILOAD(0x15, "iload", kInstrCanContinue, 1), // --
LLOAD(0x16, "lload", kInstrCanContinue, 2), // -- LLOAD(0x16, "lload", kInstrCanContinue, 2), // --
FLOAD(0x17, "fload", kInstrCanContinue, 1), // -- FLOAD(0x17, "fload", kInstrCanContinue, 1), // --
DLOAD(0x18, "dload", kInstrCanContinue, 2), // -- DLOAD(0x18, "dload", kInstrCanContinue, 2), // --
ALOAD(0x19, "aload", kInstrCanContinue, 1), // -- ALOAD(0x19, "aload", kInstrCanContinue, 1), // --
ILOAD_0(0x1a, "iload_0", kInstrCanContinue, 1), // -- ILOAD_0(0x1a, "iload_0", kInstrCanContinue, 1), // --
ILOAD_1(0x1b, "iload_1", kInstrCanContinue, 1), // -- ILOAD_1(0x1b, "iload_1", kInstrCanContinue, 1), // --
ILOAD_2(0x1c, "iload_2", kInstrCanContinue, 1), // -- ILOAD_2(0x1c, "iload_2", kInstrCanContinue, 1), // --
ILOAD_3(0x1d, "iload_3", kInstrCanContinue, 1), // -- ILOAD_3(0x1d, "iload_3", kInstrCanContinue, 1), // --
LLOAD_0(0x1e, "lload_0", kInstrCanContinue, 2), // -- LLOAD_0(0x1e, "lload_0", kInstrCanContinue, 2), // --
LLOAD_1(0x1f, "lload_1", kInstrCanContinue, 2), // -- LLOAD_1(0x1f, "lload_1", kInstrCanContinue, 2), // --
LLOAD_2(0x20, "lload_2", kInstrCanContinue, 2), // -- LLOAD_2(0x20, "lload_2", kInstrCanContinue, 2), // --
LLOAD_3(0x21, "lload_3", kInstrCanContinue, 2), // -- LLOAD_3(0x21, "lload_3", kInstrCanContinue, 2), // --
FLOAD_0(0x22, "fload_0", kInstrCanContinue, 1), // -- FLOAD_0(0x22, "fload_0", kInstrCanContinue, 1), // --
FLOAD_1(0x23, "fload_1", kInstrCanContinue, 1), // -- FLOAD_1(0x23, "fload_1", kInstrCanContinue, 1), // --
FLOAD_2(0x24, "fload_2", kInstrCanContinue, 1), // -- FLOAD_2(0x24, "fload_2", kInstrCanContinue, 1), // --
FLOAD_3(0x25, "fload_3", kInstrCanContinue, 1), // -- FLOAD_3(0x25, "fload_3", kInstrCanContinue, 1), // --
DLOAD_0(0x26, "dload_0", kInstrCanContinue, 2), // -- DLOAD_0(0x26, "dload_0", kInstrCanContinue, 2), // --
DLOAD_1(0x27, "dload_1", kInstrCanContinue, 2), // -- DLOAD_1(0x27, "dload_1", kInstrCanContinue, 2), // --
DLOAD_2(0x28, "dload_2", kInstrCanContinue, 2), // -- DLOAD_2(0x28, "dload_2", kInstrCanContinue, 2), // --
DLOAD_3(0x29, "dload_3", kInstrCanContinue, 2), // -- DLOAD_3(0x29, "dload_3", kInstrCanContinue, 2), // --
ALOAD_0(0x2a, "aload_0", kInstrCanContinue, 1), // -- ALOAD_0(0x2a, "aload_0", kInstrCanContinue, 1), // --
ALOAD_1(0x2b, "aload_1", kInstrCanContinue, 1), // -- ALOAD_1(0x2b, "aload_1", kInstrCanContinue, 1), // --
ALOAD_2(0x2c, "aload_2", kInstrCanContinue, 1), // -- ALOAD_2(0x2c, "aload_2", kInstrCanContinue, 1), // --
ALOAD_3(0x2d, "aload_3", kInstrCanContinue, 1), // -- ALOAD_3(0x2d, "aload_3", kInstrCanContinue, 1), // --
IALOAD(0x2e, "iaload", kInstrCanContinue, -1), // -- IALOAD(0x2e, "iaload", kInstrCanContinue, -1), // --
LALOAD(0x2f, "laload", kInstrCanContinue, 0), // -- LALOAD(0x2f, "laload", kInstrCanContinue, 0), // --
FALOAD(0x30, "faload", kInstrCanContinue, -1), // -- FALOAD(0x30, "faload", kInstrCanContinue, -1), // --
DALOAD(0x31, "daload", kInstrCanContinue, 0), // -- DALOAD(0x31, "daload", kInstrCanContinue, 0), // --
AALOAD(0x32, "aaload", kInstrCanContinue, -1), // -- AALOAD(0x32, "aaload", kInstrCanContinue, -1), // --
BALOAD(0x33, "baload", kInstrCanContinue, -1), // -- BALOAD(0x33, "baload", kInstrCanContinue, -1), // --
CALOAD(0x34, "caload", kInstrCanContinue, -1), // -- CALOAD(0x34, "caload", kInstrCanContinue, -1), // --
SALOAD(0x35, "saload", kInstrCanContinue, -1), // -- SALOAD(0x35, "saload", kInstrCanContinue, -1), // --
ISTORE(0x36, "istore", kInstrCanContinue, -1), // -- ISTORE(0x36, "istore", kInstrCanContinue, -1), // --
LSTORE(0x37, "lstore", kInstrCanContinue, -2), // -- LSTORE(0x37, "lstore", kInstrCanContinue, -2), // --
FSTORE(0x38, "fstore", kInstrCanContinue, -1), // -- FSTORE(0x38, "fstore", kInstrCanContinue, -1), // --
DSTORE(0x39, "dstore", kInstrCanContinue, -2), // -- DSTORE(0x39, "dstore", kInstrCanContinue, -2), // --
ASTORE(0x3a, "astore", kInstrCanContinue, -1), // -- ASTORE(0x3a, "astore", kInstrCanContinue, -1), // --
ISTORE_0(0x3b, "istore_0", kInstrCanContinue, -1), // -- ISTORE_0(0x3b, "istore_0", kInstrCanContinue, -1), // --
ISTORE_1(0x3c, "istore_1", kInstrCanContinue, -1), // -- ISTORE_1(0x3c, "istore_1", kInstrCanContinue, -1), // --
ISTORE_2(0x3d, "istore_2", kInstrCanContinue, -1), // -- ISTORE_2(0x3d, "istore_2", kInstrCanContinue, -1), // --
ISTORE_3(0x3e, "istore_3", kInstrCanContinue, -1), // -- ISTORE_3(0x3e, "istore_3", kInstrCanContinue, -1), // --
LSTORE_0(0x3f, "lstore_0", kInstrCanContinue, -2), // -- LSTORE_0(0x3f, "lstore_0", kInstrCanContinue, -2), // --
LSTORE_1(0x40, "lstore_1", kInstrCanContinue, -2), // -- LSTORE_1(0x40, "lstore_1", kInstrCanContinue, -2), // --
LSTORE_2(0x41, "lstore_2", kInstrCanContinue, -2), // -- LSTORE_2(0x41, "lstore_2", kInstrCanContinue, -2), // --
LSTORE_3(0x42, "lstore_3", kInstrCanContinue, -2), // -- LSTORE_3(0x42, "lstore_3", kInstrCanContinue, -2), // --
FSTORE_0(0x43, "fstore_0", kInstrCanContinue, -1), // -- FSTORE_0(0x43, "fstore_0", kInstrCanContinue, -1), // --
FSTORE_1(0x44, "fstore_1", kInstrCanContinue, -1), // -- FSTORE_1(0x44, "fstore_1", kInstrCanContinue, -1), // --
FSTORE_2(0x45, "fstore_2", kInstrCanContinue, -1), // -- FSTORE_2(0x45, "fstore_2", kInstrCanContinue, -1), // --
FSTORE_3(0x46, "fstore_3", kInstrCanContinue, -1), // -- FSTORE_3(0x46, "fstore_3", kInstrCanContinue, -1), // --
DSTORE_0(0x47, "dstore_0", kInstrCanContinue, -2), // -- DSTORE_0(0x47, "dstore_0", kInstrCanContinue, -2), // --
DSTORE_1(0x48, "dstore_1", kInstrCanContinue, -2), // -- DSTORE_1(0x48, "dstore_1", kInstrCanContinue, -2), // --
DSTORE_2(0x49, "dstore_2", kInstrCanContinue, -2), // -- DSTORE_2(0x49, "dstore_2", kInstrCanContinue, -2), // --
DSTORE_3(0x4a, "dstore_3", kInstrCanContinue, -2), // -- DSTORE_3(0x4a, "dstore_3", kInstrCanContinue, -2), // --
ASTORE_0(0x4b, "astore_0", kInstrCanContinue, -1), // -- ASTORE_0(0x4b, "astore_0", kInstrCanContinue, -1), // --
ASTORE_1(0x4c, "astore_1", kInstrCanContinue, -1), // -- ASTORE_1(0x4c, "astore_1", kInstrCanContinue, -1), // --
ASTORE_2(0x4d, "astore_2", kInstrCanContinue, -1), // -- ASTORE_2(0x4d, "astore_2", kInstrCanContinue, -1), // --
ASTORE_3(0x4e, "astore_3", kInstrCanContinue, -1), // -- ASTORE_3(0x4e, "astore_3", kInstrCanContinue, -1), // --
IASTORE(0x4f, "iastore", kInstrCanContinue, -3), // -- IASTORE(0x4f, "iastore", kInstrCanContinue, -3), // --
LASTORE(0x50, "lastore", kInstrCanContinue, -4), // -- LASTORE(0x50, "lastore", kInstrCanContinue, -4), // --
FASTORE(0x51, "fastore", kInstrCanContinue, -3), // -- FASTORE(0x51, "fastore", kInstrCanContinue, -3), // --
DASTORE(0x52, "dastore", kInstrCanContinue, -4), // -- DASTORE(0x52, "dastore", kInstrCanContinue, -4), // --
AASTORE(0x53, "aastore", kInstrCanContinue, -3), // -- AASTORE(0x53, "aastore", kInstrCanContinue, -3), // --
BASTORE(0x54, "bastore", kInstrCanContinue, -3), // -- BASTORE(0x54, "bastore", kInstrCanContinue, -3), // --
CASTORE(0x55, "castore", kInstrCanContinue, -3), // -- CASTORE(0x55, "castore", kInstrCanContinue, -3), // --
SASTORE(0x56, "sastore", kInstrCanContinue, -3), // -- SASTORE(0x56, "sastore", kInstrCanContinue, -3), // --
POP(0x57, "pop", kInstrCanContinue, -1), // -- POP(0x57, "pop", kInstrCanContinue, -1), // --
POP2(0x58, "pop2", kInstrCanContinue, -2), // -- POP2(0x58, "pop2", kInstrCanContinue, -2), // --
DUP(0x59, "dup", kInstrCanContinue, 1), // -- DUP(0x59, "dup", kInstrCanContinue, 1), // --
DUP_X1(0x5a, "dup_x1", kInstrCanContinue, 1), // -- DUP_X1(0x5a, "dup_x1", kInstrCanContinue, 1), // --
DUP_X2(0x5b, "dup_x2", kInstrCanContinue, 1), // -- DUP_X2(0x5b, "dup_x2", kInstrCanContinue, 1), // --
DUP2(0x5c, "dup2", kInstrCanContinue, 2), // -- DUP2(0x5c, "dup2", kInstrCanContinue, 2), // --
DUP2_X1(0x5d, "dup2_x1", kInstrCanContinue, 2), // -- DUP2_X1(0x5d, "dup2_x1", kInstrCanContinue, 2), // --
DUP2_X2(0x5e, "dup2_x2", kInstrCanContinue, 2), // -- DUP2_X2(0x5e, "dup2_x2", kInstrCanContinue, 2), // --
SWAP(0x5f, "swap", kInstrCanContinue, 0), // -- SWAP(0x5f, "swap", kInstrCanContinue, 0), // --
IADD(0x60, "iadd", kInstrCanContinue, -1), // -- IADD(0x60, "iadd", kInstrCanContinue, -1), // --
LADD(0x61, "ladd", kInstrCanContinue, -2), // -- LADD(0x61, "ladd", kInstrCanContinue, -2), // --
FADD(0x62, "fadd", kInstrCanContinue, -1), // -- FADD(0x62, "fadd", kInstrCanContinue, -1), // --
DADD(0x63, "dadd", kInstrCanContinue, -2), // -- DADD(0x63, "dadd", kInstrCanContinue, -2), // --
ISUB(0x64, "isub", kInstrCanContinue, -1), // -- ISUB(0x64, "isub", kInstrCanContinue, -1), // --
LSUB(0x65, "lsub", kInstrCanContinue, -2), // -- LSUB(0x65, "lsub", kInstrCanContinue, -2), // --
FSUB(0x66, "fsub", kInstrCanContinue, -1), // -- FSUB(0x66, "fsub", kInstrCanContinue, -1), // --
DSUB(0x67, "dsub", kInstrCanContinue, -2), // -- DSUB(0x67, "dsub", kInstrCanContinue, -2), // --
IMUL(0x68, "imul", kInstrCanContinue, -1), // -- IMUL(0x68, "imul", kInstrCanContinue, -1), // --
LMUL(0x69, "lmul", kInstrCanContinue, -2), // -- LMUL(0x69, "lmul", kInstrCanContinue, -2), // --
FMUL(0x6a, "fmul", kInstrCanContinue, -1), // -- FMUL(0x6a, "fmul", kInstrCanContinue, -1), // --
DMUL(0x6b, "dmul", kInstrCanContinue, -2), // -- DMUL(0x6b, "dmul", kInstrCanContinue, -2), // --
IDIV(0x6c, "idiv", kInstrCanContinue, -1), // -- IDIV(0x6c, "idiv", kInstrCanContinue, -1), // --
LDIV(0x6d, "ldiv", kInstrCanContinue, -2), // -- LDIV(0x6d, "ldiv", kInstrCanContinue, -2), // --
FDIV(0x6e, "fdiv", kInstrCanContinue, -1), // -- FDIV(0x6e, "fdiv", kInstrCanContinue, -1), // --
DDIV(0x6f, "ddiv", kInstrCanContinue, -2), // -- DDIV(0x6f, "ddiv", kInstrCanContinue, -2), // --
IREM(0x70, "irem", kInstrCanContinue, -1), // -- IREM(0x70, "irem", kInstrCanContinue, -1), // --
LREM(0x71, "lrem", kInstrCanContinue, -2), // -- LREM(0x71, "lrem", kInstrCanContinue, -2), // --
FREM(0x72, "frem", kInstrCanContinue, -1), // -- FREM(0x72, "frem", kInstrCanContinue, -1), // --
DREM(0x73, "drem", kInstrCanContinue, -2), // -- DREM(0x73, "drem", kInstrCanContinue, -2), // --
INEG(0x74, "ineg", kInstrCanContinue, 0), // -- INEG(0x74, "ineg", kInstrCanContinue, 0), // --
LNEG(0x75, "lneg", kInstrCanContinue, 0), // -- LNEG(0x75, "lneg", kInstrCanContinue, 0), // --
FNEG(0x76, "fneg", kInstrCanContinue, 0), // -- FNEG(0x76, "fneg", kInstrCanContinue, 0), // --
DNEG(0x77, "dneg", kInstrCanContinue, 0), // -- DNEG(0x77, "dneg", kInstrCanContinue, 0), // --
ISHL(0x78, "ishl", kInstrCanContinue, -1), // -- ISHL(0x78, "ishl", kInstrCanContinue, -1), // --
LSHL(0x79, "lshl", kInstrCanContinue, -1), // -- LSHL(0x79, "lshl", kInstrCanContinue, -1), // --
ISHR(0x7a, "ishr", kInstrCanContinue, -1), // -- ISHR(0x7a, "ishr", kInstrCanContinue, -1), // --
LSHR(0x7b, "lshr", kInstrCanContinue, -1), // -- LSHR(0x7b, "lshr", kInstrCanContinue, -1), // --
IUSHR(0x7c, "iushr", kInstrCanContinue, -1), // -- IUSHR(0x7c, "iushr", kInstrCanContinue, -1), // --
LUSHR(0x7d, "lushr", kInstrCanContinue, -1), // -- LUSHR(0x7d, "lushr", kInstrCanContinue, -1), // --
IAND(0x7e, "iand", kInstrCanContinue, -1), // -- IAND(0x7e, "iand", kInstrCanContinue, -1), // --
LAND(0x7f, "land", kInstrCanContinue, -2), // -- LAND(0x7f, "land", kInstrCanContinue, -2), // --
IOR(0x80, "ior", kInstrCanContinue, -1), // -- IOR(0x80, "ior", kInstrCanContinue, -1), // --
LOR(0x81, "lor", kInstrCanContinue, -2), // -- LOR(0x81, "lor", kInstrCanContinue, -2), // --
IXOR(0x82, "ixor", kInstrCanContinue, -1), // -- IXOR(0x82, "ixor", kInstrCanContinue, -1), // --
LXOR(0x83, "lxor", kInstrCanContinue, -2), // -- LXOR(0x83, "lxor", kInstrCanContinue, -2), // --
IINC(0x84, "iinc", kInstrCanContinue, 0), // -- IINC(0x84, "iinc", kInstrCanContinue, 0), // --
I2L(0x85, "i2l", kInstrCanContinue, 1), // -- I2L(0x85, "i2l", kInstrCanContinue, 1), // --
I2F(0x86, "i2f", kInstrCanContinue, 0), // -- I2F(0x86, "i2f", kInstrCanContinue, 0), // --
I2D(0x87, "i2d", kInstrCanContinue, 1), // -- I2D(0x87, "i2d", kInstrCanContinue, 1), // --
L2I(0x88, "l2i", kInstrCanContinue, -1), // -- L2I(0x88, "l2i", kInstrCanContinue, -1), // --
L2F(0x89, "l2f", kInstrCanContinue, -1), // -- L2F(0x89, "l2f", kInstrCanContinue, -1), // --
L2D(0x8a, "l2d", kInstrCanContinue, 0), // -- L2D(0x8a, "l2d", kInstrCanContinue, 0), // --
F2I(0x8b, "f2i", kInstrCanContinue, 0), // -- F2I(0x8b, "f2i", kInstrCanContinue, 0), // --
F2L(0x8c, "f2l", kInstrCanContinue, 1), // -- F2L(0x8c, "f2l", kInstrCanContinue, 1), // --
F2D(0x8d, "f2d", kInstrCanContinue, 1), // -- F2D(0x8d, "f2d", kInstrCanContinue, 1), // --
D2I(0x8e, "d2i", kInstrCanContinue, -1), // -- D2I(0x8e, "d2i", kInstrCanContinue, -1), // --
D2L(0x8f, "d2l", kInstrCanContinue, 0), // -- D2L(0x8f, "d2l", kInstrCanContinue, 0), // --
D2F(0x90, "d2f", kInstrCanContinue, -1), // -- D2F(0x90, "d2f", kInstrCanContinue, -1), // --
I2B(0x91, "i2b", kInstrCanContinue, 0), // -- I2B(0x91, "i2b", kInstrCanContinue, 0), // --
I2C(0x92, "i2c", kInstrCanContinue, 0), // -- I2C(0x92, "i2c", kInstrCanContinue, 0), // --
I2S(0x93, "i2s", kInstrCanContinue, 0), // -- I2S(0x93, "i2s", kInstrCanContinue, 0), // --
LCMP(0x94, "lcmp", kInstrCanContinue, -2), // -- LCMP(0x94, "lcmp", kInstrCanContinue, -2), // --
FCMPL(0x95, "fcmpl", kInstrCanContinue, -1), // -- FCMPL(0x95, "fcmpl", kInstrCanContinue, -1), // --
FCMPG(0x96, "fcmpg", kInstrCanContinue, -1), // -- FCMPG(0x96, "fcmpg", kInstrCanContinue, -1), // --
DCMPL(0x97, "dcmpl", kInstrCanContinue, -3), // -- DCMPL(0x97, "dcmpl", kInstrCanContinue, -3), // --
DCMPG(0x98, "dcmpg", kInstrCanContinue, -3), // -- DCMPG(0x98, "dcmpg", kInstrCanContinue, -3), // --
IFEQ(0x99, "ifeq", kInstrCanBranch, -1), // -- IFEQ(0x99, "ifeq", kInstrCanBranch, -1), // --
IFNE(0x9a, "ifne", kInstrCanBranch, -1), // -- IFNE(0x9a, "ifne", kInstrCanBranch, -1), // --
IFLT(0x9b, "iflt", kInstrCanBranch, -1), // -- IFLT(0x9b, "iflt", kInstrCanBranch, -1), // --
IFGE(0x9c, "ifge", kInstrCanBranch, -1), // -- IFGE(0x9c, "ifge", kInstrCanBranch, -1), // --
IFGT(0x9d, "ifgt", kInstrCanBranch, -1), // -- IFGT(0x9d, "ifgt", kInstrCanBranch, -1), // --
IFLE(0x9e, "ifle", kInstrCanBranch, -1), // -- IFLE(0x9e, "ifle", kInstrCanBranch, -1), // --
IF_ICMPEQ(0x9f, "if_icmpeq", kInstrCanBranch, -2), // -- IF_ICMPEQ(0x9f, "if_icmpeq", kInstrCanBranch, -2), // --
IF_ICMPNE(0xa0, "if_icmpne", kInstrCanBranch, -2), // -- IF_ICMPNE(0xa0, "if_icmpne", kInstrCanBranch, -2), // --
IF_ICMPLT(0xa1, "if_icmplt", kInstrCanBranch, -2), // -- IF_ICMPLT(0xa1, "if_icmplt", kInstrCanBranch, -2), // --
IF_ICMPGE(0xa2, "if_icmpge", kInstrCanBranch, -2), // -- IF_ICMPGE(0xa2, "if_icmpge", kInstrCanBranch, -2), // --
IF_ICMPGT(0xa3, "if_icmpgt", kInstrCanBranch, -2), // -- IF_ICMPGT(0xa3, "if_icmpgt", kInstrCanBranch, -2), // --
IF_ICMPLE(0xa4, "if_icmple", kInstrCanBranch, -2), // -- IF_ICMPLE(0xa4, "if_icmple", kInstrCanBranch, -2), // --
IF_ACMPEQ(0xa5, "if_acmpeq", kInstrCanBranch, -2), // -- IF_ACMPEQ(0xa5, "if_acmpeq", kInstrCanBranch, -2), // --
IF_ACMPNE(0xa6, "if_acmpne", kInstrCanBranch, -2), // -- IF_ACMPNE(0xa6, "if_acmpne", kInstrCanBranch, -2), // --
GOTO(0xa7, "goto", kInstrCanBranch, 0), // -- GOTO(0xa7, "goto", kInstrCanBranch, 0), // --
JSR(0xa8, "jsr", kInstrCanContinue, 1), // ??-- JSR(0xa8, "jsr", kInstrCanContinue, 1), // ??--
RET(0xa9, "ret", kInstrCanContinue, -1), // ??-- RET(0xa9, "ret", kInstrCanContinue, -1), // ??--
TABLESWITCH(0xaa, "tableswitch", kInstrCanBranch, 1), // -- TABLESWITCH(0xaa, "tableswitch", kInstrCanBranch, 1), // --
LOOKUPSWITCH(0xab, "lookupswitch", kInstrCanBranch, 0), // -- LOOKUPSWITCH(0xab, "lookupswitch", kInstrCanBranch, 0), // --
IRETURN(0xac, "ireturn", kInstrCanReturn, -1), // -- IRETURN(0xac, "ireturn", kInstrCanReturn, -1), // --
LRETURN(0xad, "lreturn", kInstrCanReturn, -2), // -- LRETURN(0xad, "lreturn", kInstrCanReturn, -2), // --
FRETURN(0xae, "freturn", kInstrCanReturn, -1), // -- FRETURN(0xae, "freturn", kInstrCanReturn, -1), // --
DRETURN(0xaf, "dreturn", kInstrCanReturn, -2), // -- DRETURN(0xaf, "dreturn", kInstrCanReturn, -2), // --
ARETURN(0xb0, "areturn", kInstrCanReturn, -1), // -- ARETURN(0xb0, "areturn", kInstrCanReturn, -1), // --
RETURN(0xb1, "return", kInstrCanReturn, 0), // -- RETURN(0xb1, "return", kInstrCanReturn, 0), // --
GETSTATIC(0xb2, "getstatic", kInstrCanContinue, 0), // dynamic changing+ -- GETSTATIC(0xb2, "getstatic", kInstrCanContinue, 0), // dynamic changing+ --
PUTSTATIC(0xb3, "putstatic", kInstrCanContinue, 0), // dynamic changing- -- PUTSTATIC(0xb3, "putstatic", kInstrCanContinue, 0), // dynamic changing- --
GETFIELD(0xb4, "getfield", kInstrCanContinue, 0), // dynamic changing_+ -- GETFIELD(0xb4, "getfield", kInstrCanContinue, 0), // dynamic changing_+ --
PUTFIELD(0xb5, "putfield", kInstrCanContinue, 0), // dynamic changing-- -- PUTFIELD(0xb5, "putfield", kInstrCanContinue, 0), // dynamic changing-- --
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), // -- ANEWARRAY(0xbd, "anewarray", kInstrCanContinue, 0), // --
ANEWARRAY(0xbd, "anewarray", kInstrCanContinue, 0), // -- ARRAYLENGTH(0xbe, "arraylength", kInstrCanContinue, 0), // --
ARRAYLENGTH(0xbe, "arraylength", kInstrCanContinue, 0), // -- ATHROW(0xbf, "athrow", kInstrCanReturn, 0), // --
ATHROW(0xbf, "athrow", kInstrCanReturn, 0), // -- CHECKCAST(0xc0, "checkcast", kInstrCanContinue, 0), // --
CHECKCAST(0xc0, "checkcast", kInstrCanContinue, 0), // -- INSTANCEOF(0xc1, "instanceof", kInstrCanContinue, 0), // --
INSTANCEOF(0xc1, "instanceof", kInstrCanContinue, 0), // -- MONITORENTER(0xc2, "monitorenter", kInstrCanContinue, -1), // --
MONITORENTER(0xc2, "monitorenter", kInstrCanContinue, -1), // -- MONITOREXIT(0xc3, "monitorexit", kInstrCanContinue, -1), // --
MONITOREXIT(0xc3, "monitorexit", kInstrCanContinue, -1), // -- WIDE(0xc4, "wide", kInstrCanContinue, 0), // --
WIDE(0xc4, "wide", kInstrCanContinue, 0), // -- MULTIANEWARRAY(0xc5, "multianewarray", kInstrCanContinue, 0), // dynamic changing--
MULTIANEWARRAY(0xc5, "multianewarray", kInstrCanContinue, 0), // dynamic changing-- IFNULL(0xc6, "ifnull", kInstrCanBranch, -1), // --
IFNULL(0xc6, "ifnull", kInstrCanBranch, -1), // -- 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 {
OpInfo[] ops = OpInfo.ops;
for (OpInfo op : OpInfo.values()) {
if (op.opcode >= 0) {
ops[op.opcode] = op;
}
}
}
public boolean changeFrame;
int changeStack;
private int flags;
private String displayName;
private int opcode;
static { OpInfo() {
OpInfo[] ops = OpInfo.ops; }
for (OpInfo op : OpInfo.values()) {
if (op.opcode >= 0) {
ops[op.opcode] = op;
}
}
}
public boolean changeFrame;
int changeStack;
private int flags;
private String displayName;
private int opcode;
OpInfo() {} OpInfo(int opcode, String displayName, int branchType, int changStack) {
flags = branchType;
this.displayName = displayName;
this.opcode = opcode;
this.changeStack = changeStack;
}
OpInfo(int opcode, String displayName, int branchType, int changStack) { public boolean canBranch() {
flags = branchType; return 0 != (flags & kInstrCanBranch);
this.displayName = displayName; }
this.opcode = opcode;
this.changeStack = changeStack;
}
public boolean canBranch() { public boolean canContinue() {
return 0 != (flags & kInstrCanBranch); return 0 != (flags & kInstrCanContinue);
} }
public boolean canContinue() { public boolean canReturn() {
return 0 != (flags & kInstrCanContinue); return 0 != (flags & kInstrCanReturn);
} }
public boolean canReturn() { public boolean canSwitch() {
return 0 != (flags & kInstrCanReturn); return 0 != (flags & kInstrCanSwitch);
} }
public boolean canSwitch() { public boolean canThrow() {
return 0 != (flags & kInstrCanSwitch); return 0 != (flags & kInstrCanThrow);
} }
public boolean canThrow() {
return 0 != (flags & kInstrCanThrow);
}
public String toString() { public String toString() {
return displayName; return displayName;
} }
} }

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,8 +47,11 @@ 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(
+ cfg.getMethodNode().maxStack); "===Local:"
+ cfg.getMethodNode().maxLocals
+ " "
+ 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

@@ -33,23 +33,23 @@ public class ProgramPoint {
System.out.println("[stringsss: ]" + strings[0]); System.out.println("[stringsss: ]" + strings[0]);
funcTx.insert(strings[0], "ENTER"); funcTx.insert(strings[0], "ENTER");
} }
// if (string.contains("EXIT")) { // if (string.contains("EXIT")) {
// String[] strings = string.split("_"); // String[] strings = string.split("_");
// strings=strings[1].split("-"); // strings=strings[1].split("-");
// System.out.println("[stringsss: ]" + strings[0]); // System.out.println("[stringsss: ]" + strings[0]);
// functionMap.put(strings[1], "EXIT"); // functionMap.put(strings[1], "EXIT");
// } // }
if (string.contains("traceMark")) { if (string.contains("traceMark")) {
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,8 +37,11 @@ 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(
+ cfg.getMethodNode().maxStack); "===Local:"
+ cfg.getMethodNode().maxLocals
+ " "
+ cfg.getMethodNode().maxStack);
} }
} }
@@ -54,12 +57,18 @@ 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(
+ ntbb.preResult.frame2Str()); "[MultiSoruceTaintAnalysis] B"
+ ntbb.blockID
+ " beforeMerge:"
+ 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(
+ ntbb.preResult.frame2Str()); "[MultiSoruceTaintAnalysis] B"
+ ntbb.blockID
+ " afterMerge:"
+ 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,8 +129,10 @@ 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();
*/
} }
// add dependence to the last block // add dependence to the last block
@@ -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,10 +149,14 @@ 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,8 +33,11 @@ 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(
+ cfg.getMethodNode().maxStack); "===Local:"
+ cfg.getMethodNode().maxLocals
+ " "
+ cfg.getMethodNode().maxStack);
} }
} }

View File

@@ -6,29 +6,26 @@ import java.util.List;
import org.bdware.analysis.BasicBlock; 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() {
BasicBlock current = null;
public void analysis() { for (int i = 0; i < toAnalysis.size(); i++) {
BasicBlock current = null; current = toAnalysis.get(i);
for (int i = 0; i < toAnalysis.size(); i++) { //current.setInList(false);
current = toAnalysis.get(i); if(current.inList()) {
// current.setInList(false); Collection<BasicBlock> sucs = getSuc(current);
if (current.inList()) { for (BasicBlock next : sucs) {
Collection<BasicBlock> sucs = getSuc(current); if (!next.inList()) {
for (BasicBlock next : sucs) { toAnalysis.add(next);
if (!next.inList()) { next.setInList(true);
toAnalysis.add(next); }
next.setInList(true); }
} }
} }
} }
} public void setToAnalysis(List<BasicBlock> l) {
} toAnalysis = l;
}
public void setToAnalysis(List<BasicBlock> l) {
toAnalysis = l;
}
} }

View File

@@ -12,215 +12,215 @@ import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.JumpInsnNode;
public class CountProgramPoint { public class CountProgramPoint {
public static HashMap<Integer, Map<String, Integer>> ppcount; public static HashMap<Integer, Map<String, Integer>> ppcount;
CFGraph actionCfg; CFGraph actionCfg;
private String bdName; private String bdName;
HashMap<String, CFGraph> cfgraphMap; HashMap<String, CFGraph> cfgraphMap;
String actionName; String actionName;
int globalPC; int globalPC;
public CountProgramPoint(HashMap<String, CFGraph> cfgMap, int startPc, int endPc, String aName, public CountProgramPoint(HashMap<String, CFGraph> cfgMap, int startPc, int endPc, String aName,
HashMap<Integer, Map<String, Integer>> ppc) { HashMap<Integer, Map<String, Integer>> ppc) {
ppcount = ppc; ppcount = ppc;
cfgraphMap = cfgMap; cfgraphMap = cfgMap;
actionName = aName; actionName = aName;
typeCount(startPc, endPc); typeCount(startPc, endPc);
} }
private HashMap<Integer, Map<String, Integer>> callCount(AbstractInsnNode insn) { private HashMap<Integer, Map<String, Integer>> callCount(AbstractInsnNode insn) {
if (insn instanceof InvokeDynamicInsnNode) { if (insn instanceof InvokeDynamicInsnNode) {
invoke = ((InvokeDynamicInsnNode) insn).bsmArgs[0]; invoke = ((InvokeDynamicInsnNode) insn).bsmArgs[0];
String functionName = ((InvokeDynamicInsnNode) insn).name; String functionName = ((InvokeDynamicInsnNode) insn).name;
dynCount(functionName); dynCount(functionName);
} else { } else {
normalCount(insn); normalCount(insn);
} }
return ppcount; return ppcount;
} }
Object invoke = 0; Object invoke = 0;
public HashMap<Integer, Map<String, Integer>> typeCount(int startPc, int endPc) { public HashMap<Integer, Map<String, Integer>> typeCount(int startPc, int endPc) {
if (startPc == 0) { if (startPc == 0) {
ppcount.put(startPc, new HashMap<>()); ppcount.put(startPc, new HashMap<>());
globalPC = startPc; globalPC = startPc;
} else { } else {
ppcount.put(endPc, new HashMap<>()); ppcount.put(endPc, new HashMap<>());
globalPC = endPc; globalPC = endPc;
} }
actionCfg = cfgraphMap.get(actionName); actionCfg = cfgraphMap.get(actionName);
int blockStart = 0, blockend = 0; int blockStart = 0, blockend = 0;
if (startPc == 0) { if (startPc == 0) {
blockStart = 0; blockStart = 0;
} else { } else {
OUT: for (int j = 0; j < actionCfg.getBasicBlockSize(); j++) { OUT: for (int j = 0; j < actionCfg.getBasicBlockSize(); j++) {
BasicBlock bb = actionCfg.getBasicBlockAt(j); BasicBlock bb = actionCfg.getBasicBlockAt(j);
AbstractInsnNode insnNode = bb.lastInsn(); AbstractInsnNode insnNode = bb.lastInsn();
if (insnNode instanceof InvokeDynamicInsnNode) { if (insnNode instanceof InvokeDynamicInsnNode) {
invoke = ((InvokeDynamicInsnNode) insnNode).bsmArgs[0]; invoke = ((InvokeDynamicInsnNode) insnNode).bsmArgs[0];
if ((int) invoke == startPc) { if ((int) invoke == startPc) {
blockStart = j; blockStart = j;
break OUT; break OUT;
} }
} }
} }
} }
OUT: for (int j = 0; j < actionCfg.getBasicBlockSize(); j++) { OUT: for (int j = 0; j < actionCfg.getBasicBlockSize(); j++) {
BasicBlock bb = actionCfg.getBasicBlockAt(j); BasicBlock bb = actionCfg.getBasicBlockAt(j);
AbstractInsnNode insnNode = bb.lastInsn(); AbstractInsnNode insnNode = bb.lastInsn();
if (insnNode instanceof InvokeDynamicInsnNode) { if (insnNode instanceof InvokeDynamicInsnNode) {
invoke = ((InvokeDynamicInsnNode) insnNode).bsmArgs[0]; invoke = ((InvokeDynamicInsnNode) insnNode).bsmArgs[0];
if ((int) invoke == endPc) { if ((int) invoke == endPc) {
blockend = j; blockend = j;
break OUT; break OUT;
} }
} }
} }
return getInsn(blockStart, blockend); return getInsn(blockStart, blockend);
} }
private HashMap<Integer, Map<String, Integer>> getInsn(int blockStart, int blockend) { private HashMap<Integer, Map<String, Integer>> getInsn(int blockStart, int blockend) {
BasicBlock t; BasicBlock t;
if (blockend == blockStart && blockStart != 0) { if (blockend == blockStart && blockStart != 0) {
System.out.println("blockend" + blockend); System.out.println("blockend" + blockend);
t = actionCfg.getBasicBlockAt(blockend); t = actionCfg.getBasicBlockAt(blockend);
if (t.list.size() > 0) { if (t.list.size() > 0) {
List<AbstractInsnNode> insnList = t.getInsn(); List<AbstractInsnNode> insnList = t.getInsn();
for (AbstractInsnNode insn : insnList) { for (AbstractInsnNode insn : insnList) {
if (insn instanceof InvokeDynamicInsnNode) { if (insn instanceof InvokeDynamicInsnNode) {
callCount(insn); callCount(insn);
} else if (insn instanceof JumpInsnNode) { } else if (insn instanceof JumpInsnNode) {
jumpCount(insn); jumpCount(insn);
} else { } else {
normalCount(insn); normalCount(insn);
} }
} }
} }
return ppcount; return ppcount;
} else if (blockend == 0) { } else if (blockend == 0) {
return ppcount; return ppcount;
} else if (blockend != blockStart && blockStart != 0) { } else if (blockend != blockStart && blockStart != 0) {
blockStart = blockStart + 1; blockStart = blockStart + 1;
blockend = blockend + 1; blockend = blockend + 1;
System.out.println(blockStart); System.out.println(blockStart);
} }
for (int i = blockStart; i < blockend; i++) { for (int i = blockStart; i < blockend; i++) {
t = actionCfg.getBasicBlockAt(i); t = actionCfg.getBasicBlockAt(i);
System.out.println("[t.blockID]" + t.blockID); System.out.println("[t.blockID]" + t.blockID);
if (t.list.size() > 0) { if (t.list.size() > 0) {
List<AbstractInsnNode> insnList = t.getInsn(); List<AbstractInsnNode> insnList = t.getInsn();
for (AbstractInsnNode insn : insnList) { for (AbstractInsnNode insn : insnList) {
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()];
System.out.println("[info.toString()]" + info.toString()); System.out.println("[info.toString()]" + info.toString());
} }
if (info == null) { if (info == null) {
} else if (info.canThrow()) { } else if (info.canThrow()) {
callCount(insn); callCount(insn);
} else if (info.canBranch()) { } else if (info.canBranch()) {
jumpCount(insn); jumpCount(insn);
} else if (info.canContinue()) { } else if (info.canContinue()) {
normalCount(insn); normalCount(insn);
} else if (info.canReturn()) { } else if (info.canReturn()) {
normalCount(insn); normalCount(insn);
} else if (info.canSwitch()) { } else if (info.canSwitch()) {
normalCount(insn); normalCount(insn);
} else { } else {
System.out.println("[info:else]" + info); System.out.println("[info:else]" + info);
normalCount(insn); normalCount(insn);
} }
} }
} }
} }
} }
return ppcount; return ppcount;
} }
private void normalCount(AbstractInsnNode insn) { private void normalCount(AbstractInsnNode insn) {
bdName = FeeSchedule.BDInsn.name(); bdName = FeeSchedule.BDInsn.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} }
private void jumpCount(AbstractInsnNode insn) { private void jumpCount(AbstractInsnNode insn) {
bdName = FeeSchedule.BDjump.name(); bdName = FeeSchedule.BDjump.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} }
private void dynCount(String functionName) { private void dynCount(String functionName) {
if (functionName.contains("getProp")) { if (functionName.contains("getProp")) {
bdName = FeeSchedule.BDgetMethod.name(); bdName = FeeSchedule.BDgetMethod.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else if (functionName.contains("setProp")) { } else if (functionName.contains("setProp")) {
bdName = FeeSchedule.BDsetMethod.name(); bdName = FeeSchedule.BDsetMethod.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else if (functionName.contains("call") && functionName.contains("Util")) { } else if (functionName.contains("call") && functionName.contains("Util")) {
bdName = FeeSchedule.BDcallUtil.name(); bdName = FeeSchedule.BDcallUtil.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else if (functionName.contains("call") && isInnerfunction(functionName)) { } else if (functionName.contains("call") && isInnerfunction(functionName)) {
bdName = FeeSchedule.BDcallFuntion.name(); bdName = FeeSchedule.BDcallFuntion.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else if (functionName.contains("call")) { } else if (functionName.contains("call")) {
bdName = FeeSchedule.BDcallUtil.name(); bdName = FeeSchedule.BDcallUtil.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else { } else {
bdName = FeeSchedule.BDInsn.name(); bdName = FeeSchedule.BDInsn.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} }
} }
private boolean isInnerfunction(String functionName) { private boolean isInnerfunction(String functionName) {
String string = functionName.split(":")[2]; String string = functionName.split(":")[2];
if (cfgraphMap.containsKey(string)) { if (cfgraphMap.containsKey(string)) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
} }

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

@@ -20,7 +20,7 @@ public class Evaluates {
long fee = getValue(cmap.getKey()); long fee = getValue(cmap.getKey());
value = fee * cmap.getValue() + value; value = fee * cmap.getValue() + value;
} }
CountResult.put(cfrKey, value); CountResult.put(cfrKey, value);
} }
return CountResult; return CountResult;
} }
@@ -62,14 +62,14 @@ 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);
}
map.put(varInsn.getKey(), sum);
} }
map.put(varInsn.getKey(), sum);
}
} }
private void blockGas(Map<Integer, HashMap<String, Integer>> m) { private void blockGas(Map<Integer, HashMap<String, Integer>> m) {
@@ -84,13 +84,13 @@ 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);
} }
map.put(varInsn.getKey().toString(), sum); map.put(varInsn.getKey().toString(), sum);
} }
} }
} }

View File

@@ -1,52 +1,51 @@
package org.bdware.analysis.gas; 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;
FeeSchedule(long value) { FeeSchedule(long value) {
fee = value; fee = value;
} }
public long getFee() { public long getFee() {
return fee; return fee;
} }
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;
} }
return value; return value;
} }
public String getString(FeeSchedule feeName) { public String getString(FeeSchedule feeName) {
return feeName.toString(); return feeName.toString();
} }
} }

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,42 +302,44 @@ 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);
} }
} else if (function.contains("call") && isInnerfunction(functionName)) { } else if (function.contains("call") && isInnerfunction(functionName)) {
// System.out.println("[call ]" + functionName); // System.out.println("[call ]" + functionName);
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)
BlockInsn.get(globalBlockID).get(bdName + "," + methName) + 1); .put(
bdName + "," + methName,
BlockInsn.get(globalBlockID).get(bdName + "," + methName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName + "," + methName, 1); BlockInsn.get(globalBlockID).put(bdName + "," + methName, 1);
@@ -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);
} }
@@ -360,8 +366,8 @@ public class PPCount extends DFS {
private boolean isInnerfunction(String functionName) { private boolean isInnerfunction(String functionName) {
String string = functionName.split(":")[2]; String string = functionName.split(":")[2];
// System.out.println("++++++++++++++" + functionName); // System.out.println("++++++++++++++" + functionName);
// System.out.println("【function】" + functionList); // System.out.println("【function】" + functionList);
if (functionList.contains(string)) { if (functionList.contains(string)) {
return true; return true;
} else { } else {
@@ -369,57 +375,57 @@ public class PPCount extends DFS {
} }
} }
// public static void main(String[] args) throws Exception { // public static void main(String[] args) throws Exception {
// String path = "/Users/hulingxuan/git/SmartContract/output/main.yjs"; // String path = "/Users/hulingxuan/git/SmartContract/output/main.yjs";
// ContractNode contractNode = null; // ContractNode contractNode = null;
// YJSCompiler compiler = new YJSCompiler(); // YJSCompiler compiler = new YJSCompiler();
// contractNode = compiler.compile(new FileInputStream(path), null); // contractNode = compiler.compile(new FileInputStream(path), null);
// engine = new DesktopEngine(); // engine = new DesktopEngine();
// engine.loadContract(contractNode, false); // engine.loadContract(contractNode, false);
// //
// Map<String, byte[]> clzs = engine.dumpClass(); // Map<String, byte[]> clzs = engine.dumpClass();
// Map<String, MethodNode> methods = new HashMap<>(); // Map<String, MethodNode> methods = new HashMap<>();
// for (byte[] clz : clzs.values()) { // for (byte[] clz : clzs.values()) {
// ClassNode classNode = new ClassNode(); // ClassNode classNode = new ClassNode();
// ClassReader cr = new ClassReader(clz); // ClassReader cr = new ClassReader(clz);
// cr.accept(classNode, ClassReader.EXPAND_FRAMES); // cr.accept(classNode, ClassReader.EXPAND_FRAMES);
// for (MethodNode mn : classNode.methods) { // for (MethodNode mn : classNode.methods) {
// methods.put(mn.name, mn); // methods.put(mn.name, mn);
// } // }
// } // }
// int flag = 0; // int flag = 0;
// for (FunctionNode fn : contractNode.getFunctions()) { // for (FunctionNode fn : contractNode.getFunctions()) {
// functionList.add(fn.functionName); // functionList.add(fn.functionName);
// MethodNode mn = methods.get(fn.functionName); // MethodNode mn = methods.get(fn.functionName);
// if (mn != null) { // if (mn != null) {
// CFGraph cfg = new CFGraph(mn) { // CFGraph cfg = new CFGraph(mn) {
// @Override // @Override
// public BasicBlock getBasicBlock(int id) { // public BasicBlock getBasicBlock(int id) {
// return new BasicBlock(id); // return new BasicBlock(id);
// } // }
// }; // };
// // cfg.getLabelOrder(); // // cfg.getLabelOrder();
// PPCount countFee = new PPCount(cfg, flag); // PPCount countFee = new PPCount(cfg, flag);
// //
// BasicBlock bb = cfg.getBasicBlockAt(0); // BasicBlock bb = cfg.getBasicBlockAt(0);
// countFee.dfs(cfg, bb); // countFee.dfs(cfg, bb);
// // cfg.printSelf(); // // cfg.printSelf();
// //
// Evaluates feEvaluates = new Evaluates(); // Evaluates feEvaluates = new Evaluates();
// feEvaluates.getGas(branchCount); // feEvaluates.getGas(branchCount);
// feEvaluates.getInsnGas(ppMap); // feEvaluates.getInsnGas(ppMap);
// countFunction(fn.functionName, Evaluates.map); // countFunction(fn.functionName, Evaluates.map);
// System.out.println("+++++++" + functionSumGas); // System.out.println("+++++++" + functionSumGas);
// System.out.println("========" + Evaluates.map); // System.out.println("========" + Evaluates.map);
// flag++; // flag++;
// } // }
// } // }
// System.out.println(branchCount); // System.out.println(branchCount);
// System.out.println(BlockInsn); // System.out.println(BlockInsn);
// System.out.println(ppMap); // System.out.println(ppMap);
// //
// // System.out.println(feEvaluates.getCallFee()); // // System.out.println(feEvaluates.getCallFee());
// } // }
public static HashMap<String, Long> functionSumGas = new HashMap<>(); public static HashMap<String, Long> functionSumGas = new HashMap<>();

View File

@@ -5,24 +5,24 @@ import java.util.Set;
import org.bdware.analysis.BasicBlock; import org.bdware.analysis.BasicBlock;
public class DirectGraphDFS { public class DirectGraphDFS {
private boolean[] marked; private boolean[] marked;
public DirectGraphDFS(TaintCFG cfg, BasicBlock start) { public DirectGraphDFS(TaintCFG cfg, BasicBlock start) {
marked = new boolean[cfg.getBlocks().size()]; marked = new boolean[cfg.getBlocks().size()];
dfs(cfg, start); dfs(cfg, start);
} }
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);
} }
} }
public boolean isArrival(BasicBlock end) { public boolean isArrival(BasicBlock end) {
return marked[end.blockID]; return marked[end.blockID];
} }
} }

View File

@@ -11,240 +11,237 @@ import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode; import org.objectweb.asm.tree.InvokeDynamicInsnNode;
public class HeapObject extends TaintValue { public class HeapObject extends TaintValue {
private Map<String, TaintValue> fields = new HashMap<String, TaintValue>(); private Map<String, TaintValue> fields = new HashMap<String, TaintValue>();
static int allocatID = 0; static int allocatID = 0;
int id; int id;
public HeapObject() { public HeapObject() {
super(1); super(1);
id = allocatID++; id = allocatID++;
} }
public HeapObject(TaintValue t) { public HeapObject(TaintValue t) {
this(); this();
if (t != null) { if (t != null) {
merge(t); merge(t);
size = t.size; size = t.size;
} else { } else {
isTainted = 0; isTainted = 0;
size = 1; size = 1;
} }
} }
public static HeapObject getRootObject() { public static HeapObject getRootObject() {
HeapObject ret = new HeapObject(); HeapObject ret = new HeapObject();
ret.setProp("Global", new HeapObject()); ret.setProp("Global", new HeapObject());
ret.setProp("getScope", new HeapObject()); ret.setProp("getScope", new HeapObject());
return ret; return ret;
} }
@Override @Override
public String toString() { public String toString() {
return countSize() + "|" + super.toString(); return countSize() + "|" + super.toString();
} }
private String countSize() { private String countSize() {
objSet = new HashSet<>(); objSet = new HashSet<>();
return countSizeInternal(); return countSizeInternal();
} }
private String countSizeInternal() { private String countSizeInternal() {
if (objSet.contains(this)) if (objSet.contains(this))
return "{H" + id + "}"; return "{H" + id + "}";
objSet.add(this); objSet.add(this);
String ret = "{H" + id + ","; String ret = "{H" + id + ",";
for (String field : fields.keySet()) { for (String field : fields.keySet()) {
TaintValue tv = fields.get(field); TaintValue tv = fields.get(field);
if (tv instanceof HeapObject) if (tv instanceof HeapObject)
ret += field + ":" + ((HeapObject) tv).countSizeInternal() + ","; ret += field + ":" + ((HeapObject) tv).countSizeInternal() + ",";
else else
ret += field + ":" + tv.isTainted; ret += field + ":" + tv.isTainted;
} }
ret += isTainted + "}"; ret += isTainted + "}";
return ret; return ret;
} }
private static HashSet<HeapObject> objSet; private static HashSet<HeapObject> objSet;
public static TaintValue operate(AbstractInsnNode insn, List<? extends TaintValue> values, public static TaintValue operate(AbstractInsnNode insn, List<? extends TaintValue> values,
TaintValue calculatedVal) { TaintValue calculatedVal) {
TaintValue retVal = null; TaintValue retVal = null;
String desc; String desc;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKEVIRTUAL:
desc = ((MethodInsnNode) insn).owner; desc = ((MethodInsnNode) insn).owner;
if (isGetScopeObject((MethodInsnNode) insn) && values.size() != 0) { if (isGetScopeObject((MethodInsnNode) insn) && values.size() != 0) {
TaintValue tv = values.get(0); TaintValue tv = values.get(0);
if (tv instanceof HeapObject) { if (tv instanceof HeapObject) {
HeapObject heapObject = (HeapObject) tv; HeapObject heapObject = (HeapObject) tv;
retVal = heapObject.getProp("getScope"); retVal = heapObject.getProp("getScope");
if (retVal == null) { if (retVal == null) {
return calculatedVal; return calculatedVal;
} else } else
return retVal; return retVal;
} }
} }
break; break;
case Opcodes.INVOKESPECIAL: case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKESTATIC: case Opcodes.INVOKESTATIC:
case Opcodes.INVOKEINTERFACE: case Opcodes.INVOKEINTERFACE:
break; break;
case Opcodes.INVOKEDYNAMIC: case Opcodes.INVOKEDYNAMIC:
desc = ((InvokeDynamicInsnNode) insn).name; desc = ((InvokeDynamicInsnNode) insn).name;
desc = desc.replaceAll(".*:", ""); desc = desc.replaceAll(".*:", "");
if (isDynGet((InvokeDynamicInsnNode) insn)) { if (isDynGet((InvokeDynamicInsnNode) insn)) {
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;
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) System.out.println("[HeapObject] get:" + desc + " taintVal: empty");
System.out.println("[HeapObject] get:" + desc + " taintVal: empty"); heapObject.setProp(desc, new HeapObject());
heapObject.setProp(desc, new HeapObject()); return heapObject.getProp(desc);
return heapObject.getProp(desc); }
} } else {
} else { // TODO
// TODO }
} } 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.println("[HeapObject] set:" + desc + " taintVal:" + values.get(1));
System.out TaintValue tval = values.get(0);
.println("[HeapObject] set:" + desc + " taintVal:" + values.get(1)); if (tval instanceof HeapObject) {
TaintValue tval = values.get(0); HeapObject heapObject = (HeapObject) tval;
if (tval instanceof HeapObject) { // heapObject.merge(values.get(1));
HeapObject heapObject = (HeapObject) tval; heapObject.setProp(desc,
// heapObject.merge(values.get(1)); values.get(1) instanceof HeapObject ? values.get(1) : new HeapObject(values.get(1)));
heapObject.setProp(desc, values.get(1) instanceof HeapObject ? values.get(1) } else {
: new HeapObject(values.get(1))); HeapObject heapObject = new HeapObject(tval);
} else { heapObject.merge(tval);
HeapObject heapObject = new HeapObject(tval); // heapObject.merge(values.get(1));
heapObject.merge(tval); heapObject.setProp(desc, values.get(1));
// heapObject.merge(values.get(1)); }
heapObject.setProp(desc, values.get(1)); } else {
} for (TaintValue tv : values) {
} else { if (tv instanceof HeapObject) {
for (TaintValue tv : values) { calculatedVal.isTainted |= ((HeapObject) tv).wholeTaint();
if (tv instanceof HeapObject) { }
calculatedVal.isTainted |= ((HeapObject) tv).wholeTaint(); }
} }
} break;
} default:
break; }
default: return calculatedVal;
}
return calculatedVal;
} }
private static boolean isDynGet(InvokeDynamicInsnNode insn) { private static boolean isDynGet(InvokeDynamicInsnNode insn) {
String desc = insn.name; String desc = insn.name;
if (desc.contains("getProp") && desc.contains("getMethod") && desc.contains("getElem")) { if (desc.contains("getProp") && desc.contains("getMethod") && desc.contains("getElem")) {
return true; return true;
} }
return false; return false;
} }
private static boolean isDynSet(InvokeDynamicInsnNode insn) { private static boolean isDynSet(InvokeDynamicInsnNode insn) {
String desc = insn.name; String desc = insn.name;
if (desc.contains("setProp") && desc.contains("setElem")) { if (desc.contains("setProp") && desc.contains("setElem")) {
// System.out.println(desc); // System.out.println(desc);
return true; return true;
} }
return false; return false;
} }
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; }
}
public TaintValue getProp(String str) { public TaintValue getProp(String str) {
return fields.get(str); return fields.get(str);
} }
public TaintValue setProp(String str, TaintValue val) { public TaintValue setProp(String str, TaintValue val) {
return fields.put(str, val); return fields.put(str, val);
} }
@Override @Override
public HeapObject clone() { public HeapObject clone() {
return this; return this;
} }
public HeapObject actualClone() { public HeapObject actualClone() {
ccObj = new HashMap<>(); ccObj = new HashMap<>();
return cloneInternal(); return cloneInternal();
} }
static Map<HeapObject, HeapObject> ccObj; static Map<HeapObject, HeapObject> ccObj;
private HeapObject cloneInternal() { private HeapObject cloneInternal() {
if (ccObj.containsKey(this)) if (ccObj.containsKey(this))
return ccObj.get(this); return ccObj.get(this);
HeapObject ho = new HeapObject(); HeapObject ho = new HeapObject();
ccObj.put(this, ho); ccObj.put(this, ho);
ho.isTainted = isTainted; ho.isTainted = isTainted;
for (String field : fields.keySet()) { for (String field : fields.keySet()) {
TaintValue target = fields.get(field); TaintValue target = fields.get(field);
if (target instanceof HeapObject) if (target instanceof HeapObject)
ho.fields.put(field, ((HeapObject) target).cloneInternal()); ho.fields.put(field, ((HeapObject) target).cloneInternal());
else else
ho.fields.put(field, target.clone()); ho.fields.put(field, target.clone());
} }
return ho; return ho;
} }
// TODO consider the "Cite circle" // TODO consider the "Cite circle"
public void heapMerge(TaintValue target) { public void heapMerge(TaintValue target) {
merge(target); merge(target);
if (target instanceof HeapObject) { if (target instanceof HeapObject) {
HeapObject targetObject = (HeapObject) target; HeapObject targetObject = (HeapObject) target;
for (String field : targetObject.fields.keySet()) { for (String field : targetObject.fields.keySet()) {
if (fields.containsKey(field)) { if (fields.containsKey(field)) {
TaintValue t2 = fields.get(field); TaintValue t2 = fields.get(field);
TaintValue target2 = targetObject.fields.get(field); TaintValue target2 = targetObject.fields.get(field);
// System.out.println("[HeapObject heapMerge]:" + field); // System.out.println("[HeapObject heapMerge]:" + field);
if (t2 instanceof HeapObject) { if (t2 instanceof HeapObject) {
((HeapObject) t2).heapMerge(target2); ((HeapObject) t2).heapMerge(target2);
} else if (target2 instanceof HeapObject) { } else if (target2 instanceof HeapObject) {
HeapObject next = ((HeapObject) target2).clone(); HeapObject next = ((HeapObject) target2).clone();
next.merge(t2); next.merge(t2);
fields.put(field, next); fields.put(field, next);
} else } else
t2.merge(target2); t2.merge(target2);
} else } else
fields.put(field, targetObject.fields.get(field).clone()); fields.put(field, targetObject.fields.get(field).clone());
} }
} }
} }
public synchronized long wholeTaint() { public synchronized long wholeTaint() {
objSet = new HashSet<>(); objSet = new HashSet<>();
return wholeTaintInternal(); return wholeTaintInternal();
} }
private long wholeTaintInternal() { private long wholeTaintInternal() {
if (objSet.contains(this)) if (objSet.contains(this))
return 0L; return 0L;
objSet.add(this); objSet.add(this);
long ret = isTainted; long ret = isTainted;
for (TaintValue tv : fields.values()) { for (TaintValue tv : fields.values()) {
if (tv instanceof HeapObject) if (tv instanceof HeapObject)
ret |= ((HeapObject) tv).wholeTaintInternal(); ret |= ((HeapObject) tv).wholeTaintInternal();
else else
ret |= tv.isTainted; ret |= tv.isTainted;
} }
return ret; return ret;
} }
} }

View File

@@ -7,67 +7,63 @@ import org.bdware.analysis.BasicBlock;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
public class TaintBB extends BasicBlock implements AnalysisTarget { public class TaintBB extends BasicBlock implements AnalysisTarget {
boolean inList = false; boolean inList = false;
public TaintBB(int id) { public TaintBB(int id) {
super(id); super(id);
preResult = new TaintResult(); preResult = new TaintResult();
sucResult = new TaintResult(); sucResult = new TaintResult();
} }
public TaintResult preResult; public TaintResult preResult;
public TaintResult sucResult; public TaintResult sucResult;
@Override @Override
public boolean inList() { public boolean inList() {
return inList; return inList;
} }
@Override @Override
public void setInList(boolean b) { public void setInList(boolean b) {
inList = b; inList = b;
} }
public String getResult() { public String getResult() {
return (sucResult.frame2Str() + " Ret:" + sucResult.ret.toString()); return (sucResult.frame2Str() + " Ret:" + sucResult.ret.toString());
} }
public String getResultWithTaintBit() { public String getResultWithTaintBit() {
return "Ret:" + sucResult.ret.toReadableTaint(); return "Ret:" + sucResult.ret.toReadableTaint();
} }
public TaintResult forwardAnalysis() { public TaintResult forwardAnalysis() {
TaintResult oldSuc = sucResult; TaintResult oldSuc = sucResult;
sucResult = (TaintResult) preResult.clone(); sucResult = (TaintResult) preResult.clone();
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));
} }
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; }
}
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() {
return list;
public List<AbstractInsnNode> AllInsn() { }
return list;
}

View File

@@ -4,65 +4,65 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class TaintBits { public class TaintBits {
Map<Long, String> data; Map<Long, String> data;
Map<String, Long> type2Taint; Map<String, Long> type2Taint;
long curr; long curr;
Map<String, String> reallocate; Map<String, String> reallocate;
int count = 0; int count = 0;
public TaintBits() { public TaintBits() {
curr = 1L; curr = 1L;
data = new HashMap<>(); data = new HashMap<>();
type2Taint = new HashMap<>(); type2Taint = new HashMap<>();
reallocate = new HashMap<>(); reallocate = new HashMap<>();
} }
public long allocate(String type) { public long allocate(String type) {
type = reallocateCall(type); type = reallocateCall(type);
if (type2Taint.containsKey(type)) if (type2Taint.containsKey(type))
return type2Taint.get(type); return type2Taint.get(type);
long ret = curr; long ret = curr;
data.put(curr, type); data.put(curr, type);
type2Taint.put(type, curr); type2Taint.put(type, curr);
curr <<= 1; curr <<= 1;
return ret; return ret;
} }
private String reallocateCall(String type) { private String reallocateCall(String type) {
if (reallocate.containsKey(type)) if (reallocate.containsKey(type))
return reallocate.get(type); return reallocate.get(type);
if (type.contains("dyn:call:executeContract")) { if (type.contains("dyn:call:executeContract")) {
reallocate.put(type, "executeContract" + (count++)); reallocate.put(type, "executeContract" + (count++));
return reallocate.get(type); return reallocate.get(type);
} }
return type; return type;
} }
public long getTaintValue(String type) { public long getTaintValue(String type) {
type = reallocateCall(type); type = reallocateCall(type);
if (type2Taint.containsKey(type)) if (type2Taint.containsKey(type))
return type2Taint.get(type); return type2Taint.get(type);
return -1; return -1;
} }
public String taintInfo() { public String taintInfo() {
String ret = ""; String ret = "";
long curr = this.curr >> 1; long curr = this.curr >> 1;
for (; curr >= 1L;) { for (; curr >= 1L;) {
ret += data.get(curr) + ", "; ret += data.get(curr) + ", ";
curr >>= 1; curr >>= 1;
} }
return ret; return ret;
} }
public String parse(long isTainted) { public String parse(long isTainted) {
String ret = ""; String ret = "";
long curr = this.curr >> 1; long curr = this.curr >> 1;
for (; curr >= 1L;) { for (; curr >= 1L;) {
if ((isTainted & curr) != 0) if ((isTainted & curr) != 0)
ret += data.get(curr) + " "; ret += data.get(curr) + " ";
curr >>= 1; curr >>= 1;
} }
return ret; return ret;
} }
} }

View File

@@ -11,75 +11,74 @@ import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
public class TaintCFG extends CFGraph { public class TaintCFG extends CFGraph {
public TaintBits taintBits; public TaintBits taintBits;
public TaintCFG(MethodNode mn) { public TaintCFG(MethodNode mn) {
super(mn); super(mn);
taintBits = new TaintBits(); taintBits = new TaintBits();
} }
@Override @Override
public BasicBlock getBasicBlock(int id) { public BasicBlock getBasicBlock(int id) {
return new TaintBB(id); return new TaintBB(id);
} }
public int argsLocal() { public int argsLocal() {
String desc = getMethodNode().desc; String desc = getMethodNode().desc;
String[] parameters = desc.split("[)]"); String[] parameters = desc.split("[)]");
String parameter = parameters[0]; String parameter = parameters[0];
String[] args = parameter.split("[;]"); String[] args = parameter.split("[;]");
return args.length - 1; return args.length - 1;
} }
public void executeLocal() { public void executeLocal() {
for (BasicBlock bb : basicBlocks) { for (BasicBlock bb : basicBlocks) {
for (AbstractInsnNode an : bb.getInsn()) { for (AbstractInsnNode an : bb.getInsn()) {
if (an instanceof InvokeDynamicInsnNode) { if (an instanceof InvokeDynamicInsnNode) {
InvokeDynamicInsnNode inDy = (InvokeDynamicInsnNode) an; InvokeDynamicInsnNode inDy = (InvokeDynamicInsnNode) an;
if (inDy.name.contains("dyn:call:executeContract")) { if (inDy.name.contains("dyn:call:executeContract")) {
taintBits.allocate(inDy.name + inDy.hashCode()); taintBits.allocate(inDy.name + inDy.hashCode());
} }
} }
} }
} }
return; return;
} }
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); if (getSucBlocks(bb).size() > 0)
if (getSucBlocks(bb).size() > 0) System.out.print("-->");
System.out.print("-->"); for (BasicBlock suc : getSucBlocks(bb))
for (BasicBlock suc : getSucBlocks(bb)) System.out.print(" B" + suc.blockID);
System.out.print(" B" + suc.blockID); System.out.println("==");
System.out.println("=="); TaintBB b = (TaintBB) bb;
TaintBB b = (TaintBB) bb; 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()) {
an.accept(printer); an.accept(printer);
} }
} }
} }
public TaintBB getLastBlock() { public TaintBB getLastBlock() {
if (basicBlocks != null && basicBlocks.size() > 0) if (basicBlocks != null && basicBlocks.size() > 0)
return (TaintBB) basicBlocks.get(basicBlocks.size() - 1); return (TaintBB) basicBlocks.get(basicBlocks.size() - 1);
return null; return null;
} }
public List<BasicBlock> getBlocks() { public List<BasicBlock> getBlocks() {
return basicBlocks; return basicBlocks;
} }
} }

View File

@@ -1,5 +1,5 @@
package org.bdware.analysis.taint; package org.bdware.analysis.taint;
public class TaintConfig { public class TaintConfig {
public static boolean isDebug = false; public static boolean isDebug = false;
} }

View File

@@ -12,172 +12,166 @@ import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.Interpreter; import org.objectweb.asm.tree.analysis.Interpreter;
public class TaintInterpreter extends Interpreter<TaintValue> { public class TaintInterpreter extends Interpreter<TaintValue> {
TaintResult currentResult; TaintResult currentResult;
TaintBits taintBits; TaintBits taintBits;
public TaintInterpreter(int api) { public TaintInterpreter(int api) {
super(api); super(api);
} }
@Override @Override
public TaintValue newValue(Type type) { public TaintValue newValue(Type type) {
if (type != null) if (type != null)
return new TaintValue(type.getSize()); return new TaintValue(type.getSize());
return new TaintValue(1); return new TaintValue(1);
} }
@Override @Override
public TaintValue newOperation(AbstractInsnNode insn) throws AnalyzerException { public TaintValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
TaintValue ret; TaintValue ret;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case Opcodes.LCONST_0: case Opcodes.LCONST_0:
case Opcodes.LCONST_1: case Opcodes.LCONST_1:
case Opcodes.DCONST_0: case Opcodes.DCONST_0:
case Opcodes.DCONST_1: case Opcodes.DCONST_1:
ret = new TaintValue(2); ret = new TaintValue(2);
break; break;
case Opcodes.NEW: case Opcodes.NEW:
TypeInsnNode typeNode = (TypeInsnNode) insn; TypeInsnNode typeNode = (TypeInsnNode) insn;
if (typeNode.desc.startsWith("wrp/jdk/nashorn/internal/scripts/JO")) { if (typeNode.desc.startsWith("wrp/jdk/nashorn/internal/scripts/JO")) {
ret = new HeapObject(); ret = new HeapObject();
} else { } else {
ret = new TaintValue(1); ret = new TaintValue(1);
} }
break; break;
default: default:
ret = new TaintValue(1); ret = new TaintValue(1);
} }
return ret; return ret;
} }
@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; }
}
@Override @Override
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); */
ret.isTainted = value1.isTainted | value2.isTainted; TaintValue ret = new TaintValue(1);
switch (insn.getOpcode()) { ret.isTainted = value1.isTainted | value2.isTainted;
case Opcodes.DALOAD: switch (insn.getOpcode()) {
case Opcodes.DADD: case Opcodes.DALOAD:
case Opcodes.DSUB: case Opcodes.DADD:
case Opcodes.DMUL: case Opcodes.DSUB:
case Opcodes.DDIV: case Opcodes.DMUL:
case Opcodes.DREM: case Opcodes.DDIV:
case Opcodes.LALOAD: case Opcodes.DREM:
case Opcodes.LADD: case Opcodes.LALOAD:
case Opcodes.LSUB: case Opcodes.LADD:
case Opcodes.LMUL: case Opcodes.LSUB:
case Opcodes.LDIV: case Opcodes.LMUL:
case Opcodes.LREM: case Opcodes.LDIV:
case Opcodes.LSHL: case Opcodes.LREM:
case Opcodes.LSHR: case Opcodes.LSHL:
case Opcodes.LUSHR: case Opcodes.LSHR:
case Opcodes.LAND: case Opcodes.LUSHR:
case Opcodes.LXOR: case Opcodes.LAND:
case Opcodes.LOR: case Opcodes.LXOR:
ret.size = 2; case Opcodes.LOR:
default: ret.size = 2;
} default:
return ret; }
} return ret;
}
@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
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY and * and INVOKEDYNAMIC
* INVOKEDYNAMIC */
*/ String desc;
String desc; switch (insn.getOpcode()) {
switch (insn.getOpcode()) { case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKESPECIAL: 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' || desc.charAt(desc.length() - 1) == 'J'))
if (desc != null && (desc.charAt(desc.length() - 1) == 'D' size = 2;
|| desc.charAt(desc.length() - 1) == 'J')) break;
size = 2; case Opcodes.INVOKEDYNAMIC:
break; desc = ((InvokeDynamicInsnNode) insn).desc;
case Opcodes.INVOKEDYNAMIC: if (desc != null && (desc.charAt(desc.length() - 1) == 'D' || desc.charAt(desc.length() - 1) == 'J'))
desc = ((InvokeDynamicInsnNode) insn).desc; size = 2;
if (desc != null && (desc.charAt(desc.length() - 1) == 'D'
|| desc.charAt(desc.length() - 1) == 'J'))
size = 2;
// Extra..Judgeffff x // Extra..Judgeffff x
if (((InvokeDynamicInsnNode) insn).name.startsWith("dyn:setElem|setProp:")) { if (((InvokeDynamicInsnNode) insn).name.startsWith("dyn:setElem|setProp:")) {
if (values.size() == 2) { if (values.size() == 2) {
values.get(0).isTainted |= values.get(1).isTainted; values.get(0).isTainted |= values.get(1).isTainted;
} }
} }
break; break;
default: default:
} }
TaintValue ret = new TaintValue(size); TaintValue ret = new TaintValue(size);
for (TaintValue v : values) for (TaintValue v : values)
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;
} }
return HeapObject.operate(insn, values, ret); return HeapObject.operate(insn, values, ret);
} }
@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; }
}
@Override @Override
public TaintValue merge(TaintValue v, TaintValue w) { public TaintValue merge(TaintValue v, TaintValue w) {
TaintValue ret = new TaintValue(v.getSize()); TaintValue ret = new TaintValue(v.getSize());
ret.isTainted |= v.isTainted; ret.isTainted |= v.isTainted;
ret.isTainted |= w.isTainted; ret.isTainted |= w.isTainted;
return ret; return ret;
} }
public void setCurrentResult(TaintResult naiveTaintResult) { public void setCurrentResult(TaintResult naiveTaintResult) {
currentResult = naiveTaintResult; currentResult = naiveTaintResult;
} }
public void setTaintBits(TaintBits tb) { public void setTaintBits(TaintBits tb) {
taintBits = tb; taintBits = tb;
} }
} }

View File

@@ -8,183 +8,183 @@ import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.Frame; import org.objectweb.asm.tree.analysis.Frame;
public class TaintResult extends AnalysisResult { public class TaintResult extends AnalysisResult {
// public HeapObject heapObejct; // public HeapObject heapObejct;
public Frame<TaintValue> frame; public Frame<TaintValue> frame;
public TaintValue ret; public TaintValue ret;
public static int nLocals = 0; public static int nLocals = 0;
public static int nStack = 0; public static int nStack = 0;
public static InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out); public static InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out);
public static TaintInterpreter interpreter = new TaintInterpreter(Opcodes.ASM4); public static TaintInterpreter interpreter = new TaintInterpreter(Opcodes.ASM4);
public TaintResult() { public TaintResult() {
frame = new Frame<>(nLocals, nStack); frame = new Frame<>(nLocals, nStack);
ret = new TaintValue(1); ret = new TaintValue(1);
ret.isTainted = 0L; ret.isTainted = 0L;
} }
@Override @Override
public AnalysisResult merge(AbstractInsnNode insn) { public AnalysisResult merge(AbstractInsnNode insn) {
interpreter.setCurrentResult(this); interpreter.setCurrentResult(this);
try { try {
if (TaintConfig.isDebug && insn.getOpcode() >= 0) { if (TaintConfig.isDebug && insn.getOpcode() >= 0) {
System.out.println("[TaintResult] frameStatus:" + frame2Str()); System.out.println("[TaintResult] frameStatus:" + frame2Str());
insn.accept(printer); insn.accept(printer);
} }
if (insn.getOpcode() < 0) { if (insn.getOpcode() < 0) {
// System.out.println("[TaintResult] MetLabel:" + // System.out.println("[TaintResult] MetLabel:" +
// insn.getClass().getCanonicalName()); // insn.getClass().getCanonicalName());
} else } else
frame.execute(insn, interpreter); frame.execute(insn, interpreter);
if (TaintConfig.isDebug && insn.getOpcode() >= 0) { if (TaintConfig.isDebug && insn.getOpcode() >= 0) {
System.out.println("[TaintResult] frameStatus:" + frame2Str()); System.out.println("[TaintResult] frameStatus:" + frame2Str());
} }
} catch (AnalyzerException e) { } catch (AnalyzerException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
// we use suc instead,so we don't create new object here. // we use suc instead,so we don't create new object here.
return this; return this;
} }
@Override @Override
public void printResult() { public void printResult() {
System.out.println("====" + frame2Str() + " Ret:" + ret.toString() + "===="); System.out.println("====" + frame2Str() + " Ret:" + ret.toString() + "====");
} }
public String frame2Str() { public String frame2Str() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Local:"); sb.append("Local:");
for (int i = 0; i < frame.getLocals(); i++) { // getLocals<6C><73><EFBFBD><EFBFBD>local<61><6C><EFBFBD><EFBFBD><EFBFBD>size for (int i = 0; i < frame.getLocals(); i++) { // getLocals<6C><73><EFBFBD><EFBFBD>local<61><6C><EFBFBD><EFBFBD><EFBFBD>size
TaintValue t = frame.getLocal(i); TaintValue t = frame.getLocal(i);
if (t != null) if (t != null)
sb.append(t.toString()); sb.append(t.toString());
else else
sb.append("0--"); sb.append("0--");
} }
sb.append(" Stack:"); sb.append(" Stack:");
for (int i = 0; i < frame.getStackSize(); i++) { // getStackSize<7A><65><EFBFBD><EFBFBD>stack<63>ĵ<EFBFBD>ǰsize for (int i = 0; i < frame.getStackSize(); i++) { // getStackSize<7A><65><EFBFBD><EFBFBD>stack<63>ĵ<EFBFBD>ǰsize
TaintValue t = frame.getStack(i); TaintValue t = frame.getStack(i);
if (t != null) if (t != null)
sb.append(t.toString()); sb.append(t.toString());
else else
sb.append("0--"); sb.append("0--");
} }
return sb.toString(); return sb.toString();
} }
private static boolean cover(TaintValue t1, TaintValue t2) { private static boolean cover(TaintValue t1, TaintValue t2) {
// if (t2 == null || t2.isTainted == 0) // if (t2 == null || t2.isTainted == 0)
// return true; // return true;
// TODO whether is cover? // TODO whether is cover?
if (t1 != null && t1.isTainted != 0) { if (t1 != null && t1.isTainted != 0) {
if (t2 == null || t1.isTainted != t2.isTainted) if (t2 == null || t1.isTainted != t2.isTainted)
return true; return true;
} }
return false; return false;
} }
/* /*
* 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) {
return true; return true;
} }
return false; return false;
} }
@Override @Override
public boolean covers(AnalysisResult result) { public boolean covers(AnalysisResult result) {
TaintResult tr = (TaintResult) result; TaintResult tr = (TaintResult) result;
boolean ret = coversInternal(tr); boolean ret = coversInternal(tr);
return ret; return ret;
// System.out.println("[NaiveTaintResult] Cover:" + ret); // System.out.println("[NaiveTaintResult] Cover:" + ret);
// System.out.println("[NaiveTaintResult] " + frame.toString()); // System.out.println("[NaiveTaintResult] " + frame.toString());
// System.out.println("[NaiveTaintResult] " + tr.frame.toString()); // System.out.println("[NaiveTaintResult] " + tr.frame.toString());
} }
// preResult cover sucResult means // preResult cover sucResult means
// preResult's taint is large or equals sucResult. // preResult's taint is large or equals sucResult.
public boolean coversInternal(TaintResult tr) { public boolean coversInternal(TaintResult tr) {
for (int i = 0; i < frame.getLocals() && i < tr.frame.getLocals(); i++) for (int i = 0; i < frame.getLocals() && i < tr.frame.getLocals(); i++)
if (cover(tr.frame.getLocal(i), frame.getLocal(i))) if (cover(tr.frame.getLocal(i), frame.getLocal(i)))
return false; return false;
// TODO why locals is not equal?? // TODO why locals is not equal??
for (int i = frame.getLocals(); i < tr.frame.getLocals(); i++) for (int i = frame.getLocals(); i < tr.frame.getLocals(); i++)
if (isTainted(tr.frame.getLocal(i))) if (isTainted(tr.frame.getLocal(i)))
return false; return false;
for (int i = 0; i < frame.getStackSize() && i < tr.frame.getStackSize(); i++) for (int i = 0; i < frame.getStackSize() && i < tr.frame.getStackSize(); i++)
if (cover(tr.frame.getStack(i), frame.getStack(i))) if (cover(tr.frame.getStack(i), frame.getStack(i)))
return false; return false;
for (int i = frame.getStackSize(); i < tr.frame.getStackSize(); i++) for (int i = frame.getStackSize(); i < tr.frame.getStackSize(); i++)
if (isTainted(tr.frame.getStack(i))) if (isTainted(tr.frame.getStack(i)))
return false; return false;
return true; return true;
} }
@Override @Override
public void mergeResult(AnalysisResult r) { public void mergeResult(AnalysisResult r) {
TaintResult from = (TaintResult) r; TaintResult from = (TaintResult) r;
for (int i = 0; i < from.frame.getLocals(); i++) { for (int i = 0; i < from.frame.getLocals(); i++) {
TaintValue target = from.frame.getLocal(i); TaintValue target = from.frame.getLocal(i);
if (frame.getLocals() > i) { if (frame.getLocals() > i) {
TaintValue t1 = frame.getLocal(i); TaintValue t1 = frame.getLocal(i);
if (target != null) { if (target != null) {
if (t1 == null) { if (t1 == null) {
t1 = target.clone(); t1 = target.clone();
frame.setLocal(i, t1); frame.setLocal(i, t1);
} else { } else {
t1.merge(target); t1.merge(target);
} }
} }
} else { } else {
frame.setLocal(i, target.clone()); frame.setLocal(i, target.clone());
} }
} }
for (int i = 0; i < from.frame.getStackSize(); i++) { for (int i = 0; i < from.frame.getStackSize(); i++) {
TaintValue target = from.frame.getStack(i); TaintValue target = from.frame.getStack(i);
if (frame.getStackSize() > i) { if (frame.getStackSize() > i) {
TaintValue t1 = frame.getStack(i); TaintValue t1 = frame.getStack(i);
if (target != null) { if (target != null) {
if (t1 == null) { if (t1 == null) {
t1 = target.clone(); t1 = target.clone();
frame.setStack(i, t1); frame.setStack(i, t1);
} else { } else {
t1.merge(target); t1.merge(target);
} }
} }
t1.merge(from.frame.getStack(i)); t1.merge(from.frame.getStack(i));
} else { } else {
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);
} }
@Override @Override
public AnalysisResult clone() { public AnalysisResult clone() {
TaintResult ret = new TaintResult(); TaintResult ret = new TaintResult();
ret.frame = new Frame<>(frame); ret.frame = new Frame<>(frame);
for (int i = 0; i < ret.frame.getLocals(); i++) { for (int i = 0; i < ret.frame.getLocals(); i++) {
TaintValue t = ret.frame.getLocal(i); TaintValue t = ret.frame.getLocal(i);
if (t != null) if (t != null)
ret.frame.setLocal(i, t.clone()); ret.frame.setLocal(i, t.clone());
} }
for (int i = 0; i < ret.frame.getStackSize(); i++) { for (int i = 0; i < ret.frame.getStackSize(); i++) {
TaintValue t = ret.frame.getStack(i); TaintValue t = ret.frame.getStack(i);
if (t != null) if (t != null)
ret.frame.setStack(i, t.clone()); ret.frame.setStack(i, t.clone());
} }
ret.ret = this.ret.clone(); ret.ret = this.ret.clone();
return ret; return ret;
} }
} }

View File

@@ -3,52 +3,52 @@ package org.bdware.analysis.taint;
import org.objectweb.asm.tree.analysis.Value; import org.objectweb.asm.tree.analysis.Value;
public class TaintValue implements Value { public class TaintValue implements Value {
public int size; public int size;
// public boolean isTainted; // public boolean isTainted;
public long isTainted; public long isTainted;
public TaintValue(int size) { public TaintValue(int size) {
this.size = size; this.size = size;
isTainted = 0L; isTainted = 0L;
} }
public TaintValue(int size, long isTainted) { public TaintValue(int size, long isTainted) {
this.size = size; this.size = size;
this.isTainted = isTainted; this.isTainted = isTainted;
} }
@Override @Override
public int getSize() { public int getSize() {
return size; return size;
} }
@Override @Override
public String toString() { public String toString() {
String s = Long.toBinaryString(isTainted); String s = Long.toBinaryString(isTainted);
char[] c = s.toCharArray(); char[] c = s.toCharArray();
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
for (int i = 0; i < c.length; i++) { for (int i = 0; i < c.length; i++) {
if (c[i] == '1') if (c[i] == '1')
buf.append("1/"); buf.append("1/");
else else
buf.append("0/"); buf.append("0/");
} }
buf.append("--"); buf.append("--");
return buf.toString(); return buf.toString();
} }
public TaintValue clone() { public TaintValue clone() {
TaintValue ret = new TaintValue(size); TaintValue ret = new TaintValue(size);
ret.isTainted = isTainted; ret.isTainted = isTainted;
return ret; return ret;
} }
public String toReadableTaint() { public String toReadableTaint() {
return TaintResult.interpreter.taintBits.parse(isTainted); return TaintResult.interpreter.taintBits.parse(isTainted);
} }
public void merge(TaintValue target) { public void merge(TaintValue target) {
if (target != null) if (target != null)
isTainted |= target.isTainted; isTainted |= target.isTainted;
} }
} }

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,267 +35,344 @@ 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.
*/ */
private final ClassWriter cw; private final ClassWriter cw;
/** /**
* The number of values in this annotation. * The number of values in this annotation.
*/ */
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;
/** /**
* Next annotation writer. This field is used to store annotation lists. * Next annotation writer. This field is used to store annotation lists.
*/ */
AnnotationWriter next; AnnotationWriter next;
/** /**
* Previous annotation writer. This field is used to store annotation lists. * Previous annotation writer. This field is used to store annotation lists.
*/ */
AnnotationWriter prev; AnnotationWriter prev;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Constructor // Constructor
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* 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.
AnnotationWriter(final ClassWriter cw, final boolean named, final ByteVector bv, * @param parent
final ByteVector parent, final int offset) { * where the number of annotation values must be stored.
super(Opcodes.ASM4); * @param offset
this.cw = cw; * where in <tt>parent</tt> the number of annotation values must
this.named = named; * be stored.
this.bv = bv; */
this.parent = parent; AnnotationWriter(final ClassWriter cw, final boolean named,
this.offset = offset; final ByteVector bv, final ByteVector parent, final int offset)
} {
super(Opcodes.ASM4);
this.cw = cw;
this.named = named;
this.bv = bv;
this.parent = parent;
this.offset = offset;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Implementation of the AnnotationVisitor abstract class // Implementation of the AnnotationVisitor abstract class
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public void visit(final String name, final Object value) { public void visit(final String name, final Object value)
++size; {
if (named) { ++size;
bv.putShort(cw.newUTF8(name)); if (named)
} {
if (value instanceof String) { bv.putShort(cw.newUTF8(name));
bv.put12('s', cw.newUTF8((String) value)); }
} else if (value instanceof Byte) { if (value instanceof String)
bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index); {
} else if (value instanceof Boolean) { bv.put12('s', cw.newUTF8((String) value));
int v = ((Boolean) value).booleanValue() ? 1 : 0; }
bv.put12('Z', cw.newInteger(v).index); else if (value instanceof Byte)
} else if (value instanceof Character) { {
bv.put12('C', cw.newInteger(((Character) value).charValue()).index); bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
} else if (value instanceof Short) { }
bv.put12('S', cw.newInteger(((Short) value).shortValue()).index); else if (value instanceof Boolean)
} else if (value instanceof Type) { {
bv.put12('c', cw.newUTF8(((Type) value).getDescriptor())); int v = ((Boolean) value).booleanValue() ? 1 : 0;
} else if (value instanceof byte[]) { bv.put12('Z', cw.newInteger(v).index);
byte[] v = (byte[]) value; }
bv.put12('[', v.length); else if (value instanceof Character)
for (int i = 0; i < v.length; i++) { {
bv.put12('B', cw.newInteger(v[i]).index); bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
} }
} else if (value instanceof boolean[]) { else if (value instanceof Short)
boolean[] v = (boolean[]) value; {
bv.put12('[', v.length); bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
for (int i = 0; i < v.length; i++) { }
bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index); else if (value instanceof Type)
} {
} else if (value instanceof short[]) { bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
short[] v = (short[]) value; }
bv.put12('[', v.length); else if (value instanceof byte[])
for (int i = 0; i < v.length; i++) { {
bv.put12('S', cw.newInteger(v[i]).index); byte[] v = (byte[]) value;
} bv.put12('[', v.length);
} else if (value instanceof char[]) { for (int i = 0; i < v.length; i++)
char[] v = (char[]) value; {
bv.put12('[', v.length); bv.put12('B', cw.newInteger(v[i]).index);
for (int i = 0; i < v.length; i++) { }
bv.put12('C', cw.newInteger(v[i]).index); }
} else if (value instanceof boolean[])
} else if (value instanceof int[]) { {
int[] v = (int[]) 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('I', cw.newInteger(v[i]).index); {
} bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
} else if (value instanceof long[]) { }
long[] v = (long[]) value; }
bv.put12('[', v.length); else if (value instanceof short[])
for (int i = 0; i < v.length; i++) { {
bv.put12('J', cw.newLong(v[i]).index); short[] v = (short[]) value;
} bv.put12('[', v.length);
} else if (value instanceof float[]) { for (int i = 0; i < v.length; i++)
float[] v = (float[]) value; {
bv.put12('[', v.length); bv.put12('S', cw.newInteger(v[i]).index);
for (int i = 0; i < v.length; i++) { }
bv.put12('F', cw.newFloat(v[i]).index); }
} else if (value instanceof char[])
} else if (value instanceof double[]) { {
double[] v = (double[]) 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('D', cw.newDouble(v[i]).index); {
} bv.put12('C', cw.newInteger(v[i]).index);
} else { }
Item i = cw.newConstItem(value); }
bv.put12(".s.IFJDCS".charAt(i.type), i.index); else if (value instanceof int[])
} {
} int[] v = (int[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++)
{
bv.put12('I', cw.newInteger(v[i]).index);
}
}
else if (value instanceof long[])
{
long[] v = (long[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++)
{
bv.put12('J', cw.newLong(v[i]).index);
}
}
else if (value instanceof float[])
{
float[] v = (float[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++)
{
bv.put12('F', cw.newFloat(v[i]).index);
}
}
else if (value instanceof double[])
{
double[] v = (double[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++)
{
bv.put12('D', cw.newDouble(v[i]).index);
}
}
else
{
Item i = cw.newConstItem(value);
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,
++size; final String value)
// TODO add by chq! &&name!=null; {
if (named && name != null) { ++size;
bv.putShort(cw.newUTF8(name)); // TODO add by chq! &&name!=null;
} if (named && name != null)
bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value)); {
} bv.putShort(cw.newUTF8(name));
}
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,
++size; final String desc)
if (named) { {
bv.putShort(cw.newUTF8(name)); ++size;
} if (named)
// write tag and type, and reserve space for values count {
bv.put12('@', cw.newUTF8(desc)).putShort(0); bv.putShort(cw.newUTF8(name));
return new AnnotationWriter(cw, true, bv, bv, bv.length - 2); }
} // write tag and type, and reserve space for values count
bv.put12('@', cw.newUTF8(desc)).putShort(0);
return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
}
@Override @Override
public AnnotationVisitor visitArray(final String name) { public AnnotationVisitor visitArray(final String name)
++size; {
if (named) { ++size;
bv.putShort(cw.newUTF8(name)); if (named)
} {
// write tag, and reserve space for array size bv.putShort(cw.newUTF8(name));
bv.put12('[', 0); }
return new AnnotationWriter(cw, false, bv, bv, bv.length - 2); // write tag, and reserve space for array size
} bv.put12('[', 0);
return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
}
@Override @Override
public void visitEnd() { public void visitEnd()
if (parent != null) { {
byte[] data = parent.data; if (parent != null)
data[offset] = (byte) (size >>> 8); {
data[offset + 1] = (byte) size; byte[] data = parent.data;
} data[offset] = (byte) (size >>> 8);
} data[offset + 1] = (byte) size;
}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Utility methods // Utility methods
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the size of this annotation writer list. * Returns the size of this annotation writer list.
* *
* @return the size of this annotation writer list. * @return the size of this annotation writer list.
*/ */
int getSize() { int getSize()
int size = 0; {
AnnotationWriter aw = this; int size = 0;
while (aw != null) { AnnotationWriter aw = this;
size += aw.bv.length; while (aw != null)
aw = aw.next; {
} size += aw.bv.length;
return size; aw = aw.next;
} }
return size;
}
/** /**
* 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
void put(final ByteVector out) { * where the annotations must be put.
int n = 0; */
int size = 2; void put(final ByteVector out)
AnnotationWriter aw = this; {
AnnotationWriter last = null; int n = 0;
while (aw != null) { int size = 2;
++n; AnnotationWriter aw = this;
size += aw.bv.length; AnnotationWriter last = null;
aw.visitEnd(); // in case user forgot to call visitEnd while (aw != null)
aw.prev = last; {
last = aw; ++n;
aw = aw.next; size += aw.bv.length;
} aw.visitEnd(); // in case user forgot to call visitEnd
out.putInt(size); aw.prev = last;
out.putShort(n); last = aw;
aw = last; aw = aw.next;
while (aw != null) { }
out.putByteArray(aw.bv.data, 0, aw.bv.length); out.putInt(size);
aw = aw.prev; out.putShort(n);
} aw = last;
} while (aw != null)
{
out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev;
}
}
/** /**
* 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.
static void put(final AnnotationWriter[] panns, final int off, final ByteVector out) { * @param out
int size = 1 + 2 * (panns.length - off); * where the annotations must be put.
for (int i = off; i < panns.length; ++i) { */
size += panns[i] == null ? 0 : panns[i].getSize(); static void put(final AnnotationWriter[] panns, final int off,
} final ByteVector out)
out.putInt(size).putByte(panns.length - off); {
for (int i = off; i < panns.length; ++i) { int size = 1 + 2 * (panns.length - off);
AnnotationWriter aw = panns[i]; for (int i = off; i < panns.length; ++i)
AnnotationWriter last = null; {
int n = 0; size += panns[i] == null ? 0 : panns[i].getSize();
while (aw != null) { }
++n; out.putInt(size).putByte(panns.length - off);
aw.visitEnd(); // in case user forgot to call visitEnd for (int i = off; i < panns.length; ++i)
aw.prev = last; {
last = aw; AnnotationWriter aw = panns[i];
aw = aw.next; AnnotationWriter last = null;
} int n = 0;
out.putShort(n); while (aw != null)
aw = last; {
while (aw != null) { ++n;
out.putByteArray(aw.bv.data, 0, aw.bv.length); aw.visitEnd(); // in case user forgot to call visitEnd
aw = aw.prev; aw.prev = last;
} last = aw;
} aw = aw.next;
} }
out.putShort(n);
aw = last;
while (aw != null)
{
out.putByteArray(aw.bv.data, 0, aw.bv.length);
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
* <tt>null</tt>, but only for the {@link Object} class. * the signature of this class. May be <tt>null</tt> if the class
* @param interfaces the internal names of the class's interfaces (see * is not a generic one, and does not extend or implement generic
* {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>. * 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.
* @param interfaces
* 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
* <tt>null</tt>. * the name of the source file from which the class was compiled.
* @param debug additional debug information to compute the correspondance between source and * May be <tt>null</tt>.
* compiled elements of the class. 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>.
*/ */
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;

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;
@@ -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},
* handle. * {@link Opcodes#H_INVOKESPECIAL},
* @param name the name of the field or method designated by this handle. * {@link Opcodes#H_NEWINVOKESPECIAL} or
* @param desc the descriptor of the field or method designated by this handle. * {@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.
*/ */
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,60 +192,72 @@ 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;
this.strVal3 = strVal3; this.strVal3 = strVal3;
switch (type) { switch (type) {
case ClassWriter.UTF8: case ClassWriter.UTF8:
case ClassWriter.STR: case ClassWriter.STR:
case ClassWriter.CLASS: case ClassWriter.CLASS:
case ClassWriter.MTYPE: case ClassWriter.MTYPE:
case ClassWriter.TYPE_NORMAL: case ClassWriter.TYPE_NORMAL:
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()
return; * strVal2.hashCode());
} return;
// ClassWriter.FIELD: }
// ClassWriter.METH: // ClassWriter.FIELD:
// ClassWriter.IMETH: // ClassWriter.METH:
// ClassWriter.HANDLE_BASE + 1..9 // ClassWriter.IMETH:
default: // ClassWriter.HANDLE_BASE + 1..9
hashCode = 0x7FFFFFFF default:
& (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode()); hashCode = 0x7FFFFFFF & (type + strVal1.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,42 +266,45 @@ 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) {
case ClassWriter.UTF8: case ClassWriter.UTF8:
case ClassWriter.STR: case ClassWriter.STR:
case ClassWriter.CLASS: case ClassWriter.CLASS:
case ClassWriter.MTYPE: case ClassWriter.MTYPE:
case ClassWriter.TYPE_NORMAL: case ClassWriter.TYPE_NORMAL:
return i.strVal1.equals(strVal1); return i.strVal1.equals(strVal1);
case ClassWriter.TYPE_MERGED: case ClassWriter.TYPE_MERGED:
case ClassWriter.LONG: case ClassWriter.LONG:
case ClassWriter.DOUBLE: case ClassWriter.DOUBLE:
return i.longVal == longVal; return i.longVal == longVal;
case ClassWriter.INT: case ClassWriter.INT:
case ClassWriter.FLOAT: case ClassWriter.FLOAT:
return i.intVal == intVal; return i.intVal == intVal;
case ClassWriter.TYPE_UNINIT: case ClassWriter.TYPE_UNINIT:
return i.intVal == intVal && i.strVal1.equals(strVal1); return i.intVal == intVal && i.strVal1.equals(strVal1);
case ClassWriter.NAME_TYPE: case ClassWriter.NAME_TYPE:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
case ClassWriter.INDY: { case ClassWriter.INDY: {
return i.longVal == longVal && i.strVal1.equals(strVal1) return i.longVal == longVal && i.strVal1.equals(strVal1)
&& i.strVal2.equals(strVal2); && i.strVal2.equals(strVal2);
} }
// case ClassWriter.FIELD: // case ClassWriter.FIELD:
// case ClassWriter.METH: // case ClassWriter.METH:
// case ClassWriter.IMETH: // case ClassWriter.IMETH:
// case ClassWriter.HANDLE_BASE + 1..9 // case ClassWriter.HANDLE_BASE + 1..9
default: default:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
&& i.strVal3.equals(strVal3); && i.strVal3.equals(strVal3);
} }
} }

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
* been created by the given code writer. * 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.
*/ */
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
* compressed frames. * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
* @param nLocal the number of local variables in the visited frame. * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
* @param local the local variable types in this frame. This array must not be modified. * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
* Primitive types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, * compressed frames.
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, * @param nLocal
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} * the number of local variables in the visited frame.
* (long and double are represented by a single element). Reference types are represented * @param local
* by String objects (representing internal names), and uninitialized types by Label * the local variable types in this frame. This array must not be
* objects (this label designates the NEW instruction that created this uninitialized * modified. Primitive types are represented by
* value). * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
* @param nStack the number of operand stack elements in the visited frame. * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* @param stack the operand stack types in this frame. This array must not be modified. Its * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
* content has the same format as the "local" array. * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
* @throws IllegalStateException if a frame is visited just after another one, without any * represented by a single element). Reference types are
* instruction between the two (unless this frame is a Opcodes#F_SAME frame, in which * represented by String objects (representing internal names),
* case it is silently ignored). * and uninitialized types by Label objects (this label
* designates the NEW instruction that created this uninitialized
* value).
* @param nStack
* the number of operand stack elements in the visited frame.
* @param stack
* the operand stack types in this frame. This array must not be
* modified. Its content has the same format as the "local"
* 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
* visitor (by the {@link #visitLabel visitLabel} method). * 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).
*/ */
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,11 +619,14 @@ 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
* visitor (by the {@link #visitLabel visitLabel} method). * 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).
*/ */
public void visitLineNumber(int line, Label start) { public void visitLineNumber(int line, Label start) {
if (mv != null) { if (mv != null) {
@@ -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,55 +433,58 @@ 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) {
int len; int len;
switch (buf[off]) { switch (buf[off]) {
case 'V': case 'V':
return VOID_TYPE; return VOID_TYPE;
case 'Z': case 'Z':
return BOOLEAN_TYPE; return BOOLEAN_TYPE;
case 'C': case 'C':
return CHAR_TYPE; return CHAR_TYPE;
case 'B': case 'B':
return BYTE_TYPE; return BYTE_TYPE;
case 'S': case 'S':
return SHORT_TYPE; return SHORT_TYPE;
case 'I': case 'I':
return INT_TYPE; return INT_TYPE;
case 'F': case 'F':
return FLOAT_TYPE; return FLOAT_TYPE;
case 'J': case 'J':
return LONG_TYPE; return LONG_TYPE;
case 'D': case 'D':
return DOUBLE_TYPE; return DOUBLE_TYPE;
case '[': case '[':
len = 1; len = 1;
while (buf[off + len] == '[') { while (buf[off + len] == '[') {
++len; ++len;
} }
if (buf[off + len] == 'L') { if (buf[off + len] == 'L') {
++len; ++len;
while (buf[off + len] != ';') {
++len;
}
}
return new Type(ARRAY, buf, off, len + 1);
case 'L':
len = 1;
while (buf[off + len] != ';') { while (buf[off + len] != ';') {
++len; ++len;
} }
return new Type(OBJECT, buf, off + 1, len - 1); }
return new Type(ARRAY, buf, off, len + 1);
case 'L':
len = 1;
while (buf[off + len] != ';') {
++len;
}
return new Type(OBJECT, buf, off + 1, len - 1);
// case '(': // case '(':
default: default:
return new Type(METHOD, buf, off, buf.length - off); return new Type(METHOD, buf, off, buf.length - 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,48 +530,49 @@ 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.
*/ */
public String getClassName() { public String getClassName() {
switch (sort) { switch (sort) {
case VOID: case VOID:
return "void"; return "void";
case BOOLEAN: case BOOLEAN:
return "boolean"; return "boolean";
case CHAR: case CHAR:
return "char"; return "char";
case BYTE: case BYTE:
return "byte"; return "byte";
case SHORT: case SHORT:
return "short"; return "short";
case INT: case INT:
return "int"; return "int";
case FLOAT: case FLOAT:
return "float"; return "float";
case LONG: case LONG:
return "long"; return "long";
case DOUBLE: case DOUBLE:
return "double"; return "double";
case ARRAY: case ARRAY:
StringBuffer b = new StringBuffer(getElementType().getClassName()); StringBuffer b = new StringBuffer(getElementType().getClassName());
for (int i = getDimensions(); i > 0; --i) { for (int i = getDimensions(); i > 0; --i) {
b.append("[]"); b.append("[]");
} }
return b.toString(); return b.toString();
case OBJECT: case OBJECT:
return new String(buf, off, len).replace('/', '.'); return new String(buf, off, len).replace('/', '.');
default: default:
return null; return null;
} }
} }
/** /**
* 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;
@@ -117,178 +130,178 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
if (constructor) { if (constructor) {
int s; int s;
switch (opcode) { switch (opcode) {
case RETURN: // empty stack case RETURN: // empty stack
onMethodExit(opcode); onMethodExit(opcode);
break; break;
case IRETURN: // 1 before n/a after case IRETURN: // 1 before n/a after
case FRETURN: // 1 before n/a after case FRETURN: // 1 before n/a after
case ARETURN: // 1 before n/a after case ARETURN: // 1 before n/a after
case ATHROW: // 1 before n/a after case ATHROW: // 1 before n/a after
popValue(); popValue();
onMethodExit(opcode); onMethodExit(opcode);
break; break;
case LRETURN: // 2 before n/a after case LRETURN: // 2 before n/a after
case DRETURN: // 2 before n/a after case DRETURN: // 2 before n/a after
popValue(); popValue();
popValue(); popValue();
onMethodExit(opcode); onMethodExit(opcode);
break; break;
case NOP: case NOP:
case LALOAD: // remove 2 add 2 case LALOAD: // remove 2 add 2
case DALOAD: // remove 2 add 2 case DALOAD: // remove 2 add 2
case LNEG: case LNEG:
case DNEG: case DNEG:
case FNEG: case FNEG:
case INEG: case INEG:
case L2D: case L2D:
case D2L: case D2L:
case F2I: case F2I:
case I2B: case I2B:
case I2C: case I2C:
case I2S: case I2S:
case I2F: case I2F:
case ARRAYLENGTH: case ARRAYLENGTH:
break; break;
case ACONST_NULL: case ACONST_NULL:
case ICONST_M1: case ICONST_M1:
case ICONST_0: case ICONST_0:
case ICONST_1: case ICONST_1:
case ICONST_2: case ICONST_2:
case ICONST_3: case ICONST_3:
case ICONST_4: case ICONST_4:
case ICONST_5: case ICONST_5:
case FCONST_0: case FCONST_0:
case FCONST_1: case FCONST_1:
case FCONST_2: case FCONST_2:
case F2L: // 1 before 2 after case F2L: // 1 before 2 after
case F2D: case F2D:
case I2L: case I2L:
case I2D: case I2D:
pushValue(OTHER); pushValue(OTHER);
break; break;
case LCONST_0: case LCONST_0:
case LCONST_1: case LCONST_1:
case DCONST_0: case DCONST_0:
case DCONST_1: case DCONST_1:
pushValue(OTHER); pushValue(OTHER);
pushValue(OTHER); pushValue(OTHER);
break; break;
case IALOAD: // remove 2 add 1 case IALOAD: // remove 2 add 1
case FALOAD: // remove 2 add 1 case FALOAD: // remove 2 add 1
case AALOAD: // remove 2 add 1 case AALOAD: // remove 2 add 1
case BALOAD: // remove 2 add 1 case BALOAD: // remove 2 add 1
case CALOAD: // remove 2 add 1 case CALOAD: // remove 2 add 1
case SALOAD: // remove 2 add 1 case SALOAD: // remove 2 add 1
case POP: case POP:
case IADD: case IADD:
case FADD: case FADD:
case ISUB: case ISUB:
case LSHL: // 3 before 2 after case LSHL: // 3 before 2 after
case LSHR: // 3 before 2 after case LSHR: // 3 before 2 after
case LUSHR: // 3 before 2 after case LUSHR: // 3 before 2 after
case L2I: // 2 before 1 after case L2I: // 2 before 1 after
case L2F: // 2 before 1 after case L2F: // 2 before 1 after
case D2I: // 2 before 1 after case D2I: // 2 before 1 after
case D2F: // 2 before 1 after case D2F: // 2 before 1 after
case FSUB: case FSUB:
case FMUL: case FMUL:
case FDIV: case FDIV:
case FREM: case FREM:
case FCMPL: // 2 before 1 after case FCMPL: // 2 before 1 after
case FCMPG: // 2 before 1 after case FCMPG: // 2 before 1 after
case IMUL: case IMUL:
case IDIV: case IDIV:
case IREM: case IREM:
case ISHL: case ISHL:
case ISHR: case ISHR:
case IUSHR: case IUSHR:
case IAND: case IAND:
case IOR: case IOR:
case IXOR: case IXOR:
case MONITORENTER: case MONITORENTER:
case MONITOREXIT: case MONITOREXIT:
popValue(); popValue();
break; break;
case POP2: case POP2:
case LSUB: case LSUB:
case LMUL: case LMUL:
case LDIV: case LDIV:
case LREM: case LREM:
case LADD: case LADD:
case LAND: case LAND:
case LOR: case LOR:
case LXOR: case LXOR:
case DADD: case DADD:
case DMUL: case DMUL:
case DSUB: case DSUB:
case DDIV: case DDIV:
case DREM: case DREM:
popValue(); popValue();
popValue(); popValue();
break; break;
case IASTORE: case IASTORE:
case FASTORE: case FASTORE:
case AASTORE: case AASTORE:
case BASTORE: case BASTORE:
case CASTORE: case CASTORE:
case SASTORE: case SASTORE:
case LCMP: // 4 before 1 after case LCMP: // 4 before 1 after
case DCMPL: case DCMPL:
case DCMPG: case DCMPG:
popValue(); popValue();
popValue(); popValue();
popValue(); popValue();
break; break;
case LASTORE: case LASTORE:
case DASTORE: case DASTORE:
popValue(); popValue();
popValue(); popValue();
popValue(); popValue();
popValue(); popValue();
break; break;
case DUP: case DUP:
pushValue(peekValue()); pushValue(peekValue());
break; break;
case DUP_X1: case DUP_X1:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 2, stackFrame.get(s - 1)); stackFrame.add(s - 2, stackFrame.get(s - 1));
break; break;
case DUP_X2: case DUP_X2:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 3, stackFrame.get(s - 1)); stackFrame.add(s - 3, stackFrame.get(s - 1));
break; break;
case DUP2: case DUP2:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 2, stackFrame.get(s - 1)); stackFrame.add(s - 2, stackFrame.get(s - 1));
stackFrame.add(s - 2, stackFrame.get(s - 1)); stackFrame.add(s - 2, stackFrame.get(s - 1));
break; break;
case DUP2_X1: case DUP2_X1:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 3, stackFrame.get(s - 1)); stackFrame.add(s - 3, stackFrame.get(s - 1));
stackFrame.add(s - 3, stackFrame.get(s - 1)); stackFrame.add(s - 3, stackFrame.get(s - 1));
break; break;
case DUP2_X2: case DUP2_X2:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 4, stackFrame.get(s - 1)); stackFrame.add(s - 4, stackFrame.get(s - 1));
stackFrame.add(s - 4, stackFrame.get(s - 1)); stackFrame.add(s - 4, stackFrame.get(s - 1));
break; break;
case SWAP: case SWAP:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 2, stackFrame.get(s - 1)); stackFrame.add(s - 2, stackFrame.get(s - 1));
stackFrame.remove(s); stackFrame.remove(s);
break; break;
} }
} else { } else {
switch (opcode) { switch (opcode) {
case RETURN: case RETURN:
case IRETURN: case IRETURN:
case FRETURN: case FRETURN:
case ARETURN: case ARETURN:
case LRETURN: case LRETURN:
case DRETURN: case DRETURN:
case ATHROW: case ATHROW:
onMethodExit(opcode); onMethodExit(opcode);
break; break;
} }
} }
mv.visitInsn(opcode); mv.visitInsn(opcode);
@@ -299,64 +312,64 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
super.visitVarInsn(opcode, var); super.visitVarInsn(opcode, var);
if (constructor) { if (constructor) {
switch (opcode) { switch (opcode) {
case ILOAD: case ILOAD:
case FLOAD: case FLOAD:
pushValue(OTHER); pushValue(OTHER);
break; break;
case LLOAD: case LLOAD:
case DLOAD: case DLOAD:
pushValue(OTHER); pushValue(OTHER);
pushValue(OTHER); pushValue(OTHER);
break; break;
case ALOAD: case ALOAD:
pushValue(var == 0 ? THIS : OTHER); pushValue(var == 0 ? THIS : OTHER);
break; break;
case ASTORE: case ASTORE:
case ISTORE: case ISTORE:
case FSTORE: case FSTORE:
popValue(); popValue();
break; break;
case LSTORE: case LSTORE:
case DSTORE: case DSTORE:
popValue(); popValue();
popValue(); popValue();
break; break;
} }
} }
} }
@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);
boolean longOrDouble = c == 'J' || c == 'D'; boolean longOrDouble = c == 'J' || c == 'D';
switch (opcode) { switch (opcode) {
case GETSTATIC: case GETSTATIC:
pushValue(OTHER);
if (longOrDouble) {
pushValue(OTHER); pushValue(OTHER);
if (longOrDouble) { }
pushValue(OTHER); break;
} case PUTSTATIC:
break; popValue();
case PUTSTATIC: if (longOrDouble) {
popValue(); popValue();
if (longOrDouble) { }
popValue(); break;
} case PUTFIELD:
break; popValue();
case PUTFIELD: if (longOrDouble) {
popValue(); popValue();
if (longOrDouble) { popValue();
popValue(); }
popValue(); break;
} // case GETFIELD:
break; default:
// case GETFIELD: if (longOrDouble) {
default: pushValue(OTHER);
if (longOrDouble) { }
pushValue(OTHER);
}
} }
} }
} }
@@ -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);
@@ -413,22 +426,22 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
} }
switch (opcode) { switch (opcode) {
// case INVOKESTATIC: // case INVOKESTATIC:
// break; // break;
case INVOKEINTERFACE: case INVOKEINTERFACE:
case INVOKEVIRTUAL: case INVOKEVIRTUAL:
popValue(); // objectref popValue(); // objectref
break; break;
case INVOKESPECIAL: case INVOKESPECIAL:
Object type = popValue(); // objectref Object type = popValue(); // objectref
if (type == THIS && !superInitialized) { if (type == THIS && !superInitialized) {
onMethodEnter(); onMethodEnter();
superInitialized = true; superInitialized = true;
// once super has been initialized it is no longer // once super has been initialized it is no longer
// necessary to keep track of stack state // necessary to keep track of stack state
constructor = false; constructor = false;
} }
break; break;
} }
Type returnType = Type.getReturnType(desc); Type returnType = Type.getReturnType(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);
@@ -468,37 +482,38 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
mv.visitJumpInsn(opcode, label); mv.visitJumpInsn(opcode, label);
if (constructor) { if (constructor) {
switch (opcode) { switch (opcode) {
case IFEQ: case IFEQ:
case IFNE: case IFNE:
case IFLT: case IFLT:
case IFGE: case IFGE:
case IFGT: case IFGT:
case IFLE: case IFLE:
case IFNULL: case IFNULL:
case IFNONNULL: case IFNONNULL:
popValue(); popValue();
break; break;
case IF_ICMPEQ: case IF_ICMPEQ:
case IF_ICMPNE: case IF_ICMPNE:
case IF_ICMPLT: case IF_ICMPLT:
case IF_ICMPGE: case IF_ICMPGE:
case IF_ICMPGT: case IF_ICMPGT:
case IF_ICMPLE: case IF_ICMPLE:
case IF_ACMPEQ: case IF_ACMPEQ:
case IF_ACMPNE: case IF_ACMPNE:
popValue(); popValue();
popValue(); popValue();
break; break;
case JSR: case JSR:
pushValue(OTHER); pushValue(OTHER);
break; break;
} }
addBranch(label); addBranch(label);
} }
} }
@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
} }

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;
@@ -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

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;
@@ -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;
@@ -289,22 +331,22 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
// check to see if this opcode falls through to the next instruction // check to see if this opcode falls through to the next instruction
// or not; if not, return. // or not; if not, return.
switch (instructions.get(index).getOpcode()) { switch (instructions.get(index).getOpcode()) {
case GOTO: case GOTO:
case RET: case RET:
case TABLESWITCH: case TABLESWITCH:
case LOOKUPSWITCH: case LOOKUPSWITCH:
case IRETURN: case IRETURN:
case LRETURN: case LRETURN:
case FRETURN: case FRETURN:
case DRETURN: case DRETURN:
case ARETURN: case ARETURN:
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;
} }
// Use tail recursion here in the form of an outer while loop to // Use tail recursion here in the form of an outer while loop to
@@ -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;
@@ -105,32 +123,32 @@ public class LocalVariablesSorter extends MethodVisitor {
public void visitVarInsn(final int opcode, final int var) { public void visitVarInsn(final int opcode, final int var) {
Type type; Type type;
switch (opcode) { switch (opcode) {
case Opcodes.LLOAD: case Opcodes.LLOAD:
case Opcodes.LSTORE: case Opcodes.LSTORE:
type = Type.LONG_TYPE; type = Type.LONG_TYPE;
break; break;
case Opcodes.DLOAD: case Opcodes.DLOAD:
case Opcodes.DSTORE: case Opcodes.DSTORE:
type = Type.DOUBLE_TYPE; type = Type.DOUBLE_TYPE;
break; break;
case Opcodes.FLOAD: case Opcodes.FLOAD:
case Opcodes.FSTORE: case Opcodes.FSTORE:
type = Type.FLOAT_TYPE; type = Type.FLOAT_TYPE;
break; break;
case Opcodes.ILOAD: case Opcodes.ILOAD:
case Opcodes.ISTORE: case Opcodes.ISTORE:
type = Type.INT_TYPE; type = Type.INT_TYPE;
break; break;
default: default:
// case Opcodes.ALOAD: // case Opcodes.ALOAD:
// case Opcodes.ASTORE: // case Opcodes.ASTORE:
// case RET: // case RET:
type = OBJECT_TYPE; type = OBJECT_TYPE;
break; break;
} }
mv.visitVarInsn(opcode, remap(var, type)); mv.visitVarInsn(opcode, remap(var, type));
} }
@@ -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,35 +245,36 @@ 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) {
Object t; Object t;
switch (type.getSort()) { switch (type.getSort()) {
case Type.BOOLEAN: case Type.BOOLEAN:
case Type.CHAR: case Type.CHAR:
case Type.BYTE: case Type.BYTE:
case Type.SHORT: case Type.SHORT:
case Type.INT: case Type.INT:
t = Opcodes.INTEGER; t = Opcodes.INTEGER;
break; break;
case Type.FLOAT: case Type.FLOAT:
t = Opcodes.FLOAT; t = Opcodes.FLOAT;
break; break;
case Type.LONG: case Type.LONG:
t = Opcodes.LONG; t = Opcodes.LONG;
break; break;
case Type.DOUBLE: case Type.DOUBLE:
t = Opcodes.DOUBLE; t = Opcodes.DOUBLE;
break; break;
case Type.ARRAY: case Type.ARRAY:
t = type.getDescriptor(); t = type.getDescriptor();
break; break;
// case Type.OBJECT: // case Type.OBJECT:
default: default:
t = type.getInternalName(); t = type.getInternalName();
break; break;
} }
int local = newLocalMapping(type); int local = newLocalMapping(type);
setLocalType(local, type); setLocalType(local, 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>
@@ -44,34 +53,34 @@ public abstract class Remapper {
public String mapDesc(String desc) { public String mapDesc(String desc) {
Type t = Type.getType(desc); Type t = Type.getType(desc);
switch (t.getSort()) { switch (t.getSort()) {
case Type.ARRAY: case Type.ARRAY:
String s = mapDesc(t.getElementType().getDescriptor()); String s = mapDesc(t.getElementType().getDescriptor());
for (int i = 0; i < t.getDimensions(); ++i) { for (int i = 0; i < t.getDimensions(); ++i) {
s = '[' + s; s = '[' + s;
} }
return s; return s;
case Type.OBJECT: case Type.OBJECT:
String newType = map(t.getInternalName()); String newType = map(t.getInternalName());
if (newType != null) { if (newType != null) {
return 'L' + newType + ';'; return 'L' + newType + ';';
} }
} }
return desc; return desc;
} }
private Type mapType(Type t) { private Type mapType(Type t) {
switch (t.getSort()) { switch (t.getSort()) {
case Type.ARRAY: case Type.ARRAY:
String s = mapDesc(t.getElementType().getDescriptor()); String s = mapDesc(t.getElementType().getDescriptor());
for (int i = 0; i < t.getDimensions(); ++i) { for (int i = 0; i < t.getDimensions(); ++i) {
s = '[' + s; s = '[' + s;
} }
return Type.getType(s); return Type.getType(s);
case Type.OBJECT: case Type.OBJECT:
s = map(t.getInternalName()); s = map(t.getInternalName());
return s != null ? Type.getObjectType(s) : t; return s != null ? Type.getObjectType(s) : t;
case Type.METHOD: case Type.METHOD:
return Type.getMethodType(mapMethodDesc(t.getDescriptor())); return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
} }
return t; return t;
} }
@@ -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);
@@ -173,29 +185,31 @@ public class SerialVersionUIDAdder extends ClassVisitor {
* Sorts the items in the collection and writes it to the data output stream * Sorts the items in the collection and writes it to the data output stream
* *
* @param itemCollection collection of items * @param itemCollection collection of items
* @param dos a <code>DataOutputStream</code> value * @param dos a <code>DataOutputStream</code> value
* @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,23 +46,28 @@ 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
* <i>FieldTypeSignature</i>. * A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or
* <i>FieldTypeSignature</i>.
*/ */
public SignatureReader(final String signature) { public SignatureReader(final String signature) {
this.signature = signature; this.signature = signature;
} }
/** /**
* 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,90 +133,96 @@ 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;
String name; String name;
switch (c = signature.charAt(pos++)) { switch (c = signature.charAt(pos++)) {
case 'Z': case 'Z':
case 'C': case 'C':
case 'B': case 'B':
case 'S': case 'S':
case 'I': case 'I':
case 'F': case 'F':
case 'J': case 'J':
case 'D': case 'D':
case 'V': case 'V':
v.visitBaseType(c); v.visitBaseType(c);
return pos; return pos;
case '[': case '[':
return parseType(signature, pos, v.visitArrayType()); return parseType(signature, pos, v.visitArrayType());
case 'T': case 'T':
end = signature.indexOf(';', pos); end = signature.indexOf(';', pos);
v.visitTypeVariable(signature.substring(pos, end)); v.visitTypeVariable(signature.substring(pos, end));
return end + 1; return end + 1;
default: // case 'L': default: // case 'L':
start = pos; start = pos;
visited = false; visited = false;
inner = false; inner = false;
for (;;) { for (;;) {
switch (c = signature.charAt(pos++)) { switch (c = signature.charAt(pos++)) {
case '.': case '.':
case ';': case ';':
if (!visited) { if (!visited) {
name = signature.substring(start, pos - 1); name = signature.substring(start, pos - 1);
if (inner) { if (inner) {
v.visitInnerClassType(name); v.visitInnerClassType(name);
} else { } else {
v.visitClassType(name); v.visitClassType(name);
} }
} }
if (c == ';') { if (c == ';') {
v.visitEnd(); v.visitEnd();
return pos; return pos;
} }
start = pos; start = pos;
visited = false; visited = false;
inner = true; inner = true;
break;
case '<':
name = signature.substring(start, pos - 1);
if (inner) {
v.visitInnerClassType(name);
} else {
v.visitClassType(name);
}
visited = true;
top: for (;;) {
switch (c = signature.charAt(pos)) {
case '>':
break top;
case '*':
++pos;
v.visitTypeArgument();
break; break;
case '+':
case '<': case '-':
name = signature.substring(start, pos - 1); pos = parseType(signature, pos + 1,
if (inner) { v.visitTypeArgument(c));
v.visitInnerClassType(name); break;
} else { default:
v.visitClassType(name); pos = parseType(signature, pos,
} v.visitTypeArgument('='));
visited = true; break;
top: for (;;) { }
switch (c = signature.charAt(pos)) {
case '>':
break top;
case '*':
++pos;
v.visitTypeArgument();
break;
case '+':
case '-':
pos = parseType(signature, pos + 1, v.visitTypeArgument(c));
break;
default:
pos = parseType(signature, pos, v.visitTypeArgument('='));
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,192 +35,247 @@ 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.
*/ */
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
public List<Object> values; * pair.
*/
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
public AnnotationNode(final String desc) { * the class descriptor of the annotation class.
this(Opcodes.ASM4, desc); */
} public AnnotationNode(final String 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
public AnnotationNode(final int api, final String desc) { * the class descriptor of the annotation class.
super(api); */
this.desc = desc; public AnnotationNode(final int api, final String desc)
} {
super(api);
this.desc = desc;
}
/** /**
* 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) { */
super(Opcodes.ASM4); AnnotationNode(final List<Object> values)
this.values = values; {
} super(Opcodes.ASM4);
this.values = values;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Implementation of the AnnotationVisitor abstract class // Implementation of the AnnotationVisitor abstract class
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public void visit(final String name, final Object value) { public void visit(final String name, final Object value)
if (values == null) { {
values = new ArrayList<Object>(this.desc != null ? 2 : 1); if (values == null)
} {
if (this.desc != null) { values = new ArrayList<Object>(this.desc != null ? 2 : 1);
values.add(name); }
} if (this.desc != null)
// else {
// { values.add(name);
// System.out.println("[AnnotationNode] desc is null!"); }
// values.add(""); // else
// } // {
values.add(value); // System.out.println("[AnnotationNode] desc is null!");
} // values.add("");
// }
values.add(value);
}
@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)
values = new ArrayList<Object>(this.desc != null ? 2 : 1); {
} if (values == null)
if (this.desc != null) { {
values.add(name); values = new ArrayList<Object>(this.desc != null ? 2 : 1);
} }
values.add(new String[] {desc, value}); if (this.desc != null)
} {
values.add(name);
}
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)
values = new ArrayList<Object>(this.desc != null ? 2 : 1); {
} if (values == null)
if (this.desc != null) { {
values.add(name); values = new ArrayList<Object>(this.desc != null ? 2 : 1);
} }
AnnotationNode annotation = new AnnotationNode(desc); if (this.desc != null)
values.add(annotation); {
return annotation; values.add(name);
} }
AnnotationNode annotation = new AnnotationNode(desc);
values.add(annotation);
return annotation;
}
@Override @Override
public AnnotationVisitor visitArray(final String name) { public AnnotationVisitor visitArray(final String name)
if (values == null) { {
values = new ArrayList<Object>(this.desc != null ? 2 : 1); if (values == null)
} {
if (this.desc != null) { values = new ArrayList<Object>(this.desc != null ? 2 : 1);
values.add(name); }
} if (this.desc != null)
List<Object> array = new ArrayList<Object>(); {
values.add(array); values.add(name);
return new AnnotationNode(array); }
} List<Object> array = new ArrayList<Object>();
values.add(array);
return new AnnotationNode(array);
}
@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
public void check(final int api) { * an ASM API version. Must be one of {@link Opcodes#ASM4}.
// nothing to do */
} public void check(final int api)
{
// 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) { */
if (av != null) { public void accept(final AnnotationVisitor av)
if (values != null) { {
for (int i = 0; i < values.size(); i += 2) { if (av != null)
if (values.get(i) == null) { {
System.out.println("[AnnotationNode] name is null!!!!!"); if (values != null)
// DelayLogger.logValue(values); {
System.out.flush(); for (int i = 0; i < values.size(); i += 2)
try { {
Thread.sleep(2000); if (values.get(i) == null)
} catch (InterruptedException e) { {
// TODO Auto-generated catch block System.out
e.printStackTrace(); .println("[AnnotationNode] name is null!!!!!");
} // DelayLogger.logValue(values);
} System.out.flush();
String name = (String) values.get(i); try
Object value = values.get(i + 1); {
accept(av, name, value); Thread.sleep(2000);
} }
} catch (InterruptedException e)
av.visitEnd(); {
} // TODO Auto-generated catch block
} e.printStackTrace();
}
}
String name = (String) values.get(i);
Object value = values.get(i + 1);
accept(av, name, value);
}
}
av.visitEnd();
}
}
/** /**
* 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.
static void accept(final AnnotationVisitor av, final String name, final Object value) { * @param value
if (av != null) { * the actual value.
if (value instanceof String[]) { */
String[] typeconst = (String[]) value; static void accept(final AnnotationVisitor av, final String name,
av.visitEnum(name, typeconst[0], typeconst[1]); final Object value)
} else if (value instanceof AnnotationNode) { {
AnnotationNode an = (AnnotationNode) value; if (av != null)
an.accept(av.visitAnnotation(name, an.desc)); {
} else if (value instanceof List) { if (value instanceof String[])
AnnotationVisitor v = av.visitArray(name); {
List<?> array = (List<?>) value; String[] typeconst = (String[]) value;
for (int j = 0; j < array.size(); ++j) { av.visitEnum(name, typeconst[0], typeconst[1]);
accept(v, null, array.get(j)); }
} else if (value instanceof AnnotationNode)
v.visitEnd(); {
} else { AnnotationNode an = (AnnotationNode) value;
av.visit(name, value); an.accept(av.visitAnnotation(name, an.desc));
} }
} else if (value instanceof List)
} {
AnnotationVisitor v = av.visitArray(name);
List<?> array = (List<?>) value;
for (int j = 0; j < array.size(); ++j)
{
accept(v, null, array.get(j));
}
v.visitEnd();
}
else
{
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,40 +84,48 @@ 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) {
case Opcodes.F_NEW: case Opcodes.F_NEW:
case Opcodes.F_FULL: case Opcodes.F_FULL:
this.local = asList(nLocal, local); this.local = asList(nLocal, local);
this.stack = asList(nStack, stack); this.stack = asList(nStack, stack);
break; break;
case Opcodes.F_APPEND: case Opcodes.F_APPEND:
this.local = asList(nLocal, local); this.local = asList(nLocal, local);
break; break;
case Opcodes.F_CHOP: case Opcodes.F_CHOP:
this.local = Arrays.asList(new Object[nLocal]); this.local = Arrays.asList(new Object[nLocal]);
break; break;
case Opcodes.F_SAME: case Opcodes.F_SAME:
break; break;
case Opcodes.F_SAME1: case Opcodes.F_SAME1:
this.stack = asList(1, stack); this.stack = asList(1, stack);
break; break;
} }
} }
@@ -118,27 +137,29 @@ 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(),
break; asArray(stack));
case Opcodes.F_APPEND: break;
mv.visitFrame(type, local.size(), asArray(local), 0, null); case Opcodes.F_APPEND:
break; mv.visitFrame(type, local.size(), asArray(local), 0, null);
case Opcodes.F_CHOP: break;
mv.visitFrame(type, local.size(), null, 0, null); case Opcodes.F_CHOP:
break; mv.visitFrame(type, local.size(), null, 0, null);
case Opcodes.F_SAME: break;
mv.visitFrame(type, 0, null, 0, null); case Opcodes.F_SAME:
break; mv.visitFrame(type, 0, null, 0, null);
case Opcodes.F_SAME1: break;
mv.visitFrame(type, 0, null, 1, asArray(stack)); case Opcodes.F_SAME1:
break; mv.visitFrame(type, 0, null, 1, asArray(stack));
break;
} }
} }

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;
@@ -331,31 +350,33 @@ public class Analyzer<V extends Value> implements Opcodes {
// if insn does not falls through to the next instruction, return. // if insn does not falls through to the next instruction, return.
switch (node.getOpcode()) { switch (node.getOpcode()) {
case GOTO: case GOTO:
case RET: case RET:
case TABLESWITCH: case TABLESWITCH:
case LOOKUPSWITCH: case LOOKUPSWITCH:
case IRETURN: case IRETURN:
case LRETURN: case LRETURN:
case FRETURN: case FRETURN:
case DRETURN: case DRETURN:
case ARETURN: case ARETURN:
case RETURN: case RETURN:
case ATHROW: case ATHROW:
return; return;
} }
insn++; insn++;
} }
} }
/** /**
* 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;
} }
} }

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