下面列出了org.objectweb.asm.Opcodes# IRETURN 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void addTraceReturn() {
InsnList il = this.mn.instructions;
Iterator<AbstractInsnNode> it = il.iterator();
while (it.hasNext()) {
AbstractInsnNode abstractInsnNode = it.next();
switch (abstractInsnNode.getOpcode()) {
case Opcodes.RETURN:
il.insertBefore(abstractInsnNode, getVoidReturnTraceInstructions());
break;
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.FRETURN:
case Opcodes.ARETURN:
case Opcodes.DRETURN:
il.insertBefore(abstractInsnNode, getReturnTraceInstructions());
}
}
}
/**
* value → ∅
*/
public void _return() {
Type returnType = method.methodDescriptor.returnType();
switch (returnType.getOpcode(Opcodes.IRETURN)) {
case Opcodes.IRETURN:
ireturn();
return;
case Opcodes.LRETURN:
lreturn();
return;
case Opcodes.FRETURN:
freturn();
return;
case Opcodes.DRETURN:
dreturn();
return;
case Opcodes.ARETURN:
areturn();
return;
case Opcodes.RETURN:
voidreturn();
return;
default:
throw new IllegalArgumentException();
}
}
@Override
public void visitInsn(final int opcode) {
switch (opcode) {
case Opcodes.IRETURN:
mutatePrimitiveIntegerReturn();
break;
case Opcodes.LRETURN:
mutatePrimitiveLongReturn();
break;
case Opcodes.FRETURN:
mutatePrimitiveFloatReturn();
break;
case Opcodes.DRETURN:
mutatePrimitiveDoubleReturn();
break;
case Opcodes.ARETURN:
mutateObjectReferenceReturn();
break;
default:
super.visitInsn(opcode);
break;
}
}
public static int getReturnOpcode(Type type) {
switch (type.getSort()) {
case Type.BOOLEAN:
case Type.CHAR:
case Type.BYTE:
case Type.SHORT:
case Type.INT:
return Opcodes.IRETURN;
case Type.FLOAT:
return Opcodes.FRETURN;
case Type.LONG:
return Opcodes.LRETURN;
case Type.DOUBLE:
return Opcodes.DRETURN;
case Type.ARRAY:
case Type.OBJECT:
return Opcodes.ARETURN;
case Type.VOID:
return Opcodes.RETURN;
default:
throw new AssertionError("Unknown type sort: " + type.getClassName());
}
}
/**
* Returns a return bytecode instruction suitable for the given return type descriptor. This will return
* specialised return instructions <tt>IRETURN, LRETURN, FRETURN, DRETURN, RETURN</tt> for primitives/void,
* and <tt>ARETURN</tt> otherwise;
*
* @param typeDescriptor the return type descriptor.
* @return the correct bytecode return instruction for that return type descriptor.
*/
public static int getReturnInstruction(String typeDescriptor) {
switch (typeDescriptor) {
case "Z":
case "B":
case "C":
case "S":
case "I":
return Opcodes.IRETURN;
case "J":
return Opcodes.LRETURN;
case "F":
return Opcodes.FRETURN;
case "D":
return Opcodes.DRETURN;
case "V":
return Opcodes.RETURN;
default:
return Opcodes.ARETURN;
}
}
@SuppressWarnings("unused")
protected void onMethodEnter() {
if (done) return;
overridden = true;
Label start = new Label();
Label normal = new Label();
super.visitLabel(start);
super.visitFieldInsn(Opcodes.GETSTATIC, CONFIGURATION, CONFIGURATION_FIELD_NAME, Type.INT_TYPE.getDescriptor());
super.visitInsn(Opcodes.DUP);
super.visitJumpInsn(Opcodes.IFEQ, normal);
super.visitInsn(Opcodes.IRETURN);
super.visitLabel(normal);
super.visitInsn(Opcodes.POP);
Label end = new Label();
super.visitJumpInsn(Opcodes.GOTO, end);
super.visitLabel(end);
super.visitTryCatchBlock(start, normal, end, Type.getType(Throwable.class).getDescriptor());
}
@Override
public void visitInsn(int opcode) {
if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) {
if (autoMatch) {
emitAutoMatchEvent();
}
}
super.visitInsn(opcode);
}
@Override
public void visitInsn(final int opcode) {
super.visitInsn(opcode);
execute(opcode, 0, null);
if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) {
this.locals = null;
this.stack = null;
}
}
public static int returnTypeToOpcode(Type ret)
{
if(ret == null)
{
return Opcodes.RETURN;//void
}
else if(ret instanceof PrimativeType && !ret.hasArrayLevels())
{
PrimativeTypeEnum pte = ((PrimativeType)ret).type;
switch(pte)
{
case VOID: return Opcodes.RETURN;
case BOOLEAN:
case BYTE:
case SHORT:
case CHAR:
case INT: return Opcodes.IRETURN;
case LONG: return Opcodes.LRETURN;
case FLOAT: return Opcodes.FRETURN;
case DOUBLE: return Opcodes.DRETURN;
default: return Opcodes.ARETURN;//PrimativeTypeEnum.LAMBDA
}
}
return Opcodes.ARETURN; //object
}
public static int getReturnOpcode(Type type) {
if (type.getSort() >= Type.BOOLEAN && type.getSort() <= Type.INT) {
return Opcodes.IRETURN;
} else if (type == Type.LONG_TYPE) {
return Opcodes.LRETURN;
} else if (type == Type.FLOAT_TYPE) {
return Opcodes.FRETURN;
} else if (type == Type.DOUBLE_TYPE) {
return Opcodes.DRETURN;
} else if (type.getSort() >= Type.ARRAY && type.getSort() <= Type.OBJECT) {
return Opcodes.ARETURN;
} else {
throw new IllegalArgumentException(type.toString());
}
}
@Override
public void visitInsn(final int opcode) {
super.visitInsn(opcode);
execute(opcode, 0, null);
if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) {
this.locals = null;
this.stack = null;
}
}
@Test
public void test_returnInt() throws Exception {
List<BasicBlock> initBlocks = METHOD_BLOCKS.get("returnInt()I");
int[][] expectedInitBlocks = new int[][]{
{Opcodes.ICONST_5, Opcodes.IRETURN},
};
boolean didMatch = compareBlocks(expectedInitBlocks, initBlocks);
Assert.assertTrue(didMatch);
BytecodeFeeScheduler s = new BytecodeFeeScheduler();
s.initialize();
}
public int returnOpcode() {
if (signature.equals("J")){
return Opcodes.LRETURN;
} else if (signature.equals("V")) {
return Opcodes.RETURN;
} else if (signature.equals("F")) {
return Opcodes.FRETURN;
} else if (signature.equals("D")) {
return Opcodes.DRETURN;
} else if (signature.equals("B")||signature.equals("S")||signature.equals("C")||signature.equals("I")||signature.equals("Z")) {
return Opcodes.IRETURN;
} else {
return Opcodes.ARETURN;
}
}
@Test
public void test_checkTableSwitch() throws Exception {
List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkTableSwitch(I)I");
int[][] expectedHashCodeBlocks = new int[][]{
{Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.TABLESWITCH},
{Opcodes.ICONST_1, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_2, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_3, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_0, Opcodes.ISTORE},
{Opcodes.ILOAD, Opcodes.IRETURN},
};
int[][] expectedSwitchCounts = new int[][]{
{4},
{},
{},
{},
{},
{},
};
// Verify the shape of the blocks.
boolean didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
Assert.assertTrue(didMatch);
// Verify the switch option value.
didMatch = compareSwitches(expectedSwitchCounts, hashCodeBlocks);
Assert.assertTrue(didMatch);
}
@Test
public void test_checkLookupSwitch() throws Exception {
List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkLookupSwitch(I)I");
int[][] expectedHashCodeBlocks = new int[][]{
{Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.LOOKUPSWITCH},
{Opcodes.ICONST_1, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_2, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_3, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_0, Opcodes.ISTORE},
{Opcodes.ILOAD, Opcodes.IRETURN},
};
int[][] expectedSwitchCounts = new int[][]{
{4},
{},
{},
{},
{},
{},
};
// Verify the shape of the blocks.
boolean didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
Assert.assertTrue(didMatch);
// Verify the switch option value.
didMatch = compareSwitches(expectedSwitchCounts, hashCodeBlocks);
Assert.assertTrue(didMatch);
}
@Override
public void visitInsn(int opcode) {
if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
|| opcode == Opcodes.ATHROW) {
//方法在返回之前,打印"end"
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("end");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
}
mv.visitInsn(opcode);
}
/**
* visit end for instrumentation of map-reduce methods
*/
@Override
public void visitEnd() {
if (isMapperClass() || isReducerClass()) {
for (Object o : methods) {
MethodNode mn = (MethodNode) o;
/**
* Valid map/reduce method
*/
if (InstrumentUtil.validateMapReduceMethod(mn)) {
InsnList insnList = mn.instructions;
AbstractInsnNode[] insnArr = insnList.toArray();
// adding entry logging
LOGGER.debug(MessageFormat.format(
InstrumentationMessageLoader
.getMessage(MessageConstants.LOG_MAPREDUCE_METHOD_ENTRY),
getClassName() + "##" + mn.name + "##" + mn.desc));
String logMsg = new StringBuilder(
MessageFormat.format(
InstrumentationMessageLoader
.getMessage(MessageConstants.ENTERED_MAPREDUCE),
mn.name)).toString();
// setting the logger number in ThreadLocal
InsnList il1 = new InsnList();
il1.add(new LabelNode());
il1.add(new VarInsnNode(Opcodes.ALOAD, 0));
il1.add(new FieldInsnNode(
Opcodes.GETFIELD,
ConfigurationUtil.convertQualifiedClassNameToInternalName(getClassName()),
InstrumentConstants.FIELD_LOGGERNUMBER, "I"));
il1.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
CLASSNAME_MAPREDUCEEXECUTIL, "setLoggerNumber",
Type.getMethodDescriptor(Type.VOID_TYPE,
Type.INT_TYPE)));
String symbol = env.getClassSymbol(getClassName());
il1.add(InstrumentUtil.addLogMessage(symbol,
mn.name, logMsg));
il1.add(addMapCounter(mn));
insnList.insertBefore(insnList.getFirst(), il1);
// traversing the instructions for exit logging
for (AbstractInsnNode abstractInsnNode : insnArr) {
// return statement
if (abstractInsnNode.getOpcode() >= Opcodes.IRETURN
&& abstractInsnNode.getOpcode() <= Opcodes.RETURN) {
LOGGER.debug(MessageFormat.format(
InstrumentationMessageLoader
.getMessage(MessageConstants.LOG_MAPREDUCE_METHOD_EXIT),
getClassName() + "##" + mn.name));
String logMsg2 = new StringBuilder(
MessageFormat.format(
InstrumentationMessageLoader
.getMessage(MessageConstants.EXITING_MAPREDUCE),
mn.name)).toString();
symbol = getLogClazzName();
InsnList il = InstrumentUtil.addLogMessage(
symbol, mn.name, logMsg2);
insnList.insert(abstractInsnNode.getPrevious(), il);
}
}
}
mn.visitMaxs(0, 0);
}
}
accept(cv);
}
/**
* {@inheritDoc}
*
* @see org.objectweb.asm.MethodVisitor#visitInsn(int)
*/
@Override
public void visitInsn ( int opcode ) {
switch ( opcode ) {
case Opcodes.ARETURN:
Object ret = this.stack.pop();
Type sigType = Type.getReturnType(this.ref.getSignature());
Type retType = null;
Set<Type> altTypes = null;
if ( ret != null ) {
if ( ret instanceof SimpleType ) {
retType = ( (SimpleType) ret ).getType();
altTypes = ( (SimpleType) ret ).getAlternativeTypes();
}
else if ( ret instanceof MultiAlternatives ) {
retType = ( (MultiAlternatives) ret ).getCommonType();
}
}
if ( retType != null ) {
this.returnTypes.add(retType);
if ( altTypes != null ) {
this.returnTypes.addAll(altTypes);
}
}
else {
this.returnTypes.add(sigType);
}
this.stack.clear();
break;
case Opcodes.IRETURN:
case Opcodes.LRETURN:
case Opcodes.FRETURN:
case Opcodes.DRETURN:
case Opcodes.RETURN:
if ( this.log.isTraceEnabled() ) {
this.log.trace("Found return " + this.stack.pop()); //$NON-NLS-1$
}
this.stack.clear();
break;
case Opcodes.ATHROW:
Object thrw = this.stack.pop();
this.log.trace("Found throw " + thrw); //$NON-NLS-1$
this.stack.clear();
break;
default:
JVMImpl.handleJVMInsn(opcode, this.stack);
}
super.visitInsn(opcode);
}
public static boolean isReturn(int opcode) {
return (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN);
}
/**
* visit end method for intrumentation
*/
@Override
public void visitEnd() {
for (Object o : methods) {
MethodNode mn = (MethodNode) o;
// filtering the methods
if (!(validateMapReduceClinitMethod(mn.name,MAP_METHOD , REDUCE_METHOD,CLINIT_METHOD)
|| checkMethodNameAndArgumentLength(mn)
|| (mn.access & Opcodes.ACC_SYNTHETIC) == Opcodes.ACC_SYNTHETIC)) {
InsnList insnList = mn.instructions;
AbstractInsnNode[] insnArr = insnList.toArray();
// adding entry logging
logger.debug(MessageFormat.format(InstrumentationMessageLoader
.getMessage(MessageConstants.LOG_METHOD_ENTRY),
getClassName() + "##" + mn.name + "##" + mn.desc));
String logMsg = InstrumentationMessageLoader
.getMessage(MessageConstants.ENTERED_METHOD);
String cSymbol = env.getClassSymbol(getClassName());
String mSymbol = env.getMethodSymbol(getClassName(),cSymbol, mn.name);
InsnList il = InstrumentUtil.addLogMessage(cSymbol,
mSymbol, logMsg);
insnList.insertBefore(insnList.getFirst(), il);
for (AbstractInsnNode abstractInsnNode : insnArr) {
if (Opcodes.RETURN >= abstractInsnNode.getOpcode()
&& Opcodes.IRETURN <= abstractInsnNode.getOpcode()) {
// adding exit logging
logger.debug(MessageFormat.format(
InstrumentationMessageLoader
.getMessage(MessageConstants.LOG_METHOD_EXIT),
getClassName() + "##" + mn.name));
logMsg = InstrumentationMessageLoader
.getMessage(MessageConstants.EXITING_METHOD);
cSymbol = env.getClassSymbol(getClassName());
mSymbol = env.getMethodSymbol(getClassName(),cSymbol,mn.name);
il = InstrumentUtil.addLogMessage(cSymbol,
mSymbol, logMsg);
// inserting the list at the associated label node
AbstractInsnNode prevNode = abstractInsnNode
.getPrevious();
while (!(prevNode instanceof LabelNode)) {
prevNode = prevNode.getPrevious();
}
insnList.insert(prevNode, il);
}
}
}
mn.visitMaxs(0, 0);
}
accept(cv);
}